[App] Fix PendingIntent crashing on API 31+.

This commit is contained in:
Kuba Szczodrzyński 2022-09-17 17:21:13 +02:00
parent 99afa77a63
commit 9dbb5d70e9
No known key found for this signature in database
GPG Key ID: 70CB8A85BA1633CB
10 changed files with 32 additions and 15 deletions

View File

@ -13,6 +13,7 @@ import androidx.core.app.NotificationCompat.PRIORITY_MIN
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.ext.Bundle import pl.szczodrzynski.edziennik.ext.Bundle
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -40,14 +41,14 @@ class EdziennikNotification(val app: App) {
"task" to "TaskCancelRequest", "task" to "TaskCancelRequest",
"taskId" to taskId "taskId" to taskId
)) ))
return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) as PendingIntent return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or pendingIntentFlag()) as PendingIntent
} }
private val closePendingIntent: PendingIntent private val closePendingIntent: PendingIntent
get() { get() {
val intent = SzkolnyReceiver.getIntent(app, Bundle( val intent = SzkolnyReceiver.getIntent(app, Bundle(
"task" to "ServiceCloseRequest" "task" to "ServiceCloseRequest"
)) ))
return PendingIntent.getBroadcast(app, 0, intent, 0) as PendingIntent return PendingIntent.getBroadcast(app, 0, intent, pendingIntentFlag()) as PendingIntent
} }
private fun errorCountText(): String? { private fun errorCountText(): String? {

View File

@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_SER
import pl.szczodrzynski.edziennik.ext.Intent import pl.szczodrzynski.edziennik.ext.Intent
import pl.szczodrzynski.edziennik.ext.asBoldSpannable import pl.szczodrzynski.edziennik.ext.asBoldSpannable
import pl.szczodrzynski.edziennik.ext.concat import pl.szczodrzynski.edziennik.ext.concat
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.data.db.entity.Notification as AppNotification import pl.szczodrzynski.edziennik.data.db.entity.Notification as AppNotification
@ -92,7 +93,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
MainActivity::class.java, MainActivity::class.java,
"fragmentId" to MainActivity.DRAWER_ITEM_NOTIFICATIONS "fragmentId" to MainActivity.DRAWER_ITEM_NOTIFICATIONS
) )
val summaryIntent = PendingIntent.getActivity(app, app.notificationChannelsManager.data.id, intent, PendingIntent.FLAG_ONE_SHOT) val summaryIntent = PendingIntent.getActivity(app, app.notificationChannelsManager.data.id, intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag())
// On Nougat or newer - show maximum 8 notifications // On Nougat or newer - show maximum 8 notifications
// On Marshmallow or older - show maximum 4 notifications // On Marshmallow or older - show maximum 4 notifications

View File

@ -13,6 +13,7 @@ import com.google.gson.JsonObject
import com.mikepenz.iconics.typeface.IIcon import com.mikepenz.iconics.typeface.IIcon
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
@Entity(tableName = "notifications") @Entity(tableName = "notifications")
data class Notification( data class Notification(
@ -98,7 +99,7 @@ data class Notification(
fun getPendingIntent(context: Context): PendingIntent { fun getPendingIntent(context: Context): PendingIntent {
val intent = Intent(context, MainActivity::class.java) val intent = Intent(context, MainActivity::class.java)
fillIntent(intent) fillIntent(intent)
return PendingIntent.getActivity(context, id.toInt(), intent, PendingIntent.FLAG_ONE_SHOT) return PendingIntent.getActivity(context, id.toInt(), intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag())
} }
fun getLargeIcon(): IIcon = when (type) { fun getLargeIcon(): IIcon = when (type) {

View File

@ -4,7 +4,9 @@
package pl.szczodrzynski.edziennik.ext package pl.szczodrzynski.edziennik.ext
import android.app.PendingIntent
import android.database.Cursor import android.database.Cursor
import android.os.Build
import androidx.core.database.getIntOrNull import androidx.core.database.getIntOrNull
import androidx.core.database.getLongOrNull import androidx.core.database.getLongOrNull
import androidx.core.database.getStringOrNull import androidx.core.database.getStringOrNull
@ -64,3 +66,9 @@ inline fun <A, B, R> ifNotNull(a: A?, b: B?, code: (A, B) -> R): R? {
} }
infix fun Int.hasSet(what: Int) = this and what == what infix fun Int.hasSet(what: Int) = this and what == what
fun pendingIntentFlag(): Int {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
return PendingIntent.FLAG_IMMUTABLE
return 0
}

View File

@ -21,6 +21,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
import pl.szczodrzynski.edziennik.ext.DAY import pl.szczodrzynski.edziennik.ext.DAY
import pl.szczodrzynski.edziennik.ext.concat import pl.szczodrzynski.edziennik.ext.concat
import pl.szczodrzynski.edziennik.ext.formatDate import pl.szczodrzynski.edziennik.ext.formatDate
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.html.BetterHtml import pl.szczodrzynski.edziennik.utils.html.BetterHtml
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -109,7 +110,7 @@ class UpdateWorker(val context: Context, val params: WorkerParameters) : Worker(
} }
val notificationIntent = Intent(app, UpdateDownloaderService::class.java) val notificationIntent = Intent(app, UpdateDownloaderService::class.java)
val pendingIntent = PendingIntent.getService(app, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT) val pendingIntent = PendingIntent.getService(app, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT or pendingIntentFlag())
val notification = NotificationCompat.Builder(app, app.notificationChannelsManager.updates.key) val notification = NotificationCompat.Builder(app, app.notificationChannelsManager.updates.key)
.setContentTitle(app.getString(R.string.notification_updates_title)) .setContentTitle(app.getString(R.string.notification_updates_title))
.setContentText(app.getString(R.string.notification_updates_text, update.versionName)) .setContentText(app.getString(R.string.notification_updates_text, update.versionName))

View File

@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.ext.getJsonObject import pl.szczodrzynski.edziennik.ext.getJsonObject
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
@ -81,7 +82,7 @@ class WidgetLuckyNumberProvider : AppWidgetProvider() {
val openIntent = Intent(context, MainActivity::class.java) val openIntent = Intent(context, MainActivity::class.java)
openIntent.action = Intent.ACTION_MAIN openIntent.action = Intent.ACTION_MAIN
openIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOME) openIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOME)
val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, 0) val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, pendingIntentFlag())
views.setOnClickPendingIntent(R.id.widgetLuckyNumberRoot, openPendingIntent) views.setOnClickPendingIntent(R.id.widgetLuckyNumberRoot, openPendingIntent)
appWidgetManager.updateAppWidget(appWidgetId, views) appWidgetManager.updateAppWidget(appWidgetId, views)

