- targetSdkVersion 33

- 端末のOSバージョンにより権限要求の内容を切り替える
-- アカウント設定の画像選択
-- 内蔵メディアビューアのダウンロード
- メイン画面開始時に通知権限を要求する
This commit is contained in:
tateisu 2023-01-05 16:26:35 +09:00
parent 74d5d19848
commit 71bba5c011
19 changed files with 149 additions and 67 deletions

View File

@ -51,12 +51,24 @@
</queries>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- CAMERAパーミッションをつけるとPlayストアにプライバシーポリシーを記載する必要がある -->
<!--<uses-permission android:name="android.permission.CAMERA"/>-->
@ -64,6 +76,8 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!--suppress AndroidUnknownAttribute -->
<application
android:name=".App1"

View File

@ -1,6 +1,5 @@
package jp.juggler.subwaytooter
import android.Manifest
import android.app.Activity
import android.content.ContentValues
import android.content.Intent
@ -179,15 +178,8 @@ class ActAccountSetting : AppCompatActivity(),
}
}
private val prPickAvater = PermissionRequester(
permissions = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
deniedId = R.string.missing_permission_to_access_media,
) { openPicker(it) }
private val prPickHeader = PermissionRequester(
permissions = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
deniedId = R.string.missing_permission_to_access_media,
) { openPicker(it) }
private val prPickAvater = permissionSpecImagePicker.requester { openPicker(it) }
private val prPickHeader = permissionSpecImagePicker.requester { openPicker(it) }
///////////////////////////////////////////////////
@ -239,8 +231,6 @@ class ActAccountSetting : AppCompatActivity(),
outState.putString(ACTIVITY_STATE, encodedState)
}
var density: Float = 1f
@Suppress("LongMethod")

View File

@ -311,6 +311,10 @@ class ActMain : AppCompatActivity(),
}
}
var prNotification = permissionSpecNotification.requester {
// 特に何もしない
}
//////////////////////////////////////////////////////////////////
// ライフサイクルイベント
@ -320,6 +324,7 @@ class ActMain : AppCompatActivity(),
super.onCreate(savedInstanceState)
refActMain = WeakReference(this)
prNotification.register(this)
arColumnColor.register(this)
arLanguageFilter.register(this)
arNickname.register(this)
@ -358,6 +363,7 @@ class ActMain : AppCompatActivity(),
}
checkPrivacyPolicy()
}
override fun onDestroy() {
@ -436,6 +442,8 @@ class ActMain : AppCompatActivity(),
// 残りの処理はActivityResultの処理より後回しにしたい
handler.postDelayed(onStartAfter, 1L)
prNotification.checkOrLaunch()
}
}

View File

@ -226,10 +226,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
}
}
private val prDownload = PermissionRequester(
permissions = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
deniedId = R.string.missing_permission_to_access_media,
) { download(mediaList[idx]) }
private val prDownload = permissionSpecMediaDownload.requester { download(mediaList[idx]) }
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)

View File

