通知権限の要求を1回だけにする。権限がない場合はサイドメニューに表示を追加する。

This commit is contained in:
tateisu 2023-02-06 03:08:48 +09:00
parent 90f657ef94
commit 8daad253b9
8 changed files with 85 additions and 14 deletions

View File

@ -156,7 +156,7 @@ class ActMain : AppCompatActivity(),
lateinit var handler: Handler
lateinit var appState: AppState
private lateinit var sideMenuAdapter: SideMenuAdapter
lateinit var sideMenuAdapter: SideMenuAdapter
//////////////////////////////////////////////////////////////////
// 読み取り専用のプロパティ
@ -326,7 +326,9 @@ class ActMain : AppCompatActivity(),
}
val prNotification = permissionSpecNotification.requester {
// 特に何もしない
launchAndShowError {
afterNotificationGranted()
}
}
private var startAfterJob: WeakReference<Job>? = null

View File

@ -22,7 +22,6 @@ import jp.juggler.subwaytooter.dialog.actionsDialog
import jp.juggler.subwaytooter.itemviewholder.ItemViewHolder
import jp.juggler.subwaytooter.pref.*
import jp.juggler.subwaytooter.push.PushWorker
import jp.juggler.subwaytooter.push.pushRepo
import jp.juggler.subwaytooter.span.MyClickableSpan
import jp.juggler.subwaytooter.util.checkPrivacyPolicy
import jp.juggler.subwaytooter.util.openCustomTab
@ -247,13 +246,22 @@ fun ActMain.launchDialogs() {
// テーマ告知
themeDefaultChangedDialog()
// 通知権限の確認
if(!prNotification.checkOrLaunch()) return@launchAndShowError
// 通知権限の確認を一度だけ行う
if (!prefDevice.supressRequestNotificationPermission) {
prefDevice.supressRequestNotificationPermission = true
if (!prNotification.checkOrLaunch()) return@launchAndShowError
}
// Workの掃除
WorkManager.getInstance(applicationContext).pruneWork()
// 定期的にendpointを再登録したい
PushWorker.enqueueRegisterEndpoint(applicationContext, keepAliveMode = true)
afterNotificationGranted()
}
}
fun ActMain.afterNotificationGranted() {
sideMenuAdapter.filterListItems()
// Workの掃除
WorkManager.getInstance(applicationContext).pruneWork()
// 定期的にendpointを再登録したい
PushWorker.enqueueRegisterEndpoint(applicationContext, keepAliveMode = true)
}

View File

