parent
ca4caec216
commit
8d1199925f
@ -1,4 +1,4 @@ |
|||||||
package io.legado.app.help.permission |
package io.legado.app.constant |
||||||
|
|
||||||
@Suppress("unused") |
@Suppress("unused") |
||||||
object Permissions { |
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