Skip to content

Commit

Permalink
Use ActivityResult API to remove the deprecated API.
Browse files Browse the repository at this point in the history
  • Loading branch information
guolindev committed Sep 22, 2021
1 parent 443ef8d commit e47cf6c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ package com.permissionx.guolindev.request
import android.Manifest
import android.os.Build
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Environment
import android.provider.Settings
import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import com.permissionx.guolindev.PermissionX
import java.util.ArrayList
Expand All @@ -45,6 +45,55 @@ class InvisibleFragment : Fragment() {
*/
private lateinit var task: ChainTask

/**
* Used to get the result for request multiple permissions.
*/
private val requestNormalPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { grantResults ->
onRequestNormalPermissionsResult(grantResults)
}

/**
* Used to get the result for ACCESS_BACKGROUND_LOCATION permission.
*/
private val requestBackgroundLocationLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
onRequestBackgroundLocationPermissionResult(granted)
}

/**
* Used to get the result for SYSTEM_ALERT_WINDOW permission.
*/
private val requestSystemAlertWindowLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
onRequestSystemAlertWindowPermissionResult()
}

/**
* Used to get the result for WRITE_SETTINGS permission.
*/
private val requestWriteSettingsLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
onRequestWriteSettingsPermissionResult()
}

/**
* Used to get the result for MANAGE_EXTERNAL_STORAGE permission.
*/
private val requestManageExternalStorageLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
onRequestManageExternalStoragePermissionResult()
}

/**
* Used to get the result for REQUEST_INSTALL_PACKAGES permission.
*/
private val requestInstallPackagesLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
onRequestInstallPackagesPermissionResult()
}

/**
* Used to get the result when user switch back from Settings.
*/
private val forwardToSettingsLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
task.requestAgain(ArrayList(pb.forwardPermissions))
}

/**
* Request permissions at once by calling [Fragment.requestPermissions],
* and handle request result in ActivityCompat.OnRequestPermissionsResultCallback.
Expand All @@ -56,7 +105,7 @@ class InvisibleFragment : Fragment() {
fun requestNow(permissionBuilder: PermissionBuilder, permissions: Set<String>, chainTask: ChainTask) {
pb = permissionBuilder
task = chainTask
requestPermissions(permissions.toTypedArray(), REQUEST_NORMAL_PERMISSIONS)
requestNormalPermissionLauncher.launch(permissions.toTypedArray())
}

/**
Expand All @@ -69,10 +118,7 @@ class InvisibleFragment : Fragment() {
fun requestAccessBackgroundLocationNow(permissionBuilder: PermissionBuilder, chainTask: ChainTask) {
pb = permissionBuilder
task = chainTask
requestPermissions(
arrayOf(RequestBackgroundLocationPermission.ACCESS_BACKGROUND_LOCATION),
REQUEST_BACKGROUND_LOCATION_PERMISSION
)
requestBackgroundLocationLauncher.launch(RequestBackgroundLocationPermission.ACCESS_BACKGROUND_LOCATION)
}

/**
Expand All @@ -85,7 +131,7 @@ class InvisibleFragment : Fragment() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(context)) {
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
intent.data = Uri.parse("package:${requireActivity().packageName}")
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION)
requestSystemAlertWindowLauncher.launch(intent)
} else {
onRequestSystemAlertWindowPermissionResult()
}
Expand All @@ -101,7 +147,7 @@ class InvisibleFragment : Fragment() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(context)) {
val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)
intent.data = Uri.parse("package:${requireActivity().packageName}")
startActivityForResult(intent, ACTION_WRITE_SETTINGS_PERMISSION)
requestWriteSettingsLauncher.launch(intent)
} else {
onRequestWriteSettingsPermissionResult()
}
Expand All @@ -116,7 +162,7 @@ class InvisibleFragment : Fragment() {
task = chainTask
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
startActivityForResult(intent, ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
requestManageExternalStorageLauncher.launch(intent)
} else {
onRequestManageExternalStoragePermissionResult()
}
Expand All @@ -132,35 +178,20 @@ class InvisibleFragment : Fragment() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
intent.data = Uri.parse("package:${requireActivity().packageName}")
startActivityForResult(intent, ACTION_MANAGE_UNKNOWN_APP_SOURCES_PERMISSION)
requestInstallPackagesLauncher.launch(intent)
} else {
onRequestInstallPackagesPermissionResult()
}
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (requestCode == REQUEST_NORMAL_PERMISSIONS) {
onRequestNormalPermissionsResult(permissions, grantResults)
} else if (requestCode == REQUEST_BACKGROUND_LOCATION_PERMISSION) {
onRequestBackgroundLocationPermissionResult()
}
}

/**
* Handle the request result when user switch back from Settings.
* Go to your app's Settings page to let user turn on the necessary permissions.
*/
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// When user switch back from settings, just request again.
if (checkForGC()) {
when (requestCode) {
FORWARD_TO_SETTINGS -> task.requestAgain(ArrayList(pb.forwardPermissions))
ACTION_MANAGE_OVERLAY_PERMISSION -> onRequestSystemAlertWindowPermissionResult()
ACTION_WRITE_SETTINGS_PERMISSION -> onRequestWriteSettingsPermissionResult()
ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION -> onRequestManageExternalStoragePermissionResult()
ACTION_MANAGE_UNKNOWN_APP_SOURCES_PERMISSION -> onRequestInstallPackagesPermissionResult()
}
}
fun forwardToSettings() {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", requireActivity().packageName, null)
intent.data = uri
forwardToSettingsLauncher.launch(intent)
}

