Ping service now subscribes to Firebase topics every 15 minutes to keep the app alive, courses and rooms are now struck through if the course is cancelled

This commit is contained in:
Deniz Düzgören
2019-08-21 10:26:54 +02:00
parent 8a659918a7
commit fce4c949b3
9 changed files with 98 additions and 35 deletions
+5 -8
View File
@@ -10,8 +10,8 @@ android {
applicationId "com.denizd.substitutionplan" applicationId "com.denizd.substitutionplan"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 27 versionCode 28
versionName "2.2.4" versionName "2.2.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@@ -27,17 +27,14 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0-rc1' implementation 'androidx.appcompat:appcompat:1.1.0-rc1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0-beta01'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-beta01'
implementation 'org.jsoup:jsoup:1.11.3' implementation 'org.jsoup:jsoup:1.11.3'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta02' implementation 'androidx.recyclerview:recyclerview:1.1.0-beta03'
implementation 'com.google.android.material:material:1.1.0-alpha09' implementation 'com.google.android.material:material:1.1.0-alpha09'
implementation 'com.android.support:customtabs:28.0.0' implementation 'com.android.support:customtabs:28.0.0'
implementation 'com.google.firebase:firebase-core:17.0.1' implementation 'com.google.firebase:firebase-core:17.1.0'
implementation 'com.google.firebase:firebase-messaging:19.0.1' implementation 'com.google.firebase:firebase-messaging:20.0.0'
// implementation 'androidx.core:core-ktx:1.0.2' // implementation 'androidx.core:core-ktx:1.0.2'
+5
View File
@@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" android:required="true"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" android:required="true"/>
<uses-permission android:name="android.permission.INTERNET" android:required="true"/> <uses-permission android:name="android.permission.INTERNET" android:required="true"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" android:required="true"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
@@ -50,6 +51,10 @@
android:name="com.google.firebase.messaging.default_notification_color" android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" /> android:resource="@color/colorAccent" />
<service
android:name=".FBPingService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:required="true"/>
</application> </application>
</manifest> </manifest>
@@ -63,6 +63,12 @@ class CardAdapter(private var mSubst: List<Subst>) : RecyclerView.Adapter<CardAd
item.setSpan(StrikethroughSpan(), 0, qmark, 0) item.setSpan(StrikethroughSpan(), 0, qmark, 0)
} }
} }
with (currentItem.additional.toLowerCase(Locale.ROOT)) {
if (contains("eigenverantwortliches arbeiten") || contains("entfall")) {
strings[2].setSpan(StrikethroughSpan(), 0, strings[2].length, 0)
strings[3].setSpan(StrikethroughSpan(), 0, strings[3].length, 0)
}
}
holder.mImageView.setImageResource(MiscData.getIconForCourse(currentItem.course)) holder.mImageView.setImageResource(MiscData.getIconForCourse(currentItem.course))
holder.mGroup.setText(strings[0], TextView.BufferType.SPANNABLE) holder.mGroup.setText(strings[0], TextView.BufferType.SPANNABLE)
@@ -131,7 +137,7 @@ class CardAdapter(private var mSubst: List<Subst>) : RecyclerView.Adapter<CardAd
"mat", "map" -> "Maths" "mat", "map" -> "Maths"
"eng", "enp", "ena" -> "English" "eng", "enp", "ena" -> "English"
"spo", "spp", "spth" -> "PhysEd" "spo", "spp", "spth" -> "PhysEd"
"pol", "pop" -> "ics" "pol", "pop" -> "Politics"
"dar", "dap" -> "Theatre" "dar", "dap" -> "Theatre"
"phy", "php" -> "Physics" "phy", "php" -> "Physics"
"bio", "bip", "nw1", "nw2", "nw3", "nw4" -> "Biology" "bio", "bip", "nw1", "nw2", "nw3", "nw4" -> "Biology"
@@ -5,7 +5,8 @@ import com.google.firebase.messaging.RemoteMessage
class FBNotificationService : FirebaseMessagingService() { class FBNotificationService : FirebaseMessagingService() {
override fun onMessageReceived(p0: RemoteMessage?) { override fun onMessageReceived(p0: RemoteMessage) {
DataFetcher(true, true, true, applicationContext, application, null).execute() DataFetcher(isplan = true, ismenu = true, isjobservice = true, context = applicationContext,
application = application, parentview = null).execute()
} }
} }
@@ -0,0 +1,46 @@
package com.denizd.substitutionplan
import android.app.job.JobParameters
import android.app.job.JobService
import android.preference.PreferenceManager
import com.google.firebase.FirebaseApp
import com.google.firebase.messaging.FirebaseMessaging
class FBPingService : JobService() {
private var jobCancelled = false
private val context = this
override fun onStartJob(params: JobParameters): Boolean {
doBackgroundWork(params)
return true
}
override fun onStopJob(params: JobParameters?): Boolean {
jobCancelled = true
return true
}
private fun doBackgroundWork(params: JobParameters) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
FirebaseApp.initializeApp(context)
if (prefs.getBoolean("notif", true)) {
FirebaseMessaging.getInstance().subscribeToTopic("substitutions-android")
} else {
FirebaseMessaging.getInstance().unsubscribeFromTopic("substitutions-android")
}
if (prefs.getBoolean("subscribedToFBDebugChannel", false)) {
FirebaseMessaging.getInstance().subscribeToTopic("substitutions-debug")
} else {
FirebaseMessaging.getInstance().unsubscribeFromTopic("substitutions-debug")
}
FirebaseMessaging.getInstance().subscribeToTopic("substitutions-broadcast")
prefs.edit().putInt("pingFB", prefs.getInt("pingFB", 0) + 1).apply()
jobFinished(params, false)
}
}
@@ -1,5 +1,8 @@
package com.denizd.substitutionplan package com.denizd.substitutionplan
import android.app.job.JobInfo
import android.app.job.JobScheduler
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
@@ -53,14 +56,7 @@ class Main : AppCompatActivity(R.layout.app_bar_main) {
edit.putInt("launchDev", prefs.getInt("launchDev", 0) + 1) edit.putInt("launchDev", prefs.getInt("launchDev", 0) + 1)
edit.apply() edit.apply()
FirebaseApp.initializeApp(context) pingFirebaseTopics()
if (prefs.getBoolean("notif", true)) {
FirebaseMessaging.getInstance().subscribeToTopic("substitutions-android")
} else {
FirebaseMessaging.getInstance().unsubscribeFromTopic("substitutions-android")
}
FirebaseMessaging.getInstance().subscribeToTopic("substitutions-broadcast")
val appbarlayout = findViewById<AppBarLayout>(R.id.appbarlayout) val appbarlayout = findViewById<AppBarLayout>(R.id.appbarlayout)
val toolbarTxt = findViewById<TextView>(R.id.toolbarTxt) val toolbarTxt = findViewById<TextView>(R.id.toolbarTxt)
@@ -237,8 +233,7 @@ class Main : AppCompatActivity(R.layout.app_bar_main) {
val dialog = AlertDialog.Builder(context) val dialog = AlertDialog.Builder(context)
val dialogView = LayoutInflater.from(context).inflate(R.layout.simple_dialog, null) val dialogView = LayoutInflater.from(context).inflate(R.layout.simple_dialog, null)
dialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(R.string.information) dialogView.findViewById<TextView>(R.id.textviewtitle).text = getString(R.string.information)
val sb = StringBuilder() val dialogText = "${getString(R.string.lastUpdated)} ${prefs.getString("timeNew", "")}.\n\n${prefs.getString("informational", "")}"
val dialogText = sb.append(getText(R.string.lastUpdated)).append((prefs.getString("timeNew", "") ?: "") + ".\n\n").append(prefs.getString("informational", ""))
dialogView.findViewById<TextView>(R.id.dialogtext).text = dialogText dialogView.findViewById<TextView>(R.id.dialogtext).text = dialogText
dialog.setView(dialogView).show() dialog.setView(dialogView).show()
} }
@@ -247,4 +242,15 @@ class Main : AppCompatActivity(R.layout.app_bar_main) {
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).commit() supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).commit()
return true return true
} }
private fun pingFirebaseTopics() {
val componentName = ComponentName(this, FBPingService::class.java)
val info = JobInfo.Builder(42, componentName)
.setRequiresCharging(false)
.setPersisted(true)
.setPeriodic(900000)
.build()
val scheduler = getSystemService(JOB_SCHEDULER_SERVICE) as JobScheduler
scheduler.schedule(info)
}
} }
@@ -369,7 +369,7 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen
} }
resetNotifBtn.setOnClickListener { resetNotifBtn.setOnClickListener {
edit.putInt("notificationTestNumberDev", 0).apply() edit.putInt("pingFB", 0).apply()
devDialogText.text = getDiagnosticsText(prefs) devDialogText.text = getDiagnosticsText(prefs)
} }
@@ -386,7 +386,7 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen
} }
} }
"_NOTIFICATION" -> { "_NOTIFICATION" -> {
edit.putString("time", "").putString("timeFood", "").apply() edit.putString("timeNew", "").putString("timeFoodNew", "").apply()
Toast.makeText(mContext, "Notification times cleared", Toast.LENGTH_LONG).show() Toast.makeText(mContext, "Notification times cleared", Toast.LENGTH_LONG).show()
} // TODO add option to clear database } // TODO add option to clear database
"_FIRSTTIME" -> { "_FIRSTTIME" -> {
@@ -400,10 +400,8 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen
} }
"_DEVCHANNEL" -> { "_DEVCHANNEL" -> {
val subbed = if (prefs.getBoolean("subscribedToFBDebugChannel", false)) { val subbed = if (prefs.getBoolean("subscribedToFBDebugChannel", false)) {
FirebaseMessaging.getInstance().unsubscribeFromTopic("substitutions-debug")
"Unsubscribed from" "Unsubscribed from"
} else { } else {
FirebaseMessaging.getInstance().subscribeToTopic("substitutions-debug")
"Subscribed to" "Subscribed to"
} }
edit.putBoolean("subscribedToFBDebugChannel", !prefs.getBoolean("subscribedToFBDebugChannel", false)).apply() edit.putBoolean("subscribedToFBDebugChannel", !prefs.getBoolean("subscribedToFBDebugChannel", false)).apply()
@@ -418,11 +416,13 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen
} }
private fun getDiagnosticsText(prefs: SharedPreferences): String { private fun getDiagnosticsText(prefs: SharedPreferences): String {
return "First Launch: " + prefs.getString("firstTimeDev", "") + return "First Launch: ${prefs.getString("firstTimeDev", "")}" +
"\n\nApp launched: " + prefs.getInt("launchDev", 0) + "\n\nApp launched: ${prefs.getInt("launchDev", 0)}" +
"\n\nNotification Service fired: " + prefs.getInt("notificationTestNumberDev", 0) + "\n\nFirebase ping service fired: ${prefs.getInt("pingFB", 0)}" +
"\n\nDevice Name: " + name + "\n\nDevice Name: $name" +
"\n\nDevice Model: " + model + "\n\nDevice Model: $model" +
"\n\nAndroid Version: " + Build.VERSION.RELEASE "\n\nAndroid Version: ${Build.VERSION.RELEASE}" +
"\n\nSubscribed to notification channel: ${prefs.getBoolean("notif", false)}" +
"\n\nSubscribed to dev channel: ${prefs.getBoolean("subscribedToFBDebugChannel", false)}"
} }
} }
@@ -27,17 +27,19 @@ public abstract class SubstDatabase : RoomDatabase() {
return instance return instance
} }
private var foodInstance: SubstDatabase? = null
fun getFoodInstance(context: Context): SubstDatabase? { fun getFoodInstance(context: Context): SubstDatabase? {
if (instance == null) { if (foodInstance == null) {
synchronized (SubstDatabase::class) { synchronized (SubstDatabase::class) {
instance = Room.databaseBuilder(context.applicationContext, foodInstance = Room.databaseBuilder(context.applicationContext,
SubstDatabase::class.java, SubstDatabase::class.java,
"food_database") "food_database")
.fallbackToDestructiveMigration() .fallbackToDestructiveMigration()
.build() .build()
} }
} }
return instance return foodInstance
} }
} }
} }
@@ -60,7 +60,7 @@
android:layout_marginStart="24dp" android:layout_marginStart="24dp"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:text="Reset notification counter" android:text="Reset ping counter"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"/> style="@style/Widget.MaterialComponents.Button.OutlinedButton"/>
</LinearLayout> </LinearLayout>