View File

@ -22,6 +22,7 @@ import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.ext.Bundle import pl.szczodrzynski.edziennik.ext.Bundle
import pl.szczodrzynski.edziennik.ext.getJsonObject import pl.szczodrzynski.edziennik.ext.getJsonObject
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver
import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig
@ -47,7 +48,7 @@ class WidgetNotificationsProvider : AppWidgetProvider() {
val syncIntent = SzkolnyReceiver.getIntent(context, Bundle( val syncIntent = SzkolnyReceiver.getIntent(context, Bundle(
"task" to "SyncRequest" "task" to "SyncRequest"
)) ))
val syncPendingIntent = PendingIntent.getBroadcast(context, 0, syncIntent, 0) val syncPendingIntent = PendingIntent.getBroadcast(context, 0, syncIntent, pendingIntentFlag())
views.setOnClickPendingIntent(R.id.widgetNotificationsSync, syncPendingIntent) views.setOnClickPendingIntent(R.id.widgetNotificationsSync, syncPendingIntent)
views.setImageViewBitmap( views.setImageViewBitmap(
@ -68,13 +69,13 @@ class WidgetNotificationsProvider : AppWidgetProvider() {
val itemIntent = Intent(context, MainActivity::class.java) val itemIntent = Intent(context, MainActivity::class.java)
itemIntent.action = Intent.ACTION_MAIN itemIntent.action = Intent.ACTION_MAIN
val itemPendingIntent = PendingIntent.getActivity(context, 0, itemIntent, 0) val itemPendingIntent = PendingIntent.getActivity(context, 0, itemIntent, pendingIntentFlag())
views.setPendingIntentTemplate(R.id.widgetNotificationsListView, itemPendingIntent) views.setPendingIntentTemplate(R.id.widgetNotificationsListView, itemPendingIntent)
val headerIntent = Intent(context, MainActivity::class.java) val headerIntent = Intent(context, MainActivity::class.java)
headerIntent.action = Intent.ACTION_MAIN headerIntent.action = Intent.ACTION_MAIN
headerIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS) headerIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS)
val headerPendingIntent = PendingIntent.getActivity(context, 0, headerIntent, 0) val headerPendingIntent = PendingIntent.getActivity(context, 0, headerIntent, pendingIntentFlag())
views.setOnClickPendingIntent(R.id.widgetNotificationsHeader, headerPendingIntent) views.setOnClickPendingIntent(R.id.widgetNotificationsHeader, headerPendingIntent)
appWidgetManager.updateAppWidget(appWidgetId, views) appWidgetManager.updateAppWidget(appWidgetId, views)

View File

@ -31,6 +31,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.entity.Lesson.Companion.TYPE_NO_LESSONS import pl.szczodrzynski.edziennik.data.db.entity.Lesson.Companion.TYPE_NO_LESSONS
import pl.szczodrzynski.edziennik.ext.filterOutArchived import pl.szczodrzynski.edziennik.ext.filterOutArchived
import pl.szczodrzynski.edziennik.ext.getJsonObject import pl.szczodrzynski.edziennik.ext.getJsonObject
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.ui.widgets.LessonDialogActivity import pl.szczodrzynski.edziennik.ui.widgets.LessonDialogActivity
import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
@ -53,8 +54,8 @@ class WidgetTimetableProvider : AppWidgetProvider() {
return getPendingSelfIntent(context, intent) return getPendingSelfIntent(context, intent)
} }
fun getPendingSelfIntent(context: Context, intent: Intent): PendingIntent { private fun getPendingSelfIntent(context: Context, intent: Intent): PendingIntent {
return PendingIntent.getBroadcast(context, 0, intent, 0) return PendingIntent.getBroadcast(context, 0, intent, pendingIntentFlag())
} }
fun drawableToBitmap(drawable: Drawable): Bitmap { fun drawableToBitmap(drawable: Drawable): Bitmap {
@ -111,7 +112,7 @@ class WidgetTimetableProvider : AppWidgetProvider() {
refreshIntent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE refreshIntent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds) refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
val refreshPendingIntent = PendingIntent.getBroadcast(context, val refreshPendingIntent = PendingIntent.getBroadcast(context,
0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT) 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT or pendingIntentFlag())
views.setOnClickPendingIntent(R.id.widgetTimetableRefresh, refreshPendingIntent) views.setOnClickPendingIntent(R.id.widgetTimetableRefresh, refreshPendingIntent)
views.setOnClickPendingIntent(R.id.widgetTimetableSync, getPendingSelfIntent(context, ACTION_SYNC_DATA)) views.setOnClickPendingIntent(R.id.widgetTimetableSync, getPendingSelfIntent(context, ACTION_SYNC_DATA))
@ -394,7 +395,7 @@ class WidgetTimetableProvider : AppWidgetProvider() {
} }
} }
headerIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE) headerIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE)
val headerPendingIntent = PendingIntent.getActivity(app, appWidgetId, headerIntent, 0) val headerPendingIntent = PendingIntent.getActivity(app, appWidgetId, headerIntent, pendingIntentFlag())
views.setOnClickPendingIntent(R.id.widgetTimetableHeader, headerPendingIntent) views.setOnClickPendingIntent(R.id.widgetTimetableHeader, headerPendingIntent)
timetables!!.put(appWidgetId, models) timetables!!.put(appWidgetId, models)
@ -408,7 +409,7 @@ class WidgetTimetableProvider : AppWidgetProvider() {
// create an intent used to display the lesson details dialog // create an intent used to display the lesson details dialog
val itemIntent = Intent(app, LessonDialogActivity::class.java) val itemIntent = Intent(app, LessonDialogActivity::class.java)
itemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK/* or Intent.FLAG_ACTIVITY_CLEAR_TASK*/) itemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK/* or Intent.FLAG_ACTIVITY_CLEAR_TASK*/)
val itemPendingIntent = PendingIntent.getActivity(app, appWidgetId, itemIntent, 0) val itemPendingIntent = PendingIntent.getActivity(app, appWidgetId, itemIntent, pendingIntentFlag())
views.setPendingIntentTemplate(R.id.widgetTimetableListView, itemPendingIntent) views.setPendingIntentTemplate(R.id.widgetTimetableListView, itemPendingIntent)
if (!unified) if (!unified)

