Add background process for checking new data and create notifications

This commit is contained in:
2019-09-13 21:02:54 +02:00
committed by Matte23
parent b4d8fb3c77
commit 1b57df88d3
6 changed files with 174 additions and 0 deletions

View File

@@ -44,6 +44,7 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0' implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0' implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'
implementation "androidx.work:work-runtime-ktx:2.2.0"
implementation "androidx.room:room-runtime:2.2.0-rc01" implementation "androidx.room:room-runtime:2.2.0-rc01"
kapt "androidx.room:room-compiler:2.2.0-rc01" kapt "androidx.room:room-compiler:2.2.0-rc01"
implementation "androidx.room:room-ktx:2.2.0-rc01" implementation "androidx.room:room-ktx:2.2.0-rc01"

View File

@@ -20,6 +20,11 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<receiver android:name=".BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,32 @@
/*
* Circolapp
* Copyright (C) 2019 Matteo Schiff
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.underdesk.circolapp
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import net.underdesk.circolapp.works.PollWork
class BootCompleteReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == null || intent.action != "android.intent.action.BOOT_COMPLETED") return
PollWork.enqueue(context)
}
}

View File

@@ -25,6 +25,7 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import net.underdesk.circolapp.works.PollWork
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@@ -45,5 +46,7 @@ class MainActivity : AppCompatActivity() {
) )
setupActionBarWithNavController(navController, appBarConfiguration) setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController) navView.setupWithNavController(navController)
PollWork.enqueue(this)
} }
} }

View File

@@ -0,0 +1,128 @@
/*
* Circolapp
* Copyright (C) 2019 Matteo Schiff
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.underdesk.circolapp.works
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.work.*
import net.underdesk.circolapp.MainActivity
import net.underdesk.circolapp.R
import net.underdesk.circolapp.data.AppDatabase
import net.underdesk.circolapp.data.Circular
import net.underdesk.circolapp.server.DataFetcher
import java.util.concurrent.TimeUnit
class PollWork(appContext: Context, workerParams: WorkerParameters) :
Worker(appContext, workerParams) {
companion object {
const val CHANNEL_ID = "net.underdesk.circolapp.NEW_CIRCULAR"
private const val pollWorkName = "net.underdesk.circolapp.POLL_WORK"
private const val repeatIntervalMin: Long = 30
private const val flexIntervalMin: Long = 10
private fun getPollWorkRequest(): PeriodicWorkRequest {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
return PeriodicWorkRequestBuilder<PollWork>(
repeatIntervalMin,
TimeUnit.MINUTES,
flexIntervalMin,
TimeUnit.MINUTES
).setConstraints(constraints).build()
}
fun enqueue(context: Context) {
WorkManager.getInstance(context)
.enqueueUniquePeriodicWork(
pollWorkName,
ExistingPeriodicWorkPolicy.KEEP,
getPollWorkRequest()
)
}
}
override fun doWork(): Result {
val fetcher = DataFetcher()
val oldCirculars = AppDatabase.getInstance(applicationContext).circularDao().getCirculars()
val newCirculars = fetcher.getCircularsFromServer()
if (newCirculars.size != oldCirculars.size) {
for (i in oldCirculars.lastIndex..newCirculars.lastIndex) {
createNotificationChannel()
createNotification(newCirculars[i])
}
AppDatabase.getInstance(applicationContext).circularDao().deleteAll()
AppDatabase.getInstance(applicationContext).circularDao().insertAll(newCirculars)
}
return Result.success()
}
private fun createNotification(circular: Circular) {
val intent = Intent(applicationContext, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent =
PendingIntent.getActivity(applicationContext, 0, intent, 0)
val builder = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notifications_black_24dp)
.setContentTitle(applicationContext.getString(R.string.notification_title, circular.id))
.setContentText(circular.name)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setGroup(CHANNEL_ID)
.setStyle(
NotificationCompat.BigTextStyle()
.bigText(circular.name)
)
with(NotificationManagerCompat.from(applicationContext)) {
notify(circular.id.toInt(), builder.build())
}
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = applicationContext.getString(R.string.channel_name)
val descriptionText = applicationContext.getString(R.string.channel_description)
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
val notificationManager: NotificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
}

View File

@@ -3,4 +3,9 @@
<string name="title_circular_letters">Circular letters</string> <string name="title_circular_letters">Circular letters</string>
<string name="title_favourites">Favourites</string> <string name="title_favourites">Favourites</string>
<string name="title_reminders">Reminders</string> <string name="title_reminders">Reminders</string>
<string name="notification_title">Published circular letter number %1$d</string>
<string name="channel_name">Circular letters</string>
<string name="channel_description">Notify when your school issue a new circular letter</string>
</resources> </resources>