pref: 优化权限申请

This commit is contained in:
HuanCheng65 2022-12-31 18:21:58 +08:00
parent 7b2a1836c1
commit 1c517de556
No known key found for this signature in database
GPG Key ID: E9031EF91A805148
9 changed files with 324 additions and 111 deletions

View File

@ -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<MyViewHolder>() {
private var fileList: MutableList<PhotoInfoBean> = ArrayList<PhotoInfoBean>()
@ -90,7 +90,7 @@ class InsertPhotoAdapter(private val mContext: Context) : RecyclerView.Adapter<M
}
PermissionUtils.askPermission(
mContext,
PermissionUtils.Permission(
PermissionUtils.PermissionData(
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
listOf(
PermissionUtils.READ_EXTERNAL_STORAGE,

View File

@ -12,7 +12,7 @@ import com.huanchengfly.tieba.post.dpToPx
import com.huanchengfly.tieba.post.utils.PermissionUtils
class RequestPermissionTipDialog(context: Context, permission: PermissionUtils.Permission) :
class RequestPermissionTipDialog(context: Context, permission: PermissionUtils.PermissionData) :
AlertDialog(context, R.style.Dialog_RequestPermissionTip) {
val title: TextView
val message: TextView

View File

@ -391,12 +391,12 @@ public class WebViewFragment extends BaseFragment implements DownloadListener, B
new PermissionDialog(getAttachContext(),
new PermissionBean(PermissionDialog.CustomPermission.PERMISSION_LOCATION,
uri.getHost(),
getAttachContext().getString(R.string.title_ask_permission, uri.getHost(), getAttachContext().getString(R.string.permission_name_location)),
getAttachContext().getString(R.string.title_ask_permission, uri.getHost(), getAttachContext().getString(R.string.common_permission_location)),
R.drawable.ic_round_location_on))
.setOnGrantedCallback(isForever -> {
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)
),

View File

@ -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)
)

View File

@ -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)
),

View File

@ -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)
),

View File

@ -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<String>): List<String> {
val textList: MutableList<String> = ArrayList()
val permissionNames: MutableList<String> = 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<String>, all: Boolean) {
if (all) {
@ -190,20 +355,66 @@ object PermissionUtils {
context.toastShort(deniedToast)
onDenied?.invoke()
}
dialog.dismiss()
}
override fun onDenied(permissions: List<String>, never: Boolean) {
context.toastShort(deniedToast)
onDenied?.invoke()
dialog.dismiss()
}
})
dialog.show()
}
}
data class Permission(val permissions: List<String>, val desc: String)
data class PermissionData(val permissions: List<String>, val desc: String)
}
class ShowPermissionTipInterceptor(val permissions: List<String>, 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<String>,
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<String>,
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<String>, never: Boolean) {
onDenied?.invoke()
if (showDialog) dialog.dismiss()
}
})
if (showDialog) dialog.show()
}
}
}

View File

@ -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" />

View File

@ -509,18 +509,37 @@
<string name="toast_ignore_battery_optimization_already">已忽略电池优化</string>
<string name="button_copy_crash">复制崩溃报告</string>
<string name="button_redo">重做</string>
<string name="permission_name_calendar">日历</string>
<string name="permission_name_camera">相机</string>
<string name="permission_name_contacts">手机账号 / 通讯录</string>
<string name="permission_name_location">位置信息</string>
<string name="permission_name_microphone">麦克风</string>
<string name="permission_name_phone">电话</string>
<string name="permission_name_call_log">通话记录</string>
<string name="permission_name_sensors">身体传感器</string>
<string name="permission_name_activity_recognition">健身运动</string>
<string name="permission_name_sms">短信</string>
<string name="permission_name_storage">存储空间</string>
<string name="permission_name_images">媒体图片</string>
<string name="common_permission_calendar">日历</string>
<string name="common_permission_camera">相机</string>
<string name="common_permission_contacts">通讯录</string>
<string name="common_permission_location">定位</string>
<string name="common_permission_location_background">后台定位</string>
<string name="common_permission_nearby_devices">附近的设备</string>
<string name="common_permission_microphone">麦克风</string>
<string name="common_permission_phone">电话</string>
<string name="common_permission_call_logs">通话记录</string>
<string name="common_permission_body_sensors">身体传感器</string>
<string name="common_permission_body_sensors_background">后台身体传感器</string>
<string name="common_permission_activity_recognition_api29">健身运动</string>
<string name="common_permission_activity_recognition_api30">身体活动</string>
<string name="common_permission_access_media_location">读取媒体文件位置</string>
<string name="common_permission_sms">短信</string>
<string name="common_permission_storage">存储</string>
<string name="common_permission_post_notifications">发送通知</string>
<string name="common_permission_image_and_video">照片和视频</string>
<string name="common_permission_music_and_audio">音乐和音频</string>
<string name="common_permission_all_file_access">所有文件访问</string>
<string name="common_permission_install_unknown_apps">安装应用</string>
<string name="common_permission_display_over_other_apps">悬浮窗</string>
<string name="common_permission_modify_system_settings">修改系统设置</string>
<string name="common_permission_allow_notifications">通知</string>
<string name="common_permission_allow_notifications_access">通知栏监听</string>
<string name="common_permission_apps_with_usage_access">查看使用情况</string>
<string name="common_permission_alarms_reminders">查看闹钟提醒</string>
<string name="common_permission_do_not_disturb_access">勿扰</string>
<string name="common_permission_ignore_battery_optimize">忽略电池优化</string>
<string name="common_permission_picture_in_picture">画中画</string>
<string name="common_permission_vpn">\tVPN\t</string>
<string name="title_request_permission_tip_dialog">贴吧 Lite 正在请求“%1$s”权限</string>
<string name="message_request_permission_tip_dialog">授权后,将%1$s</string>
<string name="usage_webview_location_permission">用于向当前访问的网页提供你的位置信息,以便该网页向你提供相关服务。</string>