From 9e3d3ee03e597cdc42d154597067417b47a8931e Mon Sep 17 00:00:00 2001 From: Pierre-Yves Ricau Date: Thu, 10 Nov 2022 13:24:05 -0800 Subject: [PATCH] Request permission on Android 13 --- build.gradle | 2 +- .../src/main/AndroidManifest.xml | 7 +-- .../internal/LeakDirectoryProvider.kt | 5 ++- .../java/leakcanary/internal/Notifications.kt | 45 +++++++++++++++++-- ...tivity.kt => RequestPermissionActivity.kt} | 29 +++++++----- .../main/res/values/leak_canary_strings.xml | 2 +- 6 files changed, 70 insertions(+), 20 deletions(-) rename leakcanary-android-core/src/main/java/leakcanary/internal/{RequestStoragePermissionActivity.kt => RequestPermissionActivity.kt} (70%) diff --git a/build.gradle b/build.gradle index 4090f8c0a4..28731ee557 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ import org.jetbrains.dokka.gradle.DokkaTask buildscript { ext.versions = [ 'minSdk' : 14, - 'compileSdk': 31, + 'compileSdk': 33, ] repositories { google() diff --git a/leakcanary-android-core/src/main/AndroidManifest.xml b/leakcanary-android-core/src/main/AndroidManifest.xml index 311285aa35..5e0b6d0401 100644 --- a/leakcanary-android-core/src/main/AndroidManifest.xml +++ b/leakcanary-android-core/src/main/AndroidManifest.xml @@ -22,8 +22,9 @@ - - + + + = 33) { + val application = InternalLeakCanary.application + if (application.applicationInfo.targetSdkVersion >= 33) { + val notificationManager = + application.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + if (!notificationManager.areNotificationsEnabled()) { + if (notificationPermissionRequested) { + SharkLog.d { "Not showing notification: already requested missing POST_NOTIFICATIONS permission." } + } else { + SharkLog.d { "Not showing notification: requesting missing POST_NOTIFICATIONS permission." } + application.startActivity( + RequestPermissionActivity.createIntent( + application, + POST_NOTIFICATIONS + ) + ) + notificationPermissionRequested = true + } + return false + } + if (notificationManager.areNotificationsPaused()) { + SharkLog.d { "Not showing notification, notifications are paused." } + return false + } + } + } + return true + } @Suppress("LongParameterList") fun showNotification( diff --git a/leakcanary-android-core/src/main/java/leakcanary/internal/RequestStoragePermissionActivity.kt b/leakcanary-android-core/src/main/java/leakcanary/internal/RequestPermissionActivity.kt similarity index 70% rename from leakcanary-android-core/src/main/java/leakcanary/internal/RequestStoragePermissionActivity.kt rename to leakcanary-android-core/src/main/java/leakcanary/internal/RequestPermissionActivity.kt index 22329f1d87..74b47eefa1 100644 --- a/leakcanary-android-core/src/main/java/leakcanary/internal/RequestStoragePermissionActivity.kt +++ b/leakcanary-android-core/src/main/java/leakcanary/internal/RequestPermissionActivity.kt @@ -15,7 +15,6 @@ */ package leakcanary.internal -import android.Manifest.permission.WRITE_EXTERNAL_STORAGE import android.annotation.TargetApi import android.app.Activity import android.app.PendingIntent @@ -33,17 +32,20 @@ import android.widget.Toast.LENGTH_LONG import com.squareup.leakcanary.core.R @TargetApi(Build.VERSION_CODES.M) // -internal class RequestStoragePermissionActivity : Activity() { +internal class RequestPermissionActivity : Activity() { + + private val targetPermission: String + get() = intent.getStringExtra(TARGET_PERMISSION_EXTRA)!! override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) { - if (hasStoragePermission()) { + if (hasTargetPermission()) { finish() return } - val permissions = arrayOf(WRITE_EXTERNAL_STORAGE) + val permissions = arrayOf(targetPermission) requestPermissions(permissions, 42) } } @@ -53,7 +55,7 @@ internal class RequestStoragePermissionActivity : Activity() { permissions: Array, grantResults: IntArray ) { - if (!hasStoragePermission()) { + if (!hasTargetPermission()) { Toast.makeText(application, R.string.leak_canary_permission_not_granted, LENGTH_LONG) .show() } @@ -66,15 +68,22 @@ internal class RequestStoragePermissionActivity : Activity() { super.finish() } - private fun hasStoragePermission(): Boolean { - return checkSelfPermission(WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED + private fun hasTargetPermission(): Boolean { + return checkSelfPermission(targetPermission) == PERMISSION_GRANTED } companion object { + private const val TARGET_PERMISSION_EXTRA = "targetPermission" + + fun createIntent(context: Context, permission: String): Intent { + return Intent(context, RequestPermissionActivity::class.java).apply { + flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TOP + putExtra(TARGET_PERMISSION_EXTRA, permission) + } + } - fun createPendingIntent(context: Context): PendingIntent { - val intent = Intent(context, RequestStoragePermissionActivity::class.java) - intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TOP + fun createPendingIntent(context: Context, permission: String): PendingIntent { + val intent = createIntent(context, permission) val flags = if (Build.VERSION.SDK_INT >= 23) { FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE } else { diff --git a/leakcanary-android-core/src/main/res/values/leak_canary_strings.xml b/leakcanary-android-core/src/main/res/values/leak_canary_strings.xml index 06b6540511..39f75a4cc3 100644 --- a/leakcanary-android-core/src/main/res/values/leak_canary_strings.xml +++ b/leakcanary-android-core/src/main/res/values/leak_canary_strings.xml @@ -63,7 +63,7 @@ Delete Delete all Are you sure you want to delete all leaks? - Please grant external storage permission, otherwise memory leaks will not be detected. + Please grant requested permission, otherwise memory leak detection may not work. Leak detected, need permission Click to enable storage permission for %s. Leaks