Android Runtime Permissions- How to Implement

Android runtime permissions- how to implement

What is "MY_PERMISSIONS_REQUEST_READ_CONTACTS" in this example?

It is an int, to tie a particular requestPermissions() call to the corresponding onRequestPermissionsResult() callback.

Under the covers, requestPermissions() uses startActivityForResult(); this int serves the same role as it does in startActivityForResult().

does that mean I should make a Constants.java and declare a public static int?

I would just make it a private static final int in the activity. But, you can declare it wherever you want.

What should the value be?

I seem to recall that it needs to be below 0x8000000, but otherwise it can be whatever you want. The value that you use for each requestPermissions() call in an activity should get a distinct int, but the actual numbers do not matter.

If your activity has only one requestPermissions() call, then the int value really does not matter. But many apps will have several requestPermissions() calls in an activity. In that case, the developer may need to know, in onRequestPermissionsResult(), what request this is the result for.

Requesting app runtime permissions (Android)

You have mentioned that app is solely for your use then you don't have to write the code for the runtime permission you can skip it...

How to do this... ?

Step 1 : Just put all the permission you need inside the app manifest file and install the app

Step 2 : Go to the app settings or app info in the phone and check for app permissions all the permission that you mentioned will be displayed there just toogle them manually

That's it now write code to access the things which you supposed to write after getting permission

Android Marshmallow: How to allow Runtime Permissions programatically?

For Marshmallow or later permissions are not granted at install time and must be requested when required at runtime (if not granted previously.)

To do this, you need to run ActivityCompat.requestPermissions() to pop up the systems permissions dialog in your Activity, at the time when the user is undertaking an action that requires additional system permissions.

An example of this for the WRITE_EXTERNAL_STORAGE permission would be:

ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_EXTERNAL_STORAGE_REQUEST_CODE
);

Note: WRITE_EXTERNAL_STORAGE_REQUEST_CODE is an arbitrary integer constant you should define elsewhere.

The permissions you request should also be declared in your AndroidManifest.xml. In this example the declaration would be:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

In order to handle the system permissions dialog response you will also need to implement onRequestPermissionsResult() in your Activity. For this example the code would be similar to

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
if (grantResults.length == 0 || grantResults[0] == PackageManager.PERMISSION_DENIED) {
return; //permission not granted, could also optionally log an error
}
if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) {
//Do whatever you needed the write permissions for
}
}

If you are automating your app through Espresso, UIAutomator and/or some other UI testing framework you will need to anticipate and click the system dialog during your test, which can be accomplished with the following test code:

private void allowPermissionsIfNeeded()  {
if (Build.VERSION.SDK_INT >= 23) {
UiObject allowPermissions = mDevice.findObject(new UiSelector().text("Allow"));
if (allowPermissions.exists()) {
try {
allowPermissions.click();
} catch (UiObjectNotFoundException e) {
Timber.e(e, "There is no permissions dialog to interact with ");
}
}
}
}

A more comprehensive explanation of testing System UI Permissions is available here.

How do I implelment Android 6.0 Runtime Permissions On Existing App

The runtime permission model for Android 6.0 is mainly divided into part

1. Checking Permission

2. Requesting Permission

you can create two method for this thing in your activity, As follow

Check Permission

private boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS);
if (result == PackageManager.PERMISSION_GRANTED){

return true;

} else {

return false;

}
}

Request Permission

private void requestPermission(){

if (ActivityCompat.shouldShowRequestPermissionRationale(activity,Manifest.permission.READ_SMS)){

Toast.makeText(context,"Read Sms Allowed.",Toast.LENGTH_LONG).show();

} else {

ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.READ_SMS},PERMISSION_REQUEST_CODE);
}
}

Last but not least you need to override the onRequestPermissionsResult method

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

Snackbar.make(view,"Permission Granted, Now you can access SMS.",Snackbar.LENGTH_LONG).show();

} else {

Snackbar.make(view,"Permission Denied, You cannot access SMS.",Snackbar.LENGTH_LONG).show();

}
break;
}
}

as you asked do i need to run this in thread .. answer is No Just do this in main thread

Runtime Permissions Not Working on Real Device

ActivityCompat.requestPermission dont execute and subsequently
onRequestPermissionRationale never gets called but in the device
settings for the app, it is always showing as permission granted

Since your app is old app and you have already granted the necessary permissions to the app, ActivityCompat.checkSelfPermission will return PackageManager.PERMISSION_GRANTED and you won't see the permission request again.

If you want to see the permission request, un-install the older app and install a new one. Another way is to just disable the permissions from the settings.

Asking for permissions at run-time, Android M+

final private int REQUEST_CODE_ASK_PERMISSIONS = 123;

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

private void requestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat
.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_ASK_PERMISSIONS);
}
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT)
.show();
} else {
// Permission Denied
Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

Android 11 Runtime Permissions

My issue was fixed by the system reset, but according to comments and documents please follow the below guidelines for the location permission.

Thanks Pawel for comments,

Ref: https://stackoverflow.com/a/66321942/9909365

Background location permission does not work like other permissions. It's a request to elevate location permission from foreground-only to foreground & background.

User has to consciously select "Allow all the time" in order to do that and grant background location permission. Otherwise that permission is considered denied.

You cannot even request background location unless foreground location is already granted - when system permission activity shows up it should already have option 2 or 3 selected.

See https://developer.android.com/training/location/permissions#request-background-location

Note:

When your app is using this background location please be prepared with a short video that demonstrates the location-based feature in your app that requires access to location in the background (while the app is not in use).

See https://support.google.com/googleplay/android-developer/answer/9799150

How to ask runtime permissions for Camera in Android , Runtime storage permissions

Below I have written a code for granting a runtime permissions for Camera, There is an Array of String in which you can give multiple requests granting as which is needed at runtime.

public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 200;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkPermission()) {
//main logic or main code

// . write your main code to execute, It will execute if the permission is already given.

} else {
requestPermission();
}
}

private boolean checkPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
return false;
}
return true;
}

private void requestPermission() {

ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
PERMISSION_REQUEST_CODE);
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Permission Granted", Toast.LENGTH_SHORT).show();

// main logic
} else {
Toast.makeText(getApplicationContext(), "Permission Denied", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
showMessageOKCancel("You need to allow access permissions",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermission();
}
}
});
}
}
}
break;
}
}

private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
}

Runtime Permission - Requesting permission for already granted permission

Since the code was written using Array, its requesting permission for all the values in the array even if it is already granted. So I have rewritten the code to use ArrayList instead of Array. Now its working perfectly as expected.

private  boolean requestPermissionMethod() {
int permissionContacts = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (locationPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionContacts != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CONTACTS);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}


Related Topics



Leave a reply



Submit