override fun onDestroy() {
Expand All @@ -178,16 +209,15 @@ class InvisibleFragment : Fragment() {
/**
* Handle result of normal permissions request.
*/
private fun onRequestNormalPermissionsResult(permissions: Array<String>?, grantResults: IntArray?) {
if (checkForGC() && permissions != null && grantResults != null && permissions.size == grantResults.size) {
private fun onRequestNormalPermissionsResult(grantResults: Map<String, Boolean>) {
if (checkForGC()) {
// We can never holds granted permissions for safety, because user may turn some permissions off in settings.
// So every time request, must request the already granted permissions again and refresh the granted permission set.
pb.grantedPermissions.clear()
val showReasonList: MutableList<String> = ArrayList() // holds denied permissions in the request permissions.
val forwardList: MutableList<String> = ArrayList() // hold permanently denied permissions in the request permissions.
for (i in permissions.indices) {
val permission = permissions[i]
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
for ((permission, granted) in grantResults) {
if (granted) {
pb.grantedPermissions.add(permission)
// Remove granted permissions from deniedPermissions and permanentDeniedPermissions set in PermissionBuilder.
pb.deniedPermissions.remove(permission)
Expand All @@ -196,11 +226,11 @@ class InvisibleFragment : Fragment() {
// Denied permission can turn into permanent denied permissions, but permanent denied permission can not turn into denied permissions.
val shouldShowRationale = shouldShowRequestPermissionRationale(permission)
if (shouldShowRationale) {
showReasonList.add(permissions[i])
showReasonList.add(permission)
pb.deniedPermissions.add(permission)
// So there's no need to remove the current permission from permanentDeniedPermissions because it won't be there.
} else {
forwardList.add(permissions[i])
forwardList.add(permission)
pb.permanentDeniedPermissions.add(permission)
// We must remove the current permission from deniedPermissions because it is permanent denied permission now.
pb.deniedPermissions.remove(permission)
Expand Down Expand Up @@ -257,9 +287,9 @@ class InvisibleFragment : Fragment() {
/**
* Handle result of ACCESS_BACKGROUND_LOCATION permission request.
*/
private fun onRequestBackgroundLocationPermissionResult() {
private fun onRequestBackgroundLocationPermissionResult(granted: Boolean) {
if (checkForGC()) {
if (PermissionX.isGranted(context, RequestBackgroundLocationPermission.ACCESS_BACKGROUND_LOCATION)) {
if (granted) {
pb.grantedPermissions.add(RequestBackgroundLocationPermission.ACCESS_BACKGROUND_LOCATION)
// Remove granted permissions from deniedPermissions and permanentDeniedPermissions set in PermissionBuilder.
pb.deniedPermissions.remove(RequestBackgroundLocationPermission.ACCESS_BACKGROUND_LOCATION)
Expand Down Expand Up @@ -400,41 +430,4 @@ class InvisibleFragment : Fragment() {
}
return true
}

companion object {
/**
* Code for request normal permissions.
*/
const val REQUEST_NORMAL_PERMISSIONS = 1

/**
* Code for request ACCESS_BACKGROUND_LOCATION permissions. This permissions can't be requested with others over Android R.
*/
const val REQUEST_BACKGROUND_LOCATION_PERMISSION = 2

/**
* Code for forward to settings page of current app.
*/
const val FORWARD_TO_SETTINGS = 1

/**
* Code for request SYSTEM_ALERT_WINDOW permission.
*/
const val ACTION_MANAGE_OVERLAY_PERMISSION = 2

/**
* Code for request WRITE_SETTINGS permission.
*/
const val ACTION_WRITE_SETTINGS_PERMISSION = 3

/**
* Code for request MANAGE_EXTERNAL_STORAGE permission.
*/
const val ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION = 4

/**
* Code for request ACTION_MANAGE_UNKNOWN_APP_SOURCES permission.
*/
const val ACTION_MANAGE_UNKNOWN_APP_SOURCES_PERMISSION = 5
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ package com.permissionx.guolindev.request

import android.Manifest
import android.app.Dialog
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
Expand Down Expand Up @@ -502,10 +499,7 @@ class PermissionBuilder(
private fun forwardToSettings(permissions: List<String>) {
forwardPermissions.clear()
forwardPermissions.addAll(permissions)
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", activity.packageName, null)
intent.data = uri
invisibleFragment.startActivityForResult(intent, InvisibleFragment.FORWARD_TO_SETTINGS)
invisibleFragment.forwardToSettings()
}

/**
Expand Down

0 comments on commit e47cf6c

Please sign in to comment.