My application asks for permission when I first installed the app, however if I deny the permission and open my app again, it doesn't ask for permission and gets stuck at the
if (ActivityCompat.shouldShowRequestPermissionRationale(Script_list.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE))
I dont quite understand what does this actually do as the android's documentation says it's supposed to tell users why the permission is requested
Am I supposed to do ActivityCompat.requestPermissions in it too?
if (ContextCompat.checkSelfPermission(Script_list.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(Script_list.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(Script_list.this, "PERMISSION NOT DETECTED", Toast.LENGTH_SHORT).show();
} else {
ActivityCompat.requestPermissions(Script_list.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
}
}
else
{
Toast.makeText(Script_list.this, "USER ALREADY ALLOWED", Toast.LENGTH_SHORT).show();
setListView();
}
Related
In my Android app using Java, I define a checkForPermission() method to check the grant status of a single permission. If the permission has not already been granted, it requests this permission from the user using ActivityCompat.requestPermissions().
Here is the method:
private boolean checkForPermission(String permission, int rationaleMessageId, int requestCode) {
// Check if permission is already granted.
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
// Permission has not been granted. Check if a rationale AlertDialog should be shown.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
// Show rationale AlertDialog explaining why this permission is needed.
new AlertDialog.Builder(this)
.setTitle(R.string.rationale_dialog_title)
.setMessage(rationaleMessageId)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// Request permission again.
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
}
})
.create()
.show();
}
// Do not show rationale AlertDialog. Just request permission again.
else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
}
return false;
}
return true;
}
I've noticed that the method works perfectly fine for simple permissions such as android.permission.WRITE_EXTERNAL_STORAGE, but does not work for more dangerous permissions such as android.permission.WRITE_SETTINGS.
I'm wondering which types of permissions ActivityCompat.requestPermissions() may actually request. My assumption is that dangerous permissions must be requested using other means, but I would like any feedback I can get on this. Thank you.
Specifically, requestPermissions() is used for permissions with a protectionLevel of dangerous.
WRITE_EXTERNAL_STORAGE is dangerous. WRITE_SETTINGS is not.
So i'm trying to request both Location and Camera permissions from the user, and my app all works apart from the part where it has to request Location permissions from the user. The user never gets a request to access location. Is it even possible to request 2 different permissions and have onRequestPermissionsResults to handle them both in the same class?
#Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
HomePageActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_LOCATION_PERMISSION
);
} else {
getCurrentLocation();
}
askCameraPermissions();
}
this is how it starts, then I think it goes here
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE_LOCATION_PERMISSION:
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getCurrentLocation();
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_LONG).show();
}
}
break;
case CAMERA_PERM_CODE:
//if both are true then user has granted requests
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dispatchTakePictureIntent();
} else {
Toast.makeText(this, "Camera permission is required to Use camera.", Toast.LENGTH_SHORT).show();
}
break;
}
}
'''
except I believe this is where the application is doing something wrong. The camera request and permission works perfectly and I am able to continue and have my camera methods work. However when it comes to Location permissions, as i said, the user is never prompted to allow permissions, so I think something is going wrong here. Any help is appreciated, this is my first post so maybe formatting will be strewn with errors.
I have tried to post only relevant code. I will post more if requested
Rather then asking permission two times which is causing the problem you can actually ask it in a single time like
....
ActivityCompat.requestPermissions(
HomePageActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CAMERA},
REQUEST_CODE_MULTIPLE_PERMISSION
);
....
if you still want to ask separate permission then you should ask after the first one result has arrived.
EDIT
while asking for access fine location you should also ask for coarse location
I'm trying to test the Runtime Permissions specifically for Android sdk > 23. But my app is being granted permissions automatically without asking.
Note : I'm using sdk version 24. Here's a snippet of code I'm using:
public void onCalendarClick(View view) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) == PackageManager
.PERMISSION_DENIED) {
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.WRITE_CALENDAR)) {
//Display Explanation to the user
//For granting permissions to the app.
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CALENDAR}, CALLBACK_CALENDAR);
}
}
}
#Override
public void onRequestPermissionsResult(int resultCode, String permission[], int grantResults[]) {
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast toast;
switch (resultCode) {
case CALLBACK_CALENDAR : toast = Toast.makeText(this,"Calendar Permission Granted!!",Toast.LENGTH_LONG);
toast.show(); break;
//Other Cases
}
}
}
When I click on Calendar Button, the onCalendarClick() method run, but without asking for any permission, the App directly displays Calendar Permission Granted!! toast. In the App's settings, there are though No Permissions Granted/Requested being displayed.
Am I missing something or doing it the wrong way? Thanks for any help.
So here it is. I found out that for android sdk > 22, though Runtime permissions are added programatically for your application but you still need to declare your app's permission in the AndroidManifest.xml file. So, after adding the code:
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
in the AndroidManifest.xml, the app asks for the permission and it's finally working.
For more information : Android M permission dialog not showing
.Thanks to all for helping me out )
You are missing the order of the code. Check this:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case CALLBACK_CALENDAR: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// calendar-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
There is a little difference, you are asking if the permission is granted even before you know you are talking about CALENDAR permissions. So, you should first check if the current permission response is the one you want, and then check if the permission is granted.
Source: https://developer.android.com/training/permissions/requesting.html
I'm trying to request the ability to read contacts in an app, and have followed several tutorials. All of these use nearly the same code for this process. Below is the code in my MainActivity.java file, that should request permission.
private void checkContactPermissions()
{
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Contacts permission NOT granted");
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
}
else
{
Log.i(TAG, "Contacts permission granted");
readContacts();
}
}
My manifest.xml also includes the line:
<uses-permission android:name="android.permission.READ_CONTACTS" />
When the app is run, either on emulator or physical debugging device, it does not ask for permission, however the log states that the permission was granted. I have confirmed the permission is off by going to the settings and checking it was turned off. What else would be causing the app to perform as if permissions were granted.
Try this,
private Context mContext=YourActivity.this;
private static final int REQUEST = 112;
if (Build.VERSION.SDK_INT >= 23) {
String[] PERMISSIONS = {android.Manifest.permission.READ_CONTACTS};
if (!hasPermissions(mContext, PERMISSIONS)) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, REQUEST );
} else {
readContacts();
}
} else {
readContacts();
}
get Permissions Result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
readContacts();
} else {
Toast.makeText(mContext, "The app was not allowed to read your contact", Toast.LENGTH_LONG).show();
}
}
}
}
check permissions for marshmallow
private static boolean hasPermissions(Context context, String... permissions) {
if (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;
}
Manifest
<uses-permission android:name="android.permission.READ_CONTACTS" />
I use RxPermission for permissions to make my code ultimately short.
First add these permissions (or one you need) in your manifest.xml.
<uses-permission android:name="android.permission.READ_CONTACTS" />
Then ask run time permission from user in your activity.
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
.request(Manifest.permission.READ_CONTACTS) // ask single or multiple permission once
.subscribe(granted -> {
if (granted) {
// All requested permissions are granted
} else {
// At least one permission is denied
}
});
add this library in your build.gradle
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}
Isn't this easy?
As Divyesh Patel pointed out, I had the boolean statemetns mixed up, it should be
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED)
Rather than
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED)
Important thing for you to note here that these permissions are asked only for devices with version>23 and if you have lower version of android then for only some models like redmi you have to invoke the permissions manually .
Otherwise version<23 generally do not ask for permissions.
If you put in manifest. It will automatically take it, specially when you are installing app over usb.
If any device has OS version below <23 or In app manifist file maxtarget version is below <23 then it will not ask permission in runtime because while the app installing on these devices you actually giving permission to all you mentioned.
So the runtime permissions are possible only in the case of device has OS version above 22(Lolipop).
Hope this helpful..
#Rajesh
Android 6
I wrote the next code that checks for permissions and if there are no such permissions, it asks a user to give them.
private void checkDiskPermission ()
{
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "no disk access" , Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
else
{
Toast.makeText(this, "disk access - OK" , Toast.LENGTH_LONG).show();
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "no GPS access" , Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
}
else
{
Toast.makeText(this, "GPS access - OK" , Toast.LENGTH_LONG).show();
}
}
This code works fine for GPS permissions, but not for WRITE_EXTERNAL_STORAGE permissions. A dialog appears in only one case.
Why can it be so?
Thanks!
Because you are requesting it for 2 times simultaneously.
That's why it is taking last request.
The solution is that you have to ask both permission in one request
Like this-
private void checkDiskPermission ()
{
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "No Permissions" , Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
}
else
{
Toast.makeText(this, "Has Permissions" , Toast.LENGTH_LONG).show();
}
}
If permission > 1, than it has to combined together at Runtime.
According to Google, beginning with Android 6.0 (API level 23), users can revoke permissions from any app at any time, even if the app targets a lower API level. You should test your app to verify that it behaves properly when it’s missing a needed permission, regardless of what API level your app targets.
Things to keep in mind while asking Multiple Permission:
Number of Permission.
Never Ask Again Checkox
Look at the Source for Multiple Permission Request
your code is working fine. No issue in java code for run time permission. Once check your manifest have you add that line or not?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>