I'm trying to implement Android permissions from https://developers.google.com/android/guides/permissions
A couple of ques:
1) The callback onRequestPermissionResult - where are the parameters String[] permissions and int[]grantResults from?
2) I keep getting null values for grantResults and String[] permissions
3) I have set the value of the const REQUEST_LOCATION to 0 - does it matter what the value of this const is?
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
} else {
// permission has been granted, continue as usual
Location myLocation =
LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
One unrelated ques...when getting a google map API key is it required to set the SHA-1 value or is that optional and just limits the key to android.
Thanks.
public void onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults)
Get your run time permission like this
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
// Permission already Granted
//Do your work here
//Perform operations here only which requires permission
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
}
and if permission is not already granted override onRequestPermission Results like this
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == 1) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission Granted
//Do your work here
//Perform operations here only which requires permission
}
}
}
public class RequestUserPermission {
private Activity activity;
// Storage Permissions
private static final int REQUEST_PERMISSION = 1;
private static String[] PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
public RequestUserPermission(Activity activity) {
this.activity = activity;
}
public boolean verifyStoragePermissions() {
// Check if we have write permission
int permissionWrite = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int permissionRead = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
if ((permissionWrite != PackageManager.PERMISSION_GRANTED) ||
(permissionRead != PackageManager.PERMISSION_GRANTED)) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS,
REQUEST_PERMISSION
);
return false;
}else{
return true;
}
}
public void providePermission(){
verifyStoragePermissions();
}
public void forceFullOpenPermission(){
if(!verifyStoragePermissions()){
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
activity.startActivityForResult(intent, REQUEST_PERMISSION);
}
}
In your Activity
RequestUserPermission requestUserPermission = new
RequestUserPermission(DashBoard.this);
requestUserPermission.verifyStoragePermissions();
If you want to forceful open permission
requestUserPermission.forceFullOpenPermission();
1) request code is the one you named it REQUEST_LOCATION with value of 0. permissions is the requests you have sent. for example you can request for Location permission and Read SMS permission at once so you will get them in permissions string array. and grantResults is the status of each requests for example if user accepts Location request it will be 1 and if he rejected Read SMS it will be 0
2)I think this means you have rejected the request
3)With that if you have requested multiple times from different places you can determine which result is for which request
and answer of your unrelated question: no it's optional and if you don't want other applications uses your key you have to set that
1) The callback onRequestPermissionResult - where are the parameters String[] permissions and int[]grantResults from?
permissions is the list of permissions you requested and grantResults are the results of those requests. So since you only requested one permission (ACCESS_FINE_LOCATION), you will get back ACCESS_FINE_LOCATION in permissions, and either PackageManager.PERMISSION_GRANTED or PackageManager.PERMISSION_DENIED in grantResults
2) I keep getting null values for grantResults and String[] permissions
This means that the user did not click Accept or Decline in the permission dialog. Rather, they cancelled the dialog by clicking outside of it, or leaving the application.
3) I have set the value of the const REQUEST_LOCATION to 0 - does it matter what the value of this const is?
No, this can be anything
Related
I am developing an apps where permission to write internal storage is crucial. When I am requesting permission for api >23, there is an option to never show the request permission dialog again. I wanted to disable this because if the user choose to deny and check never show the request dialog again, then the user will have to personally go to settings and clear the apps reference himself, which I want to avoid. I also want to keep requesting for permission if the user choose deny, but resulting in error java.lang.ArrayIndexOutOfBoundsException in grantResults[0].
To summarize my problem:
1. how to disable the "never show again check"
2. my error's fix
here's my code in requesting permission again if the user choose deny:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_WRITE_EXTERNAL_STORAGE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Update();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_WRITE_EXTERNAL_STORAGE);
}
break;
}
}
You can't stop the user from permanently denying the permission. When the user does an action that requires the permission, and the permission is denied, you can flash a message - a Toast or a Snackbar, for example.
try this my friend
String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
int grant = ContextCompat.checkSelfPermission(this, permission);
if (grant != PackageManager.PERMISSION_GRANTED) {
String[] permission_list = new String[1];
permission_list[0] = permission;
ActivityCompat.requestPermissions(this, permission_list, 1);
}
#Override
public void onRequestPermissionsResult ( int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults){
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(AccountClass.this, "permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(AccountClass.this, "permission not granted", Toast.LENGTH_SHORT).show();
}
}
}
I am trying to show badge on app icon when notification came from server.
I am getting this exception:
Caused by: java.lang.SecurityException: Permission Denial: opening provider com.sec.android.provider.badge.BadgeProvider from ProcessRecord{ab1124 10588:com.rehq.app/u0a175} (pid=10588, uid=10175) requires com.sec.android.provider.badge.permission.READ or com.sec.android.provider.badge.permission.WRITE
Since Android 6.0 you need to request permissions at Runtime before you need them.
The example below is for the WRITE permission (I guess you'd like to add a badge to the app icon and normally you don't need the READ permission for this - if you need it you can request it just like the WRITE permission)
First add your permissions in the Manifest:
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
Then you can check if they are granted at Runtime like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_SETTINGS) != PackageManager.PERMISSION_GRANTED) {
//permissions not granted -> request them
requestPermissions(new String[] {Manifest.permission.WRITE_SETTINGS}, YOUR_REQUEST_CODE);
} else {
//permissions are granted - do your stuff here :)
}
The result will be available in onRequestPermissionResult:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == YOUR_REQUEST_CODE) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED) {
//permissions granted -> do your stuff ;-)
}
//Permission not granted -> react to it!
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
You can read more about it in the official docs
I have an application which ask for permission from the user to start the device's bluetooth. I want to know whether if the user accepted or denied the permission.
Is there any method to do that.
You must override onRequestPermissionsResult method.
For example, here you check if user granted permision for access to his location:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//Do something here
}
}
}
}
Also, before that when you ask your permission you must determine your requestCode, which will be also sent to this method, when the user will be asked for permission. So it would be something like here:
if (ContextCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
So now, my requestCode is equal to 1(and i am checking that later in my onActivityRestult method.
Hope this helps.
I working with anroid app in Android M and need some permission that allow to access CAMERA, RECORD_AUDIO, WRITE_EXTERNAL_STORAGE, ... so I put my permission checking when user open the app in the first time. But if user deny it, how can I detect it automatically that user is using the feature that required permission then ask them again? Or I have to put my condition in every feature that need permission.
I know when we use some feature that required permission but not allowed already it will throw the exception, so do we have any class that handle this task?
I use this logic: Every Activity extends a BaseActivity, in which there is a method that check the permissions everytime the onCreate() is called.
The method that I use is:
public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
So, everytime the user launch a new Activity, the application check the permissions and display which permissions are not granted yet.
To manage the result, use onRequestPermissionsResult()
BTW, this logic will ask the user the permission even if the activity's feature doesn't require any permission.
If you want to ask the user the permissions only where the feature that requires a permission, you must check it in every activity
onRequestPermissionsResult you can check particular Permission is granted or not you can call Permission dialog again from there if particular permission not granted for Example
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA) {
// BEGIN_INCLUDE(permission_result)
// Received permission result for camera permission.
Log.i(TAG, "Received response for Camera permission request.");
// Check if the only required permission has been granted
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Camera permission has been granted, preview can be displayed
Log.i(TAG, "CAMERA permission has now been granted. Showing preview.");
Snackbar.make(mLayout, R.string.permision_available_camera,
Snackbar.LENGTH_SHORT).show();
} else {
Log.i(TAG, "CAMERA permission was NOT granted.");
// Ask again for permission
}
// END_INCLUDE(permission_result)
} else if (requestCode == REQUEST_CONTACTS) {
Log.i(TAG, "Received response for contact permissions request.");
// We have requested multiple permissions for contacts, so all of them need to be
// checked.
if (PermissionUtil.verifyPermissions(grantResults)) {
// All required permissions have been granted, display contacts fragment.
Snackbar.make(mLayout, R.string.permision_available_contacts,
Snackbar.LENGTH_SHORT)
.show();
} else {
Log.i(TAG, "Contacts permissions were NOT granted.");
// Ask again for permission
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
I am to new to Android 6.0 Coding Please Provide a solutions For the Below Code:
When i provide Run Time Permissions like READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE it shows an Exception like
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.motorola.camera/.Camera clip={text/uri-list U:file:///storage/emulated/0/Pictures/MyAppNew%20File%20Upload/IMG_20160401_110234.jpg} (has extras) } from ProcessRecord{ed96564 26955:com.social.nocializer/u0a259} (pid=26955, uid=10259) with revoked permission android.permission.CAMERA
Either MediaStore.ACTION_IMAGE_CAPTURE and MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE Run Time Permissions are not working...
Note: READ_EXTERNAL_STORAGE Works For When Opening Gallery
You have to manage run time permission for this, Because whichever permissions you have defined in AndroidManifest will not be automatically granted. So like below method you can check whether you permission is approved or not
if (checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
MY_REQUEST_CODE);
}
Here, MY_REQUEST_CODE is a static constant that you can define, which will be used again for the requestPermission dialog callback. Now, You will need a callback for the dialog result:
#Override
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == MY_REQUEST__CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Now user should be able to use camera
}
else {
// Your app will not have this permission. Turn off all functions
// that require this permission or it will force close like your
// original question
}
}
}
#Ronak Solution worked for me but with a few following changes, As we need to check on only those devices which are above Android M.
if( ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA},
5);
}
}
And override the following method using crl+o copying, pasting would might result in an error :D
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 5) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Now user should be able to use camera
}
else {
// Your app will not have this permission. Turn off all functions
// that require this permission or it will force close like your
// original question
}
}