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();
}
}
}
Related
I am implementing Access Location from user.Following is my Code. My problem is When I am clicking on Location permission it not getting the location.Bt when i am manually turn on the location from setting after that it giving me the location.My requirement is i Want compulsory check the Location permission from my App i.e. (it goes to setting and turn on location) .I gave all Permission in AndroidMeanifest file.And following is my SpashScreen.
package com.example.sbaapp;
public class SpashScreen extends AppCompatActivity {
AlertDialog.Builder alertDialog;
String[] perms = {"android.permission.ACCESS_FINE_LOCATION", "android.permission.READ_SMS"};
int permsRequestCode = 200;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spash_screen);
alertDialog = new AlertDialog.Builder(SpashScreen.this, R.style.Theme_AppCompat_DayNight_DarkActionBar);
FirebaseApp.initializeApp(getApplicationContext());
//requestPermissions(perms, permsRequestCode);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(!CheckPermissions()){
requestPermissions(perms,permsRequestCode);
}
}
}
#RequiresApi(api = Build.VERSION_CODES.M)
private boolean CheckPermissions() {
int LocationPermission=checkSelfPermission(perms[0]);
int ReadSmsPermission=checkSelfPermission(perms[1]);
Log.d("Inside Permission","");
return LocationPermission== PackageManager.PERMISSION_GRANTED && ReadSmsPermission==PackageManager.PERMISSION_GRANTED;
}
#Override
protected void onStart() {
super.onStart();
SubscribeToTopic();
if (new SessionManager(getApplicationContext()).ISLOGIN()) {
Intent intent = new Intent(SpashScreen.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
} else {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(SpashScreen.this, Activity_home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}, 60000);
}
}
private void SubscribeToTopic() {
FirebaseMessaging.getInstance().subscribeToTopic("SBASURVEY")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
String msg = "SuccessGeneralNot";
if (!task.isSuccessful()) {
msg = "Failed";
}
Log.d("TopicstatusForGeneral", msg);
}
});
}
#Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case 200:
boolean locationAccepted = false;
boolean smspermissionaccepted=false;
if(grantResults.length>=2) {
locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
smspermissionaccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
}else if(grantResults.length>=1){
if(permissions[0].equals("android.permission.ACCESS_FINE_LOCATION")){
locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
smspermissionaccepted=true;
}else {
locationAccepted=true;
smspermissionaccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
}
}
if(!(locationAccepted || smspermissionaccepted)){
new AlertDialog.Builder(SpashScreen.this).setMessage("You Need Accept Both the permissions In Order to Smooth Working Of Application Functionality")
.setPositiveButton("Ok",new SpashScreen.OkListenerForBoth())
.setNegativeButton("Cancel",null)
.create()
.show();
}else if(!locationAccepted){
new AlertDialog.Builder(SpashScreen.this).setMessage("You Need Accept This Location Based permissions In Order to Smooth Working Of Application Functionality")
.setPositiveButton("Ok",new SpashScreen.OkListenerForLocation())
.setNegativeButton("Cancel",null)
.create()
.show();
}
else if(!smspermissionaccepted){
new AlertDialog.Builder(SpashScreen.this).setMessage("You Need Accept This SMS Read permissions In Order to Smooth Working Of Application Functionality")
.setPositiveButton("Ok",new SpashScreen.OkListenerForSmS())
.setNegativeButton("Cancel",null)
.create()
.show();
}
break;
}
}
public class OkListenerForBoth implements AlertDialog.OnClickListener{
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(perms,permsRequestCode);
}
}
public class OkListenerForLocation implements AlertDialog.OnClickListener{
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{perms[0]},permsRequestCode);
}
}
public class OkListenerForSmS implements AlertDialog.OnClickListener{
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{perms[1]},permsRequestCode);
}
}
}
Use the code below it will open a location request dialog and then you will be able to get the location.
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(
getActivity(), 1000);
} catch (IntentSender.SendIntentException e) {
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
break;
}
}
});
}
Please do this way
add library in app from gradle
// Dexter runtime permissions
implementation 'com.karumi:dexter:5.0.0'
// add permissions in manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
// please call this method in your oncreate() method of splash.
requestPermission();
/**
* Requesting multiple permissions (storage and location) at once
* This uses multiple permission model from dexter
* On permanent denial opens settings dialog
*/
private void requestPermission() {
Dexter.withActivity(this)
.withPermissions(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION)
.withListener(new MultiplePermissionsListener() {
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
// check if all permissions are granted
if (report.areAllPermissionsGranted()) {
Log.e(TAG, "All permissions are granted!");
}
// check for permanent denial of any permission
if (report.isAnyPermissionPermanentlyDenied()) {
// show alert dialog navigating to Settings
showSettingsDialog();
}
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
}).
withErrorListener(new PermissionRequestErrorListener() {
#Override
public void onError(DexterError error) {
Toast.makeText(getApplicationContext(), "Error occurred! ", Toast.LENGTH_SHORT).show();
}
})
.onSameThread()
.check();
}
/**
* Showing Alert Dialog with Settings option
* Navigates user to app settings
* NOTE: Keep proper title and message depending on your app
*/
private void showSettingsDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Need Permissions");
builder.setMessage("This app needs permission to use this feature. You can grant them in app settings.");
builder.setPositiveButton("GOTO SETTINGS", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
openSettings();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
// navigating user to app settings
private void openSettings() {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 101);
}
Hope it will help
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;
}
}
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"/>
I have a location button in the ActionBar. On clicking that it will load up the given function cityLocation() .
The code executes as follows
When pressed for the first time it asks for location permission
If accepted it runs showCity() , else it pops up a Toast
If clicked again after rejecting, it executes the shouldShowRequestPermissionRationale() part (PS. I did not click Do not show again)
Anyway this was only the second time I had clicked the button and instead of asking me the location permission (with the do not show again checkbox) again, it executes the shouldShowRequestPermissionRationale() part.
I want the code to ask for location permission with the do not ask again checkbox, if the permission was rejected for the first time, and then if I reject it again (with the checkbox) and then click the actionbar item, then it should run the the MaterialDialog.Builder code.
Here's the code I'm having right now :
private void cityLocation() {
if (Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(WeatherActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(WeatherActivity.this,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
MaterialDialog dialog;
MaterialDialog.Builder builder = new MaterialDialog.Builder(this);
builder.title("Permission needed")
.content("This Action Requires the Location Setting to be enabled. Go to Settings and check the Location Permission inside the Permissions View")
.positiveText("SETTINGS")
.negativeText("CANCEL")
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(i);
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
dialog.dismiss();
}
});
dialog = builder.build();
dialog.show();
}
else
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
READ_COARSE_LOCATION);
} else {
showCity();
}
}
else {
showCity();
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == READ_COARSE_LOCATION
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showCity();
}
else {
Toast.makeText(getApplicationContext() , "Denied Location Permission" , Toast.LENGTH_SHORT).show();
}
}
Waiting for a solution.
here is the Full runtime permisssion check code:
private void cityLocation() {
if (Build.VERSION.SDK_INT >= 23) {
if (!checkIfAlreadyhavePermission()) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, READ_COARSE_LOCATION);
} else {
showCity();
}
} else {
showCity();
}
}
private boolean checkIfAlreadyhavePermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
return result == PackageManager.PERMISSION_GRANTED;
}
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case READ_COARSE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showCity();
} else {
permission_denied();
}
break;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
public void permission_denied() {
// permission was not granted
//permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
// shouldShowRequestPermissionRationale will return true
//show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
if (ActivityCompat.shouldShowRequestPermissionRationale(WeatherActivity.this,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
showDialogOK("Permission is required for register",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
showCity();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
break;
}
}
});
} //permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
Toast.makeText(getApplicationContext(), "Go to settings and enable External storage permissions", Toast.LENGTH_LONG).show();
showMaterialDialog();
}
}
public void showMaterialDialog() {
MaterialDialog dialog;
MaterialDialog.Builder builder = new MaterialDialog.Builder(this);
builder.title("Permission needed")
.content("This Action Requires the Location Setting to be enabled. Go to Settings and check the Location Permission inside the Permissions View")
.positiveText("SETTINGS")
.negativeText("CANCEL")
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(i);
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
dialog.dismiss();
}
});
dialog = builder.build();
dialog.show();
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(getActivity())
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
it will show a dialog if user denies the permission ...
if user also check never ask again it will show the material dialog ..
If user grant the permission it will perform the required function..
If you have selected the checkbox neverAskAgain in the permission Dialog, then
ActivityCompat.shouldShowRequestPermissionRationale()
method will return false. so your logic of again showing a material dialog will not work if you keep it inside the if block.
if you have to show it again, do it in the else block.