@ -214,7 +214,8 @@ class SideMenuAdapter(
IT_GROUP_HEADER(1),
IT_DIVIDER(2),
IT_VERSION(3),
IT_TIMEZONE(4)
IT_TIMEZONE(4),
IT_NOTIFICATION_PERMISSION(5),
}
private class Item(
@ -229,6 +230,7 @@ class SideMenuAdapter(
title == 0 -> ItemType.IT_DIVIDER
title == 1 -> ItemType.IT_VERSION
title == 2 -> ItemType.IT_TIMEZONE
title == 3 -> ItemType.IT_NOTIFICATION_PERMISSION
icon == 0 -> ItemType.IT_GROUP_HEADER
else -> ItemType.IT_NORMAL
}
@ -239,11 +241,11 @@ class SideMenuAdapter(
else no icon => section header with title
else => menu item with icon and title
*/
private val list = arrayOf(
private val originalList = listOf(
Item(icon = R.drawable.ic_info_outline, title = 1),
Item(icon = R.drawable.ic_info_outline, title = 2),
Item(icon = R.drawable.ic_info_outline, title = 3),
Item(),
Item(title = R.string.account),
@ -453,6 +455,8 @@ class SideMenuAdapter(
}
)
private var list = originalList
private val iconColor = actMain.attrColor(R.attr.colorTimeSmall)
override fun getCount(): Int = list.size
@ -517,6 +521,24 @@ class SideMenuAdapter(
background = null
text = getTimeZoneString(context)
}
ItemType.IT_NOTIFICATION_PERMISSION ->
viewOrInflate<TextView>(view, parent, R.layout.lv_sidemenu_item).apply {
isAllCaps = false
text = actMain.getString(R.string.notification_permission_not_granted)
val drawable = createColoredDrawable(actMain, icon, iconColor, 1f)
setCompoundDrawablesRelativeWithIntrinsicBounds(
drawable,
null,
null,
null
)
setOnClickListener {
drawer.closeDrawer(GravityCompat.START)
if (actMain.prNotification.checkOrLaunch()) {
filterListItems()
}
}
}
}
}
@ -557,8 +579,20 @@ class SideMenuAdapter(
this.notifyDataSetChanged()
}
fun filterListItems() {
list = originalList.filter {
when (it.itemType) {
ItemType.IT_NOTIFICATION_PERMISSION ->
actMain.prNotification.spec.listNotGranded(actMain).isNotEmpty()
else -> true
}
}
notifyDataSetChanged()
}
init {
actMain.applicationContext.checkVersion()
filterListItems()
ListView(actMain).apply {
adapter = this@SideMenuAdapter

View File

@ -26,6 +26,7 @@ class PrefDevice(context: Context) {
private const val PREF_UP_ENDPOINT_EXPIRED = "upEndpointExpired"
private const val PREF_PUSH_DISTRIBUTOR = "pushDistributor"
private const val PREF_TIME_LAST_ENDPOINT_REGISTER = "timeLastEndpointRegister"
private const val PREF_SUPRESS_REQUEST_NOTIFICATION_PERMISSION = "supressRequestNotificationPermission"
const val PUSH_DISTRIBUTOR_FCM = "fcm"
const val PUSH_DISTRIBUTOR_NONE = "none"
@ -71,6 +72,9 @@ class PrefDevice(context: Context) {
@Suppress("SameParameterValue")
private fun int(key: String) = if (sp.contains(key)) sp.getInt(key, 0) else null
@Suppress("SameParameterValue")
private fun boolean(key: String) = if (sp.contains(key)) sp.getBoolean(key, false) else null
@Suppress("SameParameterValue")
private fun String?.saveTo(key: String) =
edit { it.putString(key, this) }
@ -82,6 +86,9 @@ class PrefDevice(context: Context) {
@Suppress("SameParameterValue")
private fun Int?.saveTo(key: String) =
edit { it.putIntNullable(key, this) }
@Suppress("SameParameterValue")
private fun Boolean?.saveTo(key: String) =
edit { it.putBooleanNullable(key, this) }
// 認証開始時の状態を覚えておく
val authServerType: String? get() = string(PREF_AUTH_SERVER_TYPE)
@ -138,6 +145,12 @@ class PrefDevice(context: Context) {
value.saveTo(PREF_TIME_LAST_ENDPOINT_REGISTER)
}
var supressRequestNotificationPermission: Boolean
get() = boolean(PREF_SUPRESS_REQUEST_NOTIFICATION_PERMISSION)?:false
set(value) {
value.saveTo(PREF_SUPRESS_REQUEST_NOTIFICATION_PERMISSION)
}
//////////////////////////////////
// 以下は古い

View File

@ -27,7 +27,7 @@ class PermissionRequester(
/**
* 権限の詳細
*/
private val spec: PermissionSpec,
val spec: PermissionSpec,
/**
* 権限が与えられた際に処理を再開するラムダ
* - ラムダの引数にこのPermissionRequester自身が渡される

View File

@ -1,10 +1,12 @@
package jp.juggler.subwaytooter.util
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.StringRes
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import jp.juggler.subwaytooter.R
@ -29,6 +31,16 @@ class PermissionSpec(
ContextCompat.checkSelfPermission(context, it) !=
PackageManager.PERMISSION_GRANTED
}
/**
* - 権限のどれかが不足している
* - 不足した権限のどれかが shouldShowRequestPermissionRationale == trueである
*/
fun shouldShowRational(activity: Activity) =
permissions.any {
ContextCompat.checkSelfPermission(activity, it) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.shouldShowRequestPermissionRationale(activity, it)
}
}
val permissionSpecNotification = if (Build.VERSION.SDK_INT >= 33) {

View File

@ -1232,4 +1232,5 @@
<string name="push_message_save_to_download_folder_with_secret_key">Downloadフォルダに保存 (秘密鍵つき。データ安全に注意。これは危険です!)</string>
<string name="saved_to">保存しました。 %1$s</string>
<string name="view">見る</string>
<string name="notification_permission_not_granted">通知表示権限がありません</string>
</resources>

View File

@ -1246,4 +1246,5 @@
<string name="alert_test">test alert notification</string>
<string name="saved_to">Saved to %1$s</string>
<string name="view">View</string>
<string name="notification_permission_not_granted">notification permission not granted</string>
</resources>