@ -86,19 +86,14 @@ class AttachmentPicker(
}
}
private val prPickAttachment = PermissionRequester(
permissions = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
deniedId = R.string.missing_permission_to_access_media,
) { openPicker() }
private val prPickAttachment = permissionSpecImagePicker.requester{ openPicker() }
private val prPickCustomThumbnail = PermissionRequester(
permissions = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
deniedId = R.string.missing_permission_to_access_media,
) {
private val prPickCustomThumbnail = permissionSpecImagePicker.requester{
callback.resumeCustomThumbnailTarget(states.customThumbnailTargetId)
?.let { openCustomThumbnail(it) }
}
init {
// must register all ARHs before onStart
prPickAttachment.register(activity)
@ -133,12 +128,6 @@ class AttachmentPicker(
fun openPicker() {
if (!prPickAttachment.checkOrLaunch()) return
// permissionCheck = ContextCompat.checkSelfPermission( this, Manifest.permission.CAMERA );
// if( permissionCheck != PackageManager.PERMISSION_GRANTED ){
// preparePermission();
// return;
// }
with(activity) {
val a = ActionsDialog()
a.addAction(getString(R.string.pick_images)) {

View File

@ -3,14 +3,11 @@ package jp.juggler.util
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.provider.Settings
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import jp.juggler.subwaytooter.R
@ -23,21 +20,9 @@ import kotlin.coroutines.resumeWithException
*/
class PermissionRequester(
/**
* 必要なパーミッションのリスト
* 権限の詳細
*/
val permissions: List<String>,
/**
* 要求が拒否された場合に表示するメッセージのID
*/
@StringRes val deniedId: Int,
/**
* なぜ権限が必要なのか説明するメッセージのID
* デフォルトは0でこの場合はメッセージを出さない
*/
@StringRes val rationalId: Int = 0,
private val spec: PermissionSpec,
/**
* 権限が与えられた際に処理を再開するラムダ
* - ラムダの引数にこのPermissionRequester自身が渡される
@ -79,10 +64,9 @@ class PermissionRequester(
*/
fun checkOrLaunch(): Boolean {
val activity = activity ?: error("missing activity.")
val listNotGranted = permissions.filter {
PackageManager.PERMISSION_GRANTED !=
ContextCompat.checkSelfPermission(activity, it)
}
val listNotGranted = spec.listNotGranded(activity)
if (listNotGranted.isEmpty()) return true
launchMain {
@ -91,10 +75,10 @@ class PermissionRequester(
shouldShowRequestPermissionRationale(activity, it)
}
if (shouldShowRational && rationalId != 0) {
if (shouldShowRational && spec.rationalId != 0) {
suspendCancellableCoroutine { cont ->
AlertDialog.Builder(activity)
.setMessage(rationalId)
.setMessage(spec.rationalId)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok) { _, _ ->
if (cont.isActive) cont.resumeWith(Result.success(Unit))
@ -136,7 +120,7 @@ class PermissionRequester(
// 許可されなかった。
val activity = activity ?: error("missing activity.")
AlertDialog.Builder(activity)
.setMessage(deniedId)
.setMessage(spec.deniedId)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.setting) { _, _ ->
openAppSetting(activity)
@ -160,3 +144,6 @@ class PermissionRequester(
}
}
}
fun PermissionSpec.requester(onGrant: (PermissionRequester) -> Unit) =
PermissionRequester(this, onGrant)

View File

@ -0,0 +1,80 @@
package jp.juggler.util
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import jp.juggler.subwaytooter.R
class PermissionSpec(
/**
* 必要なパーミッションのリスト
*/
val permissions: List<String>,
/**
* 要求が拒否された場合に表示するメッセージのID
*/
@StringRes val deniedId: Int,
/**
* なぜ権限が必要なのか説明するメッセージのID
*/
@StringRes val rationalId: Int,
) {
fun listNotGranded(context: Context) =
permissions.filter {
ContextCompat.checkSelfPermission(context, it) !=
PackageManager.PERMISSION_GRANTED
}
}
val permissionSpecNotification = if (Build.VERSION.SDK_INT >= 33) {
PermissionSpec(
permissions = listOf(
Manifest.permission.POST_NOTIFICATIONS,
),
deniedId = R.string.permission_denied_notifications,
rationalId = R.string.permission_rational_notifications,
)
} else {
PermissionSpec(
permissions = emptyList(),
deniedId = R.string.permission_denied_notifications,
rationalId = R.string.permission_rational_notifications,
)
}
val permissionSpecMediaDownload = if (Build.VERSION.SDK_INT >= 33) {
PermissionSpec(
permissions = listOf(Manifest.permission.POST_NOTIFICATIONS),
deniedId = R.string.permission_denied_download_manager,
rationalId = R.string.permission_rational_download_manager,
)
} else {
PermissionSpec(
permissions = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
deniedId = R.string.permission_denied_media_access,
rationalId = R.string.permission_rational_media_access,
)
}
val permissionSpecImagePicker = if (Build.VERSION.SDK_INT >= 33) {
PermissionSpec(
permissions = listOf(
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO,
Manifest.permission.READ_MEDIA_AUDIO,
),
deniedId = R.string.permission_denied_media_access,
rationalId = R.string.permission_rational_media_access,
)
} else {
PermissionSpec(
permissions = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
deniedId = R.string.permission_denied_media_access,
rationalId = R.string.permission_rational_media_access,
)
}

View File

@ -244,7 +244,7 @@
<string name="image_capture">Fes una foto</string>
<string name="video_capture">Filma un vídeo</string>
<string name="voice_capture">Grava una veu</string>
<string name="missing_permission_to_access_media">Falta el permís de l\'aplicació per accedir al contingut multimèdia. Concediu el permís a l\'aplicació a la configuració del dispositiu.</string>
<string name="permission_denied_media_access">Falta el permís de l\'aplicació per accedir al contingut multimèdia. Concediu el permís a l\'aplicació a la configuració del dispositiu.</string>
<string name="attachment_uploading">Carregant adjunció de mèdia…</string>
<string name="attachment_uploaded">S\'ha adjuntat el mèdia.</string>
<string name="actions_for_status">Accions en relació al bram</string>

View File

@ -266,7 +266,7 @@
<string name="actions_for_status">Aktionen für diesen Beitrag</string>
<string name="attachment_uploaded">Medienanhang wurde hochgeladen.</string>
<string name="attachment_uploading">Lade Medienanhang hoch…</string>
<string name="missing_permission_to_access_media">Fehlende App-Berechtigung, um Medien vom Gerät abzurufen. Bitte räume der App die entsprechende Berechtigung in den Systemeinstellungen ein.</string>
<string name="permission_denied_media_access">Fehlende App-Berechtigung, um Medien vom Gerät abzurufen. Bitte räume der App die entsprechende Berechtigung in den Systemeinstellungen ein.</string>
<string name="voice_capture">Sprachnachricht aufnehmen</string>
<string name="video_capture">Video aufnehmen</string>
<string name="image_capture">Bild aufnehmen</string>

View File

@ -189,7 +189,7 @@
<string name="mention2">Mentionner</string>
<string name="menu">Menu</string>
<string name="minimum_column_width">Largeur minimale des colonnes (défaut=300dp, redémarrage nécessaire)</string>
<string name="missing_permission_to_access_media">Autorisation de lapplication manquante pour accéder aux médias. Veuillez accorder l\'autorisation à l\'application dans les paramètres de l\'appareil.</string>
<string name="permission_denied_media_access">Autorisation de lapplication manquante pour accéder aux médias. Veuillez accorder l\'autorisation à l\'application dans les paramètres de l\'appareil.</string>
<string name="more">Plus</string>
<string name="mute">Désactiver le son</string>
<string name="mute_app_desc">&gt; Faîtes glisser à gauche pour supprimer. Vous devez rafraîchir les colonnes pour voir les statuts publiés par les applications non masquées.</string>

View File

@ -194,7 +194,7 @@
<string name="dont_resize">אל תשנה את הגודל</string>
<string name="long_side_pixel">שינוי גודל ל- %1$d פיקסלים</string>
<string name="image_capture">צלם תמונה</string>
<string name="missing_permission_to_access_media">חסר הרשאת יישום לצורך גישה למדיה.</string>
<string name="permission_denied_media_access">חסר הרשאת יישום לצורך גישה למדיה.</string>
<string name="attachment_uploading">מעלה מדיה מצורפת…</string>
<string name="attachment_uploaded">מדיה מצורפת הועלתה.</string>
<string name="actions_for_status">פעולות עבור התרועה הזו</string>

View File

@ -450,7 +450,6 @@
<string name="missing_fcm_device_id">FCMのデバイスIDを準備できません。しばらく後に試してください。</string>
<string name="missing_install_id">インストールIDを準備できません。しばらく後に試してください。</string>
<string name="missing_mail_app">メールアドレスを共有できるアプリがありません</string>
<string name="missing_permission_to_access_media">メディアアクセスに必要なアプリ権限がありません。端末の設定でアプリに権限を許可してください。</string>
<string name="missing_push_api">このサーバーにはプッシュ購読APIがありません。</string>
<string name="missing_push_scope">このアクセストークンは古いのでプッシュ購読の権限がありません。アクセストークンの更新をおすすめします。</string>
<string name="misskey">Misskey</string>
@ -1155,4 +1154,14 @@
<string name="conversation_with_reference">会話と参照</string>
<string name="tootsearch_discontinued">Tootsearchは2022/12/25にサービス終了しました。</string>
<string name="msp_discontinued">マストドン検索ポータルはサービス終了しました。</string>
<string name="permission_rational_notifications">通知を表示するには権限が必要です。</string>
<string name="permission_denied_notifications">通知を表示する権限がありません。</string>
<string name="permission_rational_download_manager">DownloadManagerを使用するには権限が必要です。</string>
<string name="permission_denied_download_manager">DownloadManagerを使用する権限がありません。</string>
<string name="permission_rational_media_access">端末上のデータにアクセスするには権限が必要です。</string>
<string name="permission_denied_media_access">端末上のデータにアクセスする権限がありません。</string>
</resources>

View File

@ -220,7 +220,7 @@
<string name="image_capture">ಚಿತ್ರ ತೆಗೆ</string>
<string name="video_capture">ವೀಡಿಯೊ ಸೆರೆಹಿಡಿ</string>
<string name="voice_capture">ಧ್ವನಿ ಸೆರೆಹಿಡಿ</string>
<string name="missing_permission_to_access_media">ಮಾಧ್ಯಮವನ್ನು ಪಡೆಯಲು ಅನ್ವಯಕ್ಕೆ ಅನುಮತಿ ಕಾಣೆಯಾಗಿದೆ.</string>
<string name="permission_denied_media_access">ಮಾಧ್ಯಮವನ್ನು ಪಡೆಯಲು ಅನ್ವಯಕ್ಕೆ ಅನುಮತಿ ಕಾಣೆಯಾಗಿದೆ.</string>
<string name="attachment_uploading">ಮಾಧ್ಯಮ ಲಗತ್ತನ್ನು ಜಾಲಕ್ಕೆ ಏರಿಸಲಾಗುತ್ತಿದೆ…</string>
<string name="attachment_uploaded">ಮಾಧ್ಯಮ ಲಗತ್ತನ್ನು ಜಾಲಕ್ಕೆ ಏರಿಸಲಾಯಿತು.</string>
<string name="actions_for_status">ಈ ಟೂಟ್‌ಗಾಗಿ ಕ್ರಿಯೆಗಳು</string>

View File

@ -231,7 +231,7 @@
<string name="dont_resize">크기 변경 하지 않기</string>
<string name="long_side_pixel">%1$d 화소로 변경</string>
<string name="image_capture">사진 찍기</string>
<string name="missing_permission_to_access_media">미디어 파일 접근에 필요한 앱 권한 없습니다.</string>
<string name="permission_denied_media_access">미디어 파일 접근에 필요한 앱 권한 없습니다.</string>
<string name="attachment_uploading">첨부 미디어 올리는 중…</string>
<string name="attachment_uploaded">첨부 미디어가 올려졌습니다.</string>
<string name="actions_for_status">이 툿에 대한 동작</string>

View File

@ -582,7 +582,7 @@
<string name="boost_from_another_account">Framhev fra en annen konto</string>
<string name="disable_fast_scroller">Skru av rask rulling (programomstart påkrevd)</string>
<string name="resize_image">Endre størrelse på bildevedlegg (JPEG, PNG)</string>
<string name="missing_permission_to_access_media">Mangler programtilgang for å åpne media.</string>
<string name="permission_denied_media_access">Mangler programtilgang for å åpne media.</string>
<string name="attachment_uploaded">Opplasting av multimediavedlegg fullført.</string>
<string name="tab_indicator_color">Fanens indikatorfarge</string>
<string name="text_to_speech_initializing">Starter tekst-til-tale…</string>

View File

@ -233,7 +233,7 @@
<string name="image_capture">Maak een foto</string>
<string name="video_capture">Neem een video op</string>
<string name="voice_capture">Neem geluid op</string>
<string name="missing_permission_to_access_media">Toegang tot media is niet verleend.</string>
<string name="permission_denied_media_access">Toegang tot media is niet verleend.</string>
<string name="attachment_uploading">Mediabijlage wordt geüpload…</string>
<string name="attachment_uploaded">Mediabijlage is geüpload.</string>
<string name="actions_for_status">Handelingen voor deze status</string>

View File

@ -241,7 +241,7 @@
<string name="actions_for_status">针对此嘟文的行动</string>
<string name="attachment_uploaded">媒体附件已上传.</string>
<string name="attachment_uploading">上传媒体附件中……</string>
<string name="missing_permission_to_access_media">缺少访问媒体的应用权限.请在设备设置中授予该应用权限.</string>
<string name="permission_denied_media_access">缺少访问媒体的应用权限.请在设备设置中授予该应用权限.</string>
<string name="voice_capture">录制音频</string>
<string name="video_capture">拍摄视频</string>
<string name="resize_square_pixels">调整尺寸至 %1$d 平方像素 (相当于 %2$dx%2$d)</string>

View File

@ -248,7 +248,6 @@
<string name="image_capture">Take a picture</string>
<string name="video_capture">Capture a video</string>
<string name="voice_capture">Capture a voice</string>
<string name="missing_permission_to_access_media">Missing app permission to access media. Please grant the permission to the app in the device settings.</string>
<string name="attachment_uploading">Uploading media attachment…</string>
<string name="attachment_uploaded">Media attachment was uploaded.</string>
<string name="actions_for_status">Actions for this toot</string>
@ -1164,4 +1163,13 @@
<string name="conversation_with_reference">conversation + reference</string>
<string name="tootsearch_discontinued">Tootsearch service discontinued on 2022/12/25.</string>
<string name="msp_discontinued">Mastodon Search Portal service was discontinued.</string>
<string name="permission_rational_notifications">to check/show notifications, the app need runtime permission.</string>
<string name="permission_denied_notifications">Missing app permission to show notifications.</string>
<string name="permission_rational_download_manager">Permission required to use DownloadManager.</string>
<string name="permission_denied_download_manager">Missing app permission to use DownloadManager.</string>
<string name="permission_rational_media_access">Permission required to access the device\'s media data.</string>
<string name="permission_denied_media_access">Missing app permission to access the device\'s media data.</string>
</resources>

View File

@ -3,7 +3,7 @@ buildscript {
ext.jvm_target = "1.8"
ext.min_sdk_version = 26
ext.target_sdk_version = 32
ext.target_sdk_version = 33
ext.compile_sdk_version = 33
ext.build_tools_version = "33.0.1"