View File

@ -19,6 +19,7 @@ import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.ext.Intent import pl.szczodrzynski.edziennik.ext.Intent
import pl.szczodrzynski.edziennik.ext.JsonObject import pl.szczodrzynski.edziennik.ext.JsonObject
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.ui.captcha.LibrusCaptchaDialog import pl.szczodrzynski.edziennik.ui.captcha.LibrusCaptchaDialog
class UserActionManager(val app: App) { class UserActionManager(val app: App) {
@ -55,7 +56,7 @@ class UserActionManager(val app: App) {
"profileId" to (apiError.profileId ?: -1), "profileId" to (apiError.profileId ?: -1),
"type" to type "type" to type
) )
val pendingIntent = PendingIntent.getActivity(app, System.currentTimeMillis().toInt(), intent, PendingIntent.FLAG_ONE_SHOT) val pendingIntent = PendingIntent.getActivity(app, System.currentTimeMillis().toInt(), intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag())
val notification = NotificationCompat.Builder(app, app.notificationChannelsManager.userAttention.key) val notification = NotificationCompat.Builder(app, app.notificationChannelsManager.userAttention.key)
.setContentTitle(app.getString(R.string.notification_user_action_required_title)) .setContentTitle(app.getString(R.string.notification_user_action_required_title))

View File

@ -115,6 +115,7 @@ class UpdateDownloaderService : IntentService(UpdateDownloaderService::class.jav
Toast.makeText(app, "Nie można znaleźć katalogu docelowego. Pobierz aktualizację ręcznie z Google Play.", Toast.LENGTH_LONG).show() Toast.makeText(app, "Nie można znaleźć katalogu docelowego. Pobierz aktualizację ręcznie z Google Play.", Toast.LENGTH_LONG).show()
return return
} }
Toast.makeText(app, "Pobieranie aktualizacji Szkolny.eu ${update.versionName}", Toast.LENGTH_LONG).show()
downloadId = downloadManager.enqueue(request) downloadId = downloadManager.enqueue(request)
} }
} }