diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/InsertPhotoAdapter.kt b/app/src/main/java/com/huanchengfly/tieba/post/adapters/InsertPhotoAdapter.kt index 9bd2d43b..a2aeeffa 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/adapters/InsertPhotoAdapter.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/InsertPhotoAdapter.kt @@ -19,7 +19,7 @@ import com.huanchengfly.tieba.post.models.PhotoInfoBean import com.huanchengfly.tieba.post.utils.PermissionUtils import com.huanchengfly.tieba.post.utils.PickMediasRequest import com.huanchengfly.tieba.post.utils.isPhotoPickerAvailable -import java.util.* +import java.util.Collections class InsertPhotoAdapter(private val mContext: Context) : RecyclerView.Adapter() { private var fileList: MutableList = ArrayList() @@ -90,7 +90,7 @@ class InsertPhotoAdapter(private val mContext: Context) : RecyclerView.Adapter { PermissionUtils.INSTANCE.askPermission( getAttachContext(), - new PermissionUtils.Permission( + new PermissionUtils.PermissionData( Arrays.asList(Permission.ACCESS_COARSE_LOCATION, Permission.ACCESS_FINE_LOCATION), getAttachContext().getString(R.string.usage_webview_location_permission) ), diff --git a/app/src/main/java/com/huanchengfly/tieba/post/fragments/intro/PermissionFragment.kt b/app/src/main/java/com/huanchengfly/tieba/post/fragments/intro/PermissionFragment.kt index 6a9f39ac..a3a8ffd0 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/fragments/intro/PermissionFragment.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/fragments/intro/PermissionFragment.kt @@ -32,7 +32,7 @@ class PermissionFragment : BaseIntroFragment() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { PermissionUtils.askPermission( attachContext, - PermissionUtils.Permission( + PermissionUtils.PermissionData( listOf(PermissionUtils.READ_PHONE_STATE), getString(R.string.tip_permission_phone) ) diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/FileUtil.java b/app/src/main/java/com/huanchengfly/tieba/post/utils/FileUtil.java index f3233429..123907d1 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/utils/FileUtil.java +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/FileUtil.java @@ -199,7 +199,7 @@ public class FileUtil { } PermissionUtils.INSTANCE.askPermission( context, - new PermissionUtils.Permission( + new PermissionUtils.PermissionData( Arrays.asList(PermissionUtils.READ_EXTERNAL_STORAGE, PermissionUtils.WRITE_EXTERNAL_STORAGE), context.getString(R.string.tip_permission_storage_download) ), diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/ImageUtil.java b/app/src/main/java/com/huanchengfly/tieba/post/utils/ImageUtil.java index 18078810..e1033674 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/utils/ImageUtil.java +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/ImageUtil.java @@ -282,7 +282,7 @@ public class ImageUtil { } PermissionUtils.INSTANCE.askPermission( context, - new PermissionUtils.Permission( + new PermissionUtils.PermissionData( Arrays.asList(PermissionUtils.READ_EXTERNAL_STORAGE, PermissionUtils.WRITE_EXTERNAL_STORAGE), context.getString(R.string.tip_permission_storage) ), diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/PermissionUtils.kt b/app/src/main/java/com/huanchengfly/tieba/post/utils/PermissionUtils.kt index c41cfad1..9450289c 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/utils/PermissionUtils.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/PermissionUtils.kt @@ -3,8 +3,11 @@ package com.huanchengfly.tieba.post.utils import android.app.Activity import android.content.Context import android.os.Build -import androidx.core.app.ActivityCompat +import android.os.Handler +import android.os.Looper +import com.hjq.permissions.IPermissionInterceptor import com.hjq.permissions.OnPermissionCallback +import com.hjq.permissions.Permission import com.hjq.permissions.XXPermissions import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.components.dialogs.RequestPermissionTipDialog @@ -57,131 +60,293 @@ object PermissionUtils { * Turn permissions into text. */ fun transformText(context: Context, permissions: List): List { - val textList: MutableList = ArrayList() + val permissionNames: MutableList = mutableListOf() + if (context == null) { + return permissionNames + } + if (permissions == null) { + return permissionNames + } for (permission in permissions) { when (permission) { - READ_CALENDAR, WRITE_CALENDAR -> { - val message = context.getString(R.string.permission_name_calendar) - if (!textList.contains(message)) { - textList.add(message) + Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE -> { + val hint = context.getString(R.string.common_permission_storage) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } - CAMERA -> { - val message = context.getString(R.string.permission_name_camera) - if (!textList.contains(message)) { - textList.add(message) + + Permission.READ_MEDIA_IMAGES, Permission.READ_MEDIA_VIDEO -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val hint = context.getString(R.string.common_permission_image_and_video) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } } } - GET_ACCOUNTS, READ_CONTACTS, WRITE_CONTACTS -> { - val message = context.getString(R.string.permission_name_contacts) - if (!textList.contains(message)) { - textList.add(message) + + Permission.READ_MEDIA_AUDIO -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val hint = context.getString(R.string.common_permission_music_and_audio) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } } } - ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION -> { - val message = context.getString(R.string.permission_name_location) - if (!textList.contains(message)) { - textList.add(message) + + Permission.CAMERA -> { + val hint = context.getString(R.string.common_permission_camera) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } - RECORD_AUDIO -> { - val message = context.getString(R.string.permission_name_microphone) - if (!textList.contains(message)) { - textList.add(message) + + Permission.RECORD_AUDIO -> { + val hint = context.getString(R.string.common_permission_microphone) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } - READ_PHONE_STATE, CALL_PHONE, ADD_VOICEMAIL, USE_SIP, READ_PHONE_NUMBERS, ANSWER_PHONE_CALLS -> { - val message = context.getString(R.string.permission_name_phone) - if (!textList.contains(message)) { - textList.add(message) + + Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_COARSE_LOCATION, Permission.ACCESS_BACKGROUND_LOCATION -> { + val hint: String = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && + !permissions.contains(Permission.ACCESS_FINE_LOCATION) && + !permissions.contains(Permission.ACCESS_COARSE_LOCATION) + ) { + context.getString(R.string.common_permission_location_background) + } else { + context.getString(R.string.common_permission_location) + } + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } - READ_CALL_LOG, WRITE_CALL_LOG, PROCESS_OUTGOING_CALLS -> { - val messageId: Int = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) R.string.permission_name_call_log else R.string.permission_name_phone - val message = context.getString(messageId) - if (!textList.contains(message)) { - textList.add(message) + + Permission.BODY_SENSORS, Permission.BODY_SENSORS_BACKGROUND -> { + val hint: String = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && + !permissions.contains(Permission.BODY_SENSORS) + ) { + context.getString(R.string.common_permission_body_sensors_background) + } else { + context.getString(R.string.common_permission_body_sensors) + } + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } - BODY_SENSORS -> { - val message = context.getString(R.string.permission_name_sensors) - if (!textList.contains(message)) { - textList.add(message) + + Permission.BLUETOOTH_SCAN, Permission.BLUETOOTH_CONNECT, Permission.BLUETOOTH_ADVERTISE -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + val hint = context.getString(R.string.common_permission_nearby_devices) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } } } - ACTIVITY_RECOGNITION -> { - val message = context.getString(R.string.permission_name_activity_recognition) - if (!textList.contains(message)) { - textList.add(message) + + Permission.NEARBY_WIFI_DEVICES -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val hint = context.getString(R.string.common_permission_nearby_devices) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } } } - SEND_SMS, RECEIVE_SMS, READ_SMS, RECEIVE_WAP_PUSH, RECEIVE_MMS -> { - val message = context.getString(R.string.permission_name_sms) - if (!textList.contains(message)) { - textList.add(message) + + Permission.READ_PHONE_STATE, Permission.CALL_PHONE, Permission.ADD_VOICEMAIL, Permission.USE_SIP, Permission.READ_PHONE_NUMBERS, Permission.ANSWER_PHONE_CALLS -> { + val hint = context.getString(R.string.common_permission_phone) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } - READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE -> { - val message = context.getString(R.string.permission_name_storage) - if (!textList.contains(message)) { - textList.add(message) + + Permission.GET_ACCOUNTS, Permission.READ_CONTACTS, Permission.WRITE_CONTACTS -> { + val hint = context.getString(R.string.common_permission_contacts) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } - READ_MEDIA_IMAGES -> { - val message = context.getString(R.string.permission_name_images) - if (!textList.contains(message)) { - textList.add(message) + + Permission.READ_CALENDAR, Permission.WRITE_CALENDAR -> { + val hint = context.getString(R.string.common_permission_calendar) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } - POST_NOTIFICATIONS -> { - val message = context.getString(R.string.permission_name_post_notifications) - if (!textList.contains(message)) { - textList.add(message) + + Permission.READ_CALL_LOG, Permission.WRITE_CALL_LOG, Permission.PROCESS_OUTGOING_CALLS -> { + val hint = + context.getString(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) R.string.common_permission_call_logs else R.string.common_permission_phone) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) } } + + Permission.ACTIVITY_RECOGNITION -> { + val hint = + context.getString(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) R.string.common_permission_activity_recognition_api30 else R.string.common_permission_activity_recognition_api29) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.ACCESS_MEDIA_LOCATION -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val hint = + context.getString(R.string.common_permission_access_media_location) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + } + + Permission.SEND_SMS, Permission.RECEIVE_SMS, Permission.READ_SMS, Permission.RECEIVE_WAP_PUSH, Permission.RECEIVE_MMS -> { + val hint = context.getString(R.string.common_permission_sms) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.MANAGE_EXTERNAL_STORAGE -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val hint = context.getString(R.string.common_permission_all_file_access) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + } + + Permission.REQUEST_INSTALL_PACKAGES -> { + val hint = context.getString(R.string.common_permission_install_unknown_apps) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.SYSTEM_ALERT_WINDOW -> { + val hint = context.getString(R.string.common_permission_display_over_other_apps) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.WRITE_SETTINGS -> { + val hint = context.getString(R.string.common_permission_modify_system_settings) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.NOTIFICATION_SERVICE -> { + val hint = context.getString(R.string.common_permission_allow_notifications) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.POST_NOTIFICATIONS -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val hint = context.getString(R.string.common_permission_post_notifications) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + } + + Permission.BIND_NOTIFICATION_LISTENER_SERVICE -> { + val hint = + context.getString(R.string.common_permission_allow_notifications_access) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.PACKAGE_USAGE_STATS -> { + val hint = context.getString(R.string.common_permission_apps_with_usage_access) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.SCHEDULE_EXACT_ALARM -> { + val hint = context.getString(R.string.common_permission_alarms_reminders) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.ACCESS_NOTIFICATION_POLICY -> { + val hint = context.getString(R.string.common_permission_do_not_disturb_access) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS -> { + val hint = context.getString(R.string.common_permission_ignore_battery_optimize) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.BIND_VPN_SERVICE -> { + val hint = context.getString(R.string.common_permission_vpn) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + Permission.PICTURE_IN_PICTURE -> { + val hint = context.getString(R.string.common_permission_picture_in_picture) + if (!permissionNames.contains(hint)) { + permissionNames.add(hint) + } + } + + else -> {} } } - return textList + + return permissionNames } - fun askPermission(context: Context, permission: Permission, onGranted: () -> Unit) { - askPermission(context, permission, R.string.tip_no_permission, onGranted) + fun askPermission(context: Context, permissionData: PermissionData, onGranted: () -> Unit) { + askPermission(context, permissionData, R.string.tip_no_permission, onGranted) } fun askPermission( context: Context, - permission: Permission, + permissionData: PermissionData, deniedToast: Int, onGranted: () -> Unit ) { - askPermission(context, permission, context.getString(deniedToast), onGranted, null) + askPermission(context, permissionData, context.getString(deniedToast), onGranted, null) } fun askPermission( context: Context, - permission: Permission, + permissionData: PermissionData, deniedToast: Int, onGranted: () -> Unit, onDenied: (() -> Unit)? ) { - askPermission(context, permission, context.getString(deniedToast), onGranted, onDenied) + askPermission(context, permissionData, context.getString(deniedToast), onGranted, onDenied) } @JvmOverloads fun askPermission( context: Context, - permission: Permission, + permissionData: PermissionData, deniedToast: String, onGranted: () -> Unit, onDenied: (() -> Unit)? = null ) { - if (XXPermissions.isGranted(context, permission.permissions)) { + if (XXPermissions.isGranted(context, permissionData.permissions)) { onGranted() } else { - val dialog = RequestPermissionTipDialog(context, permission) XXPermissions.with(context) - .permission(permission.permissions) + .permission(permissionData.permissions) + .interceptor(ShowPermissionTipInterceptor(permissionData)) .request(object : OnPermissionCallback { override fun onGranted(permissions: List, all: Boolean) { if (all) { @@ -190,20 +355,66 @@ object PermissionUtils { context.toastShort(deniedToast) onDenied?.invoke() } - dialog.dismiss() } override fun onDenied(permissions: List, never: Boolean) { context.toastShort(deniedToast) onDenied?.invoke() - dialog.dismiss() } }) - dialog.show() } } - data class Permission(val permissions: List, val desc: String) + data class PermissionData(val permissions: List, val desc: String) +} + +class ShowPermissionTipInterceptor(val permissions: List, val description: String) : + IPermissionInterceptor { + companion object { + @JvmStatic + val HANDLER: Handler = Handler(Looper.getMainLooper()) + } + + constructor(permissionData: PermissionUtils.PermissionData) : this( + permissionData.permissions, + permissionData.desc + ) + + private var mRequestFlag = false + + private var tipDialog: RequestPermissionTipDialog? = null + + override fun launchPermissionRequest( + activity: Activity, + allPermissions: MutableList, + callback: OnPermissionCallback? + ) { + mRequestFlag = true + super.launchPermissionRequest(activity, allPermissions, callback) + HANDLER.postDelayed({ + if (!mRequestFlag) { + return@postDelayed + } + if (activity.isFinishing || activity.isDestroyed) { + return@postDelayed + } + tipDialog = RequestPermissionTipDialog( + activity, + PermissionUtils.PermissionData(permissions, description) + ).apply { show() } + tipDialog?.show() + }, 300) + } + + override fun finishPermissionRequest( + activity: Activity, + allPermissions: MutableList, + skipRequest: Boolean, + callback: OnPermissionCallback? + ) { + mRequestFlag = false + tipDialog?.dismiss() + } } class PermissionRequester(val context: Context) { @@ -217,23 +428,9 @@ class PermissionRequester(val context: Context) { if (XXPermissions.isGranted(context, permissions)) { onGranted?.invoke() } else { - val isFirstRequest = permissions.any { - !SharedPreferencesUtil.get(SharedPreferencesUtil.SP_PERMISSION) - .getBoolean("tried_request_${it}", false) - } - val showRationale = (context !is Activity) || permissions.any { - ActivityCompat.shouldShowRequestPermissionRationale( - context, - it - ) - } - val showDialog = isFirstRequest || showRationale - val dialog = RequestPermissionTipDialog( - context, - PermissionUtils.Permission(permissions, description) - ) XXPermissions.with(context) .permission(permissions) + .interceptor(ShowPermissionTipInterceptor(permissions, description)) .apply { if (unchecked) { unchecked() @@ -246,15 +443,12 @@ class PermissionRequester(val context: Context) { } else { onDenied?.invoke() } - if (showDialog) dialog.dismiss() } override fun onDenied(permissions: List, never: Boolean) { onDenied?.invoke() - if (showDialog) dialog.dismiss() } }) - if (showDialog) dialog.show() } } } diff --git a/app/src/main/res/layout/layout_fragment_permission.xml b/app/src/main/res/layout/layout_fragment_permission.xml index 03d5662a..62eebc47 100644 --- a/app/src/main/res/layout/layout_fragment_permission.xml +++ b/app/src/main/res/layout/layout_fragment_permission.xml @@ -32,7 +32,7 @@ android:layout_marginStart="16dp" android:layout_marginBottom="4dp" android:layout_toEndOf="@+id/permission_icon_storage" - android:text="@string/permission_name_storage" + android:text="@string/common_permission_storage" android:textColor="@color/default_color_text" android:textSize="15sp" android:textStyle="bold" /> @@ -78,7 +78,7 @@ android:layout_marginStart="16dp" android:layout_marginBottom="4dp" android:layout_toEndOf="@+id/permission_icon_phone" - android:text="@string/permission_name_phone" + android:text="@string/common_permission_phone" android:textColor="@color/default_color_text" android:textSize="15sp" android:textStyle="bold" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 79885e91..e2cd543e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -509,18 +509,37 @@ 已忽略电池优化 复制崩溃报告 重做 - 日历 - 相机 - 手机账号 / 通讯录 - 位置信息 - 麦克风 - 电话 - 通话记录 - 身体传感器 - 健身运动 - 短信 - 存储空间 - 媒体图片 + 日历 + 相机 + 通讯录 + 定位 + 后台定位 + 附近的设备 + 麦克风 + 电话 + 通话记录 + 身体传感器 + 后台身体传感器 + 健身运动 + 身体活动 + 读取媒体文件位置 + 短信 + 存储 + 发送通知 + 照片和视频 + 音乐和音频 + 所有文件访问 + 安装应用 + 悬浮窗 + 修改系统设置 + 通知 + 通知栏监听 + 查看使用情况 + 查看闹钟提醒 + 勿扰 + 忽略电池优化 + 画中画 + \tVPN\t 贴吧 Lite 正在请求“%1$s”权限 授权后,将%1$s 用于向当前访问的网页提供你的位置信息,以便该网页向你提供相关服务。