parent
ca4caec216
commit
8d1199925f
@ -1,4 +1,4 @@ |
||||
package io.legado.app.help.permission |
||||
package io.legado.app.constant |
||||
|
||||
@Suppress("unused") |
||||
object Permissions { |
@ -1,20 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import android.content.Context |
||||
import android.content.Intent |
||||
import androidx.appcompat.app.AppCompatActivity |
||||
|
||||
import java.lang.ref.WeakReference |
||||
|
||||
internal class ActivitySource(activity: AppCompatActivity) : RequestSource { |
||||
|
||||
private val actRef: WeakReference<AppCompatActivity> = WeakReference(activity) |
||||
|
||||
override val context: Context? |
||||
get() = actRef.get() |
||||
|
||||
override fun startActivity(intent: Intent) { |
||||
actRef.get()?.startActivity(intent) |
||||
} |
||||
|
||||
} |
@ -1,19 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import android.content.Context |
||||
import android.content.Intent |
||||
import androidx.fragment.app.Fragment |
||||
|
||||
import java.lang.ref.WeakReference |
||||
|
||||
internal class FragmentSource(fragment: Fragment) : RequestSource { |
||||
|
||||
private val fragRef: WeakReference<Fragment> = WeakReference(fragment) |
||||
|
||||
override val context: Context? |
||||
get() = fragRef.get()?.requireContext() |
||||
|
||||
override fun startActivity(intent: Intent) { |
||||
fragRef.get()?.startActivity(intent) |
||||
} |
||||
} |
@ -1,7 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
interface OnPermissionsDeniedCallback { |
||||
|
||||
fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>) |
||||
|
||||
} |
@ -1,7 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
interface OnPermissionsGrantedCallback { |
||||
|
||||
fun onPermissionsGranted(requestCode: Int) |
||||
|
||||
} |
@ -1,9 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
interface OnPermissionsResultCallback { |
||||
|
||||
fun onPermissionsGranted(requestCode: Int) |
||||
|
||||
fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>) |
||||
|
||||
} |
@ -1,10 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import android.content.Intent |
||||
|
||||
interface OnRequestPermissionsResultCallback { |
||||
|
||||
fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) |
||||
|
||||
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) |
||||
} |
@ -1,76 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import android.content.Intent |
||||
import android.net.Uri |
||||
import android.os.Bundle |
||||
import android.provider.Settings |
||||
import android.view.KeyEvent |
||||
import androidx.appcompat.app.AppCompatActivity |
||||
import androidx.core.app.ActivityCompat |
||||
import io.legado.app.R |
||||
import io.legado.app.utils.toastOnUi |
||||
|
||||
class PermissionActivity : AppCompatActivity() { |
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) { |
||||
super.onCreate(savedInstanceState) |
||||
|
||||
when (intent.getIntExtra(KEY_INPUT_REQUEST_TYPE, Request.TYPE_REQUEST_PERMISSION)) { |
||||
Request.TYPE_REQUEST_PERMISSION//权限请求 |
||||
-> { |
||||
val requestCode = intent.getIntExtra(KEY_INPUT_PERMISSIONS_CODE, 1000) |
||||
val permissions = intent.getStringArrayExtra(KEY_INPUT_PERMISSIONS) |
||||
if (permissions != null) { |
||||
ActivityCompat.requestPermissions(this, permissions, requestCode) |
||||
} else { |
||||
finish() |
||||
} |
||||
} |
||||
Request.TYPE_REQUEST_SETTING//跳转到设置界面 |
||||
-> try { |
||||
val settingIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) |
||||
settingIntent.data = Uri.fromParts("package", packageName, null) |
||||
startActivityForResult(settingIntent, Request.TYPE_REQUEST_SETTING) |
||||
} catch (e: Exception) { |
||||
toastOnUi(R.string.tip_cannot_jump_setting_page) |
||||
finish() |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { |
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults) |
||||
RequestPlugins.sRequestCallback?.onRequestPermissionsResult(requestCode, permissions, grantResults) |
||||
finish() |
||||
} |
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { |
||||
super.onActivityResult(requestCode, resultCode, data) |
||||
RequestPlugins.sRequestCallback?.onActivityResult(requestCode, resultCode, data) |
||||
finish() |
||||
} |
||||
|
||||
override fun startActivity(intent: Intent) { |
||||
super.startActivity(intent) |
||||
overridePendingTransition(0, 0) |
||||
} |
||||
|
||||
override fun finish() { |
||||
super.finish() |
||||
overridePendingTransition(0, 0) |
||||
} |
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { |
||||
return if (keyCode == KeyEvent.KEYCODE_BACK) { |
||||
true |
||||
} else super.onKeyDown(keyCode, event) |
||||
} |
||||
|
||||
companion object { |
||||
|
||||
const val KEY_INPUT_REQUEST_TYPE = "KEY_INPUT_REQUEST_TYPE" |
||||
const val KEY_INPUT_PERMISSIONS_CODE = "KEY_INPUT_PERMISSIONS_CODE" |
||||
const val KEY_INPUT_PERMISSIONS = "KEY_INPUT_PERMISSIONS" |
||||
} |
||||
} |
@ -1,91 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import androidx.annotation.StringRes |
||||
import androidx.appcompat.app.AppCompatActivity |
||||
import androidx.fragment.app.Fragment |
||||
import java.util.* |
||||
|
||||
@Suppress("unused") |
||||
class PermissionsCompat private constructor() { |
||||
|
||||
private var request: Request? = null |
||||
|
||||
fun request() { |
||||
RequestManager.pushRequest(request) |
||||
} |
||||
|
||||
companion object { |
||||
// 检查权限, 如果已经拥有返回 true |
||||
fun check(activity: AppCompatActivity, vararg permissions: String): Boolean { |
||||
val request = Request(activity) |
||||
val pers = ArrayList<String>() |
||||
pers.addAll(listOf(*permissions)) |
||||
val data = request.getDeniedPermissions(pers.toTypedArray()) |
||||
return data == null |
||||
} |
||||
} |
||||
|
||||
class Builder { |
||||
private val request: Request |
||||
|
||||
constructor(activity: AppCompatActivity) { |
||||
request = Request(activity) |
||||
} |
||||
|
||||
constructor(fragment: Fragment) { |
||||
request = Request(fragment) |
||||
} |
||||
|
||||
fun addPermissions(vararg permissions: String): Builder { |
||||
request.addPermissions(*permissions) |
||||
return this |
||||
} |
||||
|
||||
fun requestCode(requestCode: Int): Builder { |
||||
request.setRequestCode(requestCode) |
||||
return this |
||||
} |
||||
|
||||
fun onGranted(callback: (requestCode: Int) -> Unit): Builder { |
||||
request.setOnGrantedCallback(object : OnPermissionsGrantedCallback { |
||||
override fun onPermissionsGranted(requestCode: Int) { |
||||
callback(requestCode) |
||||
} |
||||
}) |
||||
return this |
||||
} |
||||
|
||||
fun onDenied(callback: (requestCode: Int, deniedPermissions: Array<String>) -> Unit): Builder { |
||||
request.setOnDeniedCallback(object : OnPermissionsDeniedCallback { |
||||
override fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>) { |
||||
callback(requestCode, deniedPermissions) |
||||
} |
||||
}) |
||||
return this |
||||
} |
||||
|
||||
fun rationale(rationale: CharSequence): Builder { |
||||
request.setRationale(rationale) |
||||
return this |
||||
} |
||||
|
||||
fun rationale(@StringRes resId: Int): Builder { |
||||
request.setRationale(resId) |
||||
return this |
||||
} |
||||
|
||||
fun build(): PermissionsCompat { |
||||
val compat = PermissionsCompat() |
||||
compat.request = request |
||||
return compat |
||||
} |
||||
|
||||
fun request(): PermissionsCompat { |
||||
val compat = build() |
||||
compat.request = request |
||||
compat.request() |
||||
return compat |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,204 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import android.content.Intent |
||||
import android.content.pm.PackageManager |
||||
import android.os.Build |
||||
import androidx.annotation.StringRes |
||||
import androidx.appcompat.app.AlertDialog |
||||
import androidx.appcompat.app.AppCompatActivity |
||||
import androidx.core.content.ContextCompat |
||||
import androidx.fragment.app.Fragment |
||||
import io.legado.app.R |
||||
import io.legado.app.utils.startActivity |
||||
import java.util.* |
||||
|
||||
internal class Request : OnRequestPermissionsResultCallback { |
||||
|
||||
internal val requestTime: Long |
||||
private var requestCode: Int = TYPE_REQUEST_PERMISSION |
||||
private var source: RequestSource? = null |
||||
private var permissions: ArrayList<String>? = null |
||||
private var grantedCallback: OnPermissionsGrantedCallback? = null |
||||
private var deniedCallback: OnPermissionsDeniedCallback? = null |
||||
private var rationaleResId: Int = 0 |
||||
private var rationale: CharSequence? = null |
||||
|
||||
private var rationaleDialog: AlertDialog? = null |
||||
|
||||
private val deniedPermissions: Array<String>? |
||||
get() { |
||||
return getDeniedPermissions(this.permissions?.toTypedArray()) |
||||
} |
||||
|
||||
constructor(activity: AppCompatActivity) { |
||||
source = ActivitySource(activity) |
||||
permissions = ArrayList() |
||||
requestTime = System.currentTimeMillis() |
||||
} |
||||
|
||||
constructor(fragment: Fragment) { |
||||
source = FragmentSource(fragment) |
||||
permissions = ArrayList() |
||||
requestTime = System.currentTimeMillis() |
||||
} |
||||
|
||||
fun addPermissions(vararg permissions: String) { |
||||
this.permissions?.addAll(listOf(*permissions)) |
||||
} |
||||
|
||||
fun setRequestCode(requestCode: Int) { |
||||
this.requestCode = requestCode |
||||
} |
||||
|
||||
fun setOnGrantedCallback(callback: OnPermissionsGrantedCallback) { |
||||
grantedCallback = callback |
||||
} |
||||
|
||||
fun setOnDeniedCallback(callback: OnPermissionsDeniedCallback) { |
||||
deniedCallback = callback |
||||
} |
||||
|
||||
fun setRationale(@StringRes resId: Int) { |
||||
rationaleResId = resId |
||||
rationale = null |
||||
} |
||||
|
||||
fun setRationale(rationale: CharSequence) { |
||||
this.rationale = rationale |
||||
rationaleResId = 0 |
||||
} |
||||
|
||||
fun start() { |
||||
RequestPlugins.setOnRequestPermissionsCallback(this) |
||||
|
||||
val deniedPermissions = deniedPermissions |
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { |
||||
if (deniedPermissions == null) { |
||||
onPermissionsGranted(requestCode) |
||||
} else { |
||||
val rationale = |
||||
if (rationaleResId != 0) source?.context?.getText(rationaleResId) else rationale |
||||
if (rationale != null) { |
||||
showSettingDialog(rationale) { |
||||
onPermissionsDenied( |
||||
requestCode, |
||||
deniedPermissions |
||||
) |
||||
} |
||||
} else { |
||||
onPermissionsDenied(requestCode, deniedPermissions) |
||||
} |
||||
} |
||||
} else { |
||||
if (deniedPermissions != null) { |
||||
source?.context?.startActivity<PermissionActivity> { |
||||
putExtra(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_REQUEST_PERMISSION) |
||||
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode) |
||||
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions) |
||||
} |
||||
} else { |
||||
onPermissionsGranted(requestCode) |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun clear() { |
||||
grantedCallback = null |
||||
deniedCallback = null |
||||
} |
||||
|
||||
fun getDeniedPermissions(permissions: Array<String>?): Array<String>? { |
||||
if (permissions != null) { |
||||
val deniedPermissionList = ArrayList<String>() |
||||
for (permission in permissions) { |
||||
if (source?.context?.let { |
||||
ContextCompat.checkSelfPermission( |
||||
it, |
||||
permission |
||||
) |
||||
} != PackageManager.PERMISSION_GRANTED |
||||
) { |
||||
deniedPermissionList.add(permission) |
||||
} |
||||
} |
||||
val size = deniedPermissionList.size |
||||
if (size > 0) { |
||||
return deniedPermissionList.toTypedArray() |
||||
} |
||||
} |
||||
return null |
||||
} |
||||
|
||||
private fun showSettingDialog(rationale: CharSequence, cancel: () -> Unit) { |
||||
rationaleDialog?.dismiss() |
||||
source?.context?.let { |
||||
runCatching { |
||||
rationaleDialog = AlertDialog.Builder(it) |
||||
.setTitle(R.string.dialog_title) |
||||
.setMessage(rationale) |
||||
.setPositiveButton(R.string.dialog_setting) { _, _ -> |
||||
it.startActivity<PermissionActivity> { |
||||
putExtra( |
||||
PermissionActivity.KEY_INPUT_REQUEST_TYPE, |
||||
TYPE_REQUEST_SETTING |
||||
) |
||||
} |
||||
} |
||||
.setNegativeButton(R.string.dialog_cancel) { _, _ -> cancel() } |
||||
.show() |
||||
} |
||||
} |
||||
} |
||||
|
||||
private fun onPermissionsGranted(requestCode: Int) { |
||||
try { |
||||
grantedCallback?.onPermissionsGranted(requestCode) |
||||
} catch (ignore: Exception) { |
||||
} |
||||
|
||||
RequestPlugins.sResultCallback?.onPermissionsGranted(requestCode) |
||||
} |
||||
|
||||
private fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>) { |
||||
try { |
||||
deniedCallback?.onPermissionsDenied(requestCode, deniedPermissions) |
||||
} catch (ignore: Exception) { |
||||
} |
||||
|
||||
RequestPlugins.sResultCallback?.onPermissionsDenied(requestCode, deniedPermissions) |
||||
} |
||||
|
||||
override fun onRequestPermissionsResult( |
||||
requestCode: Int, |
||||
permissions: Array<String>, |
||||
grantResults: IntArray |
||||
) { |
||||
val deniedPermissions = getDeniedPermissions(permissions) |
||||
if (deniedPermissions != null) { |
||||
val rationale = |
||||
if (rationaleResId != 0) source?.context?.getText(rationaleResId) else rationale |
||||
if (rationale != null) { |
||||
showSettingDialog(rationale) { onPermissionsDenied(requestCode, deniedPermissions) } |
||||
} else { |
||||
onPermissionsDenied(requestCode, deniedPermissions) |
||||
} |
||||
} else { |
||||
onPermissionsGranted(requestCode) |
||||
} |
||||
} |
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { |
||||
val deniedPermissions = deniedPermissions |
||||
if (deniedPermissions == null) { |
||||
onPermissionsGranted(this.requestCode) |
||||
} else { |
||||
onPermissionsDenied(this.requestCode, deniedPermissions) |
||||
} |
||||
} |
||||
|
||||
companion object { |
||||
const val TYPE_REQUEST_PERMISSION = 1 |
||||
const val TYPE_REQUEST_SETTING = 2 |
||||
} |
||||
} |
@ -1,69 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import android.os.Handler |
||||
import android.os.Looper |
||||
import java.util.* |
||||
|
||||
internal object RequestManager : OnPermissionsResultCallback { |
||||
|
||||
private var requests: Stack<Request>? = null |
||||
private var request: Request? = null |
||||
|
||||
private val handler = Handler(Looper.getMainLooper()) |
||||
|
||||
private val requestRunnable = Runnable { |
||||
request?.start() |
||||
} |
||||
|
||||
private val isCurrentRequestInvalid: Boolean |
||||
get() = request?.let { System.currentTimeMillis() - it.requestTime > 5 * 1000L } ?: true |
||||
|
||||
init { |
||||
RequestPlugins.setOnPermissionsResultCallback(this) |
||||
} |
||||
|
||||
fun pushRequest(request: Request?) { |
||||
if (request == null) return |
||||
|
||||
if (requests == null) { |
||||
requests = Stack() |
||||
} |
||||
|
||||
requests?.let { |
||||
val index = it.indexOf(request) |
||||
if (index >= 0) { |
||||
val to = it.size - 1 |
||||
if (index != to) { |
||||
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") |
||||
Collections.swap(requests, index, to) |
||||
} |
||||
} else { |
||||
it.push(request) |
||||
} |
||||
|
||||
if (!it.empty() && isCurrentRequestInvalid) { |
||||
this.request = it.pop() |
||||
handler.post(requestRunnable) |
||||
} |
||||
} |
||||
} |
||||
|
||||
private fun startNextRequest() { |
||||
request?.clear() |
||||
request = null |
||||
|
||||
requests?.let { |
||||
request = if (it.empty()) null else it.pop() |
||||
request?.let { handler.post(requestRunnable) } |
||||
} |
||||
} |
||||
|
||||
override fun onPermissionsGranted(requestCode: Int) { |
||||
startNextRequest() |
||||
} |
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>) { |
||||
startNextRequest() |
||||
} |
||||
|
||||
} |
@ -1,20 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
internal object RequestPlugins { |
||||
|
||||
@Volatile |
||||
var sRequestCallback: OnRequestPermissionsResultCallback? = null |
||||
|
||||
@Volatile |
||||
var sResultCallback: OnPermissionsResultCallback? = null |
||||
|
||||
fun setOnRequestPermissionsCallback(callback: OnRequestPermissionsResultCallback) { |
||||
sRequestCallback = callback |
||||
} |
||||
|
||||
fun setOnPermissionsResultCallback(callback: OnPermissionsResultCallback) { |
||||
sResultCallback = callback |
||||
} |
||||
|
||||
|
||||
} |
@ -1,12 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import android.content.Context |
||||
import android.content.Intent |
||||
|
||||
interface RequestSource { |
||||
|
||||
val context: Context? |
||||
|
||||
fun startActivity(intent: Intent) |
||||
|
||||
} |
Loading…
Reference in new issue