I have implemented runtime permission in my project mainly READ_PHONE_STATE,READ_CONTACTS,GET_ACCOUNTS. Let suppose user denies 2 out of 3 then i have to show single dialog messages about each denied permission.How do i do that
code:-
PermissionManager.with(this)
.key(2100)
.permission(PermissionEnum.READ_PHONE_STATE, PermissionEnum.READ_CONTACTS, PermissionEnum.GET_ACCOUNTS, PermissionEnum.READ_SMS, PermissionEnum.ACCESS_FINE_LOCATION, PermissionEnum.ACCESS_COARSE_LOCATION, PermissionEnum.WRITE_EXTERNAL_STORAGE, PermissionEnum.READ_EXTERNAL_STORAGE)
.askAgain(true)
.askAgainCallback(new AskAgainCallback() {
/*Callback to handle denied permission response*/
#Override
public void showRequestPermission(UserResponse response) {
showDialog(response);
}
})
.callback(new SmartCallback() {
/* To handle the result of permissions after all successful/ unsuccessful user transactions*/
#Override
public void result(boolean allPermissionsGranted, boolean somePermissionsDeniedForever) {
if (allPermissionsGranted) {
init();
} else {
finish();
}
}
})
.ask();
to show dialog:-
private void showDialog(final AskAgainCallback.UserResponse response) {
new AlertDialog.Builder(Splash.this)
.setTitle("Permission needed")
.setMessage("This app really need to use these permissions, do you want to authorize it?")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
response.result(true);
}
})
.setNegativeButton("NOT NOW", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
response.result(false);
finish();
}
})
.setCancelable(false)
.show();
}
But need to show single message in dialog for each denied permission.
String Permissions array
final String[] permisions = {Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION};
Request Permissions
ActivityCompat.requestPermissions(this, permisions, Permissions_Request_Code);
3 . #Override Method
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
InSide onRequestPermissionsResult you will get grantResults array
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) { // RequestCode for our Permissions
case Permissions_Request_Code:
if (grantResults.length != 0) { // Check Granted Results Not Null
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission Granted for Manifest.permission.ACCESS_FINE_LOCATION
// DO What You Want
} else// Permission Denied for Manifest.permission.ACCESS_FINE_LOCATION
{
// Display Error Dialog
}
if (grantResults[1] == PackageManager.PERMISSION_GRANTED) {// Permission Granted for Manifest.permission.ACCESS_COARSE_LOCATION
// DO What You Want
} else // Permission Denied for Manifest.permission.ACCESS_COARSE_LOCATION
{
// Display Error Dialog
}
}
break;
}
}
Related
I want to make an app which asks user for two permissions- READ_CALL_LOG and READ_CONTACTS. Now if the user denies READ_CALL_LOG then it should show a warning which should have a button that asks the user to grant permission again. When that button is clicked the user is asked again to grant READ_CALL_LOG permission. When the user grants READ_CALL_LOG permission he is taken to READ_CONTACTS permission. If he denies READ_CONTACTS permission then again it should show a warning which should have a button that asks the user to grant permission again. When that button is clicked the user is asked again to grant READ_CONTACTS permission. I don't want the user to be navigated to Settings if he denies. I have tried this code:
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*if(((ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CALL_LOG)== PackageManager.PERMISSION_DENIED)&&(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CONTACTS)== PackageManager.PERMISSION_DENIED))||((ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CALL_LOG)!= PackageManager.PERMISSION_GRANTED)&&(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED)))
requestPermission();*/
if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CALL_LOG)== PackageManager.PERMISSION_DENIED)
{
requestCallLogsPermission();
}
if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CONTACTS)== PackageManager.PERMISSION_DENIED)
{
requestContactPermission();
}
}
private void requestCallLogsPermission()
{
if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CALL_LOG)!= PackageManager.PERMISSION_GRANTED)
{
Dexter.withActivity(MainActivity.this).withPermission(Manifest.permission.READ_CALL_LOG).withListener(new PermissionListener()
{
#Override
public void onPermissionGranted(PermissionGrantedResponse response)
{
Toast.makeText(MainActivity.this, "Call Logs Permission is granted !", Toast.LENGTH_SHORT).show();
//if((ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CONTACTS)== PackageManager.PERMISSION_DENIED)||ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED)
requestContactPermission();
}
#Override
public void onPermissionDenied(PermissionDeniedResponse response)
{
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Permissions");
builder.setMessage("Permission is required");
builder.setCancelable(false);
builder.setPositiveButton("Understood, I am ready to give the permissions required", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which)
{
requestCallLogsPermission();
}
}).show();
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
}
private void requestContactPermission()
{
Dexter.withActivity(MainActivity.this).withPermission(Manifest.permission.READ_CONTACTS).withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse response) {
Toast.makeText(MainActivity.this, "Read Contacts Permission is granted !", Toast.LENGTH_SHORT).show();
}
#Override
public void onPermissionDenied(PermissionDeniedResponse response) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Permissions");
builder.setMessage("Permission is required");
builder.setCancelable(false);
builder.setPositiveButton("Understood, I am ready to give the permissions required", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
requestCallLogsPermission();
}
}).show();
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
}
You can try this method:
1.) Setting up permissions:
String[] permissions = {
android.Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
}; // Use the permission you need
2.) -Check and request if not already permitted:
onCreate() {
if (!checkPermissions()){
ActivityCompat.requestPermissions(this, permissions, 1);
}
}
private boolean checkPermissions() {
for (String permission: permissions){
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
3.) Check for denial status and keep asking till all permissions are granted:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
boolean allGranted = true;
for (int result: grantResults){
if (result == PackageManager.PERMISSION_DENIED){
allGranted = false;
}
}
if (!allGranted){
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) ||
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE))
{
// Here do whatever you want once the user denies
final String[] mPermissions = permissions;
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert!");
alertDialog.setMessage("Please allow the permissions!");
alertDialog.setCancelable(false);
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((MainActivity.this), mPermissions, 1);
dialog.dismiss();
}
});
alertDialog.show();
}
else {
Log.d(TAG, "PERMANENTLY DENIED");
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert!");
alertDialog.setMessage("All permissions are necessary for app to run. Goto settings and grant them.");
alertDialog.setCancelable(false);
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
dialog.dismiss();
}
});
alertDialog.show();
}
}
}
if (ContextCompat.checkSelfPermission(MainActivity1.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) + ContextCompat
.checkSelfPermission(MainActivity1.this,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale
(MainActivity1.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ||
ActivityCompat.shouldShowRequestPermissionRationale
(MainActivity1.this, Manifest.permission.READ_CONTACTS)) {
Snackbar.make(findViewById(android.R.id.content),
"Please Grant Permissions",
Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCompat.requestPermissions(MainActivity1.this,
new String[]{Manifest.permission
.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_CONTACTS},
**REQUEST_PERMISSIONS**);
}
}).show();
} else {
ActivityCompat.requestPermissions(MainActivity1.this,
new String[]{Manifest.permission
.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_CONTACTS},
**REQUEST_PERMISSIONS**);
}
} else {
//Call whatever you want
**myMethod();**
}
That is the request code you need to pass to the request permisson method,
once user grants/deny the permissions,call back method
onRequestPermissionsResult will be called with permission result.
public static final int REQUEST_PERMISSIONS = 100;//Any integer
ActivityCompat.requestPermissions(MainActivity1.this,
new String[]{Manifest.permission .WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_CONTACTS}, REQUEST_PERMISSIONS);
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0
&& grantResults[0] == PackageManager.REQUEST_PERMISSIONS) {
goToCamera(null);
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
}
REQUEST_PERMISSIONS is an integer value that specifies your request code for some permission. Write following line at the top your activity.
private static final int REQUEST_PERMISSIONS=1232;//This can be any integer value and field name can also be changed
I'm working on checking and getting permission from user with API level 23 and above. So here is a confusing thing for me, android.com says:
shouldShowRequestPermissionRationale() method returns true if the app has requested this permission previously and the user denied the request.
If the user turned down the permission request in the past and chose the Don't ask again option in the permission request system dialog, this method returns false
in other side it gives following code for checking permission and request permission if its neccessery
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
else scope in above example runs if user doesn't allow permission and check Don't Ask Again, Right? So with this code user never being asked for permission at first time run. I tested that code and the result is what I expected.
So How could I request permission for first time run and do something if user previously denied my request and do something if user deny my request and check Don't Ask Again?
You can do the following.
Ask permission every time by only checking that permission is not granted already. Don't handle the "Don't ask again" in this method. (if user checks "Don't ask again" the OS will automatically handle and will not ask for permission again and will give a call back of permission denied)
Handle the ActivityCompat.shouldShowRequestPermissionRationale() in the call back method onRequestPermissionsResult().
Here is my code in which I am asking for permission everytime
public void checkAndAskCameraPermission() {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_ID);
}
}
This is how I handles the call back
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case CAMERA_PERMISSION_REQUEST_ID: {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// Do something if permission is not granted and the user has also checked the **"Don't ask again"**
} else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
// Do something if permission not granted
}
}
}
}
first check if the permission is granted then do what you need
else if permission is denied then check weather you should request the permission you need or not through shouldShowRequestPermissionRationale.
if shouldShowRequestPermissionRationale return false then you can just show a message to the user to told them to enable the permission manually.
other then if shouldShowRequestPermissionRationale return true then request the permission and get the result of granting permission in onRequestPermissionsResult
update , this is just a simple code to show the steps:
if (checkSelfPermission == granted){
// do what you want
} else if (shouldShowRequestPermissionRationale == true) {
// you can request the permission you want from the user, then check whether permission granted or not inside onRequestPermissionsResult method
} else {
// here you know the permission is not granted , and also the user check on "Dont ask Again!" checkbox, so all you can to do is just tell the user to enable the permission manually from app permissions through Toast message or any thing else
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//initilize your views
if(iscontactsAllowed){
// do your code here
} else {
requestcontactsPermission();
}
}
private void requestcontactsPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_CONTACTS)) {
//If the user has denied the permission previously your code will come to this block
//Here you can explain why you need this permission
//Explain here why you need this permission
Log.d("scancode", "denied permission before");
}
Log.d("perm", "fourth");
//And finally ask for the permission
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS}, READ_CONTACTS_CODE /*can be any interge */);
}
private boolean iscontactsAllowed() {
//Getting the permission status
int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS);
//If permission is granted returning true
if (result == PackageManager.PERMISSION_GRANTED)
return true;
//If permission is not granted returning false
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
if(requestCode == READ_CONTACTS_CODE){
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// you have the permission call yur method here
} else {
// permission denied show user why you need it or ask again by calling reuestpermission if you need the permission
}
}
#ArtinArtin I have expanded on #salmanyahya updated simple code and provided my logic with Alert Dialog's and one Snackbar (not a big fan of Snackbar's) any way see if this helps
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
//.... write file into storage ...
System.out.println("SDK > BuildVersion TRUE");
} else {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 666); // Comment 26
System.out.println("go to requestPermissions");
}
}
onLoad();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 666: // Allowed was selected so Permission granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar s = Snackbar.make(findViewById(android.R.id.content),"Permission Granted",Snackbar.LENGTH_LONG);
View snackbarView = s.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.RED);
textView.setTextSize(18);
textView.setMaxLines(6);
s.show();
// do your work here
} else if (Build.VERSION.SDK_INT >= 23 && !shouldShowRequestPermissionRationale(permissions[0])) {
// User selected the Never Ask Again Option Change settings in app settings manually
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Change Permissions in Settings");
alertDialogBuilder
.setMessage("" +
"\nClick SETTINGS to Manually Set\n"+"Permissions to use Database Storage")
.setCancelable(false)
.setPositiveButton("SETTINGS", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 1000); // Comment 3.
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
} else {
// User selected Deny Dialog to EXIT App ==> OR <== RETRY to have a second chance to Allow Permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Second Chance");
alertDialogBuilder
.setMessage("Click RETRY to Set Permissions to Allow\n\n"+"Click EXIT to the Close App")
.setCancelable(false)
.setPositiveButton("RETRY", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Integer.parseInt(WRITE_EXTERNAL_STORAGE));
Intent i = new Intent(MainActivity.this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
})
.setNegativeButton("EXIT", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
break;
}};
This code helps to handles the run time permission Management in Android
public String storagePermissions = Manifest.permission.READ_EXTERNAL_STORAGE;
private static final int REQUEST_ACCESS =101;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(storagePermissions)== PackageManager.PERMISSION_GRANTED){
result(); // result is your block of code
}else {
requestPermissions(new String[]{storagePermissions},REQUEST_ACCESS);
}
}
else{
result(); //so if user is lower than api verison M, no permission is requested
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setTitle("Hi User..")
.setPositiveButton("Ok", okListener)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) { //idea calling showMessage funtion again
Snackbar mySnackbar = Snackbar.make( findViewById(R.id.coordinatorlayout),"You Press Cancel.. ", Snackbar.LENGTH_INDEFINITE);
mySnackbar.setAction("Exit", new cancelButton());
mySnackbar.show();
}
})
.create()
.show();
}
private void result(){
//your code
}
#RequiresApi(api = Build.VERSION_CODES.M)
public class NeverAskAgain implements View.OnClickListener{
#Override
public void onClick(View view)
{
goToSettings();
}
}
#RequiresApi(api = Build.VERSION_CODES.M)
private void goToSettings() {
Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
finish();
myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(myAppSettings, REQUEST_APP_SETTINGS);
}
public class cancelButton implements View.OnClickListener{
#Override
public void onClick(View view){
Toast.makeText(MainActivity.this,"To use this app , you must grant storage permission",Toast.LENGTH_SHORT);
finish();
}
}
#Override
#RequiresApi(api = Build.VERSION_CODES.M)
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode,permissions,grantResults);
switch(requestCode) {
case REQUEST_ACCESS:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission is granted
result();
break;
}
else if (!shouldShowRequestPermissionRationale(permissions[0])){
showMessageOKCancel("You choose Never Ask Again,option",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Snackbar mySnackbar = Snackbar.make(findViewById(R.id.coordinatorlayout), "Permission=>Storage=>On", Snackbar.LENGTH_INDEFINITE);
mySnackbar.setAction("Settings", new NeverAskAgain());
mySnackbar.show();
}
});
break;
}
else {
showMessageOKCancel("You Denid permission Request..",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{storagePermissions}, REQUEST_ACCESS);
}
});
break;
}
}
}
What I have found is that shouldShowRequestPermissionRationale only returns true if the user has denied permission (at least once) and not selected "Don't Ask Again". Meaning, it won't be displayed on the first time the permission is requested either.
I want to re ask the permission to the user in the situation if he/she deny for the first time. I have set the permission but my app runs even if I press deny option. I have a code which should do the things which I want to do but I get Cant resolve symbol Snackbar when I hit Alt+Enter it created another activity and remaining -make and -permision_available_camera gets red error.
#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.");
Snackbar.make(mLayout, R.string.permissions_not_granted,
Snackbar.LENGTH_SHORT).show();
}
#Arjun Thakun Here is a way to manage the concept of ask permission again and deal with all the ways the user can answer when the app asks about permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
//.... write file into storage ...
System.out.println("SDK > BuildVersion TRUE");
} else {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 666); // Comment 26
System.out.println("go to requestPermissions");
}
}
onLoad();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 666: // Allowed was selected so Permission granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar s = Snackbar.make(findViewById(android.R.id.content),"Permission Granted",Snackbar.LENGTH_LONG);
View snackbarView = s.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.RED);
textView.setTextSize(18);
textView.setMaxLines(6);
s.show();
// do your work here
} else if (Build.VERSION.SDK_INT >= 23 && !shouldShowRequestPermissionRationale(permissions[0])) {
// User selected the Never Ask Again Option Change settings in app settings manually
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Change Permissions in Settings");
alertDialogBuilder
.setMessage("" +
"\nClick SETTINGS to Manually Set\n"+"Permissions to use Database Storage")
.setCancelable(false)
.setPositiveButton("SETTINGS", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 1000); // Comment 3.
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
} else {
// User selected Deny Dialog to EXIT App ==> OR <== RETRY to have a second chance to Allow Permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Second Chance");
alertDialogBuilder
.setMessage("Click RETRY to Set Permissions to Allow\n\n"+"Click EXIT to the Close App")
.setCancelable(false)
.setPositiveButton("RETRY", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Integer.parseInt(WRITE_EXTERNAL_STORAGE));
Intent i = new Intent(MainActivity.this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
})
.setNegativeButton("EXIT", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
break;
}};
Try this
Basically here we are trying to read the content from the External Storage. For that, we have to ask the user for runtime permission. If the user allows it's fine, but if the user denies the permission it will display a second dialog/message box until the user accepts the permission
Asking for permission
If the user denies it will display the 'Permission Needed' dialog whenever the user launches the application
If the user presses the OK button it will ask permission again.
public class MainActivity extends AppCompatActivity {
public static int REQUEST_PERMISSION=1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
permission_fn();
}
private void requestStoragePermission()
{
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE))
{
new AlertDialog.Builder(this)
.setTitle("Permission Needed")
.setMessage("Permission is needed to access files from your device...")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},REQUEST_PERMISSION);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create().show();
}
else
{
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},REQUEST_PERMISSION);
}
}
private void permission_fn()
{
if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED)
{
if(ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE))
{
}
else
{
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},REQUEST_PERMISSION);
}
}
else {
requestStoragePermission();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Thanks for enabling the permission", Toast.LENGTH_SHORT).show();
//do something permission is allowed here....
} else {
Toast.makeText(this, "Please allow the Permission", Toast.LENGTH_SHORT).show();
}
}
}
}
Add user permission in AndroidManifest.xml file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
this is my code for get permissions...but still its stop when user perform permission action(target api is 25). any other way?
boolean isMdevice;
boolean pstatus;
int code=1;
String[] perms = { android.Manifest.permission.RECEIVE_SMS, Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS};
/////then in oncreate
isMdevice=isMarshmallowPlusDevice();
pstatus= isPermissionRequestRequired(MainActivity.this, perms, code);
////then methods
public static boolean isMarshmallowPlusDevice() {
return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1;
}
#TargetApi(Build.VERSION_CODES.M)
public static boolean isPermissionRequestRequired(Activity activity, #NonNull String[] permissions, int requestCode) {
if (isMarshmallowPlusDevice() && permissions.length > 0) {
List<String> newPermissionList = new ArrayList<>();
for (String permission : permissions) {
if (PERMISSION_GRANTED != activity.checkSelfPermission(permission)) {
newPermissionList.add(permission);
}
}
if (newPermissionList.size() > 0) {
activity.requestPermissions(newPermissionList.toArray(new String[newPermissionList.size()]), requestCode);
return true;
}
}
return false;
}
try this code for Check permission and ask for runtime permission:
Add this class to your project
public class PermissionUtils {
public static boolean checkPermission(Context context, String permission) {
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
}
public static void requestPermissions(Activity activity, String messageInCaseOfCustomDialog, int permissionId, String... permissions) {
/* if (o instanceof Fragment) {
FragmentCompat.requestPermissions((Fragment) o, permissions, permissionId);
} else */
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
permissions[0])) {
showCustomDialogForAskPermission(activity, messageInCaseOfCustomDialog, permissionId, permissions);
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else if (/*MySharedPreference.getSharedPrefrence(activity).getBoolean(permissions[0], false)*/) { //Use your Shared Preference
// No explanation needed, we can request the permission.
showCustomDialogForGoToTheSettings(activity, messageInCaseOfCustomDialog);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
} else {
ActivityCompat.requestPermissions(activity, permissions, permissionId);
}
/*MySharedPreference.getSharedPrefrence(activity).edit().putBoolean(permissions[0], true).commit();*/ //Use your Shared Preference
}
private static void showCustomDialogForGoToTheSettings(final Activity activity, String message) {
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
dialog.setTitle("Permission Required");
dialog.setMessage(message);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
activity.startActivity(intent);
}
});
dialog.show();
}
private static void showCustomDialogForAskPermission(final Activity activity, String message, final int permissionId, final String... permissions) {
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
dialog.setTitle("Permission Required");
dialog.setMessage(message);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(activity, permissions, permissionId);
}
});
dialog.show();
}
}
Now you can directly check if you have that permission or not,Suppose you want to check for READ_EXTERNAL_STORAGE permission
if (PermissionUtils.checkPermission(RegisterScreenActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
//Do your work
} else {PermissionUtils.requestPermissions(RegisterScreenActivity.this, "You need to provide storage permission for this service", 101, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE});//ask for permission
}
You can also track its result in onRequestPermissionsResult() methods like
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 101:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission granted, can do your work
} else {
//permission not granted
}
break;
}
}