As stated in Android - Requesting Permissions
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app... The user can revoke the permissions at any time...
It's also stated that:
System permissions are divided into two categories, normal and dangerous:
Normal permissions do not directly risk the user's privacy. If your app lists a normal permission in its manifest, the system grants the permission automatically
Dangerous permissions can give the app access to the user's
confidential data. If you list
a dangerous permission, the user has to explicitly give approval to
your app
Here are full lists of Dangerous Permissions and Normal Permissions
All that basically means that you need to manually request for any dangerous permission, when it's actually needed.
Since it potentially might be needed multiple times in your code, you can create a reusable method that checks whether specific permission is granted already and if it's not - to request it from user.
Here an example:
Java
public class PermissionManager {
//A method that can be called from any Activity, to check for specific permission
public static void check(Activity activity, String permission, int requestCode){
//If requested permission isn't Granted yet
if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
//Request permission from user
ActivityCompat.requestPermissions(activity,new String[]{permission},requestCode);
}
}
}
Kotlin
object PermissionManager {
//A method that can be called from any Activity, to check for specific permission
fun check(activity: Activity, permission: String, requestCode: Int) {
//If requested permission isn't Granted yet
if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
//Request permission from user
ActivityCompat.requestPermissions(activity, arrayOf(permission), requestCode)
}
}
}
Usage:
Java
//Inside your activity:
//1. Define static constant for each permission request
public static final int REQUEST_CODE_FOR_SMS=1;
//2. When needed (for example inside .onStart event) use method PermissionManager.check for requested permission
@Override
protected void onStart() {
super.onStart();
PermissionManager.check(this, Manifest.permission.RECEIVE_SMS, REQUEST_CODE_FOR_SMS);
}
//3. Handle User's response for your permission request
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode==REQUEST_CODE_FOR_SMS){//response for SMS permission request
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
//What to do if User allowed SMS permission
}else{
//What to do if user disallowed requested SMS permission
}
}
}
Kotlin
//Inside your activity:
//1. Define static constant for each permission request
val REQUEST_CODE_FOR_SMS = 1
//2. When needed (for example inside .onStart event) use method PermissionManager.check for requested permission
override fun onStart() {
super.onStart()
PermissionManager.check(this, Manifest.permission.RECEIVE_SMS, REQUEST_CODE_FOR_SMS)
}
//3. Handle User's response for your permission request
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (requestCode == REQUEST_CODE_FOR_SMS) {//response for SMS permission request
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//What to do if User allowed SMS permission
} else {
//What to do if user disallowed requested SMS permission
}
}
}
Note:
If you need to use PermissionManager.check
inside Fragment
instance, use: getActivity()
as its first parameter.
You can use checkSelfPermission
inside Service
instance, to check if some permission is granted already, but not requestPermissions
to request it. Because checkSelfPermission
can be used for any Context
, but requestPermissions
only for Activity