I am building an app where I need to implement a Google Map API. In all the android versions app is working as expected but in SDK 29 or android 10 it is not working. Every time I grant location permission it again ask for the location permission, I have even manually grant the permission but still, it's not working. Here is my code:
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// 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.
new AlertDialog.Builder(this)
.setTitle("Grant Permission")
.setMessage("Location Permission Required")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Request location updates:
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
I am calling this method in onCreate in an activity.
1) In menifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
2) Inside Activity
I) Define globally inside activity
private static final int PERMISSION_CALLBACK_CONSTANT = 105;
private SharedPreferences permissionStatus;
String[] permissionsRequired = new String[]{
Manifest.permission.ACCESS_FINE_LOCATION
, Manifest.permission.ACCESS_COARSE_LOCATION
, Manifest.permission.ACCESS_BACKGROUND_LOCATION
};
II)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
permissionStatus = getSharedPreferences("permissionStatus", MODE_PRIVATE);
checkPermission();
}
III) Create a method
public void checkPermission() {
if (ActivityCompat.checkSelfPermission(BaseMapActivity.this, permissionsRequired[0]) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(BaseMapActivity.this, permissionsRequired[1]) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(BaseMapActivity.this, permissionsRequired[0]) || ActivityCompat.shouldShowRequestPermissionRationale(BaseMapActivity.this, permissionsRequired[1])) {
boolean foreground = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
boolean background = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED;
if (foreground || background) {
proceedAfterPermission();
} else {
androidx.appcompat.app.AlertDialog.Builder builder = new androidx.appcompat.app.AlertDialog.Builder(BaseMapActivity.this);
builder.setTitle("Need App Location Permission");
builder.setMessage("App name need location permission to show your current location.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
ActivityCompat.requestPermissions(BaseMapActivity.this, permissionsRequired, PERMISSION_CALLBACK_CONSTANT);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
builder.show();
}
} else if (permissionStatus.getBoolean(permissionsRequired[0], false) && permissionStatus.getBoolean(permissionsRequired[1], false)) {
boolean foreground = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
boolean background = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED;
if (foreground || background) {
proceedAfterPermission();
} else {
androidx.appcompat.app.AlertDialog.Builder builder = new androidx.appcompat.app.AlertDialog.Builder(BaseMapActivity.this);
builder.setTitle("GPS Not Enabled");
builder.setMessage("Enable GPS from your setting");
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
sentToSettings = false;
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
} else {
ActivityCompat.requestPermissions(BaseMapActivity.this, permissionsRequired, PERMISSION_CALLBACK_CONSTANT);
}
SharedPreferences.Editor editor = permissionStatus.edit();
editor.putBoolean(permissionsRequired[0], true);
editor.commit();
} else {
proceedAfterPermission();
}
}
IV)
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (requestCode == PERMISSION_CALLBACK_CONSTANT) {
boolean allgranted = false;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
allgranted = true;
} else {
allgranted = false;
break;
}
}
if (allgranted) {
proceedAfterPermission();
} else if (ActivityCompat.shouldShowRequestPermissionRationale(BaseMapActivity.this, permissionsRequired[0])
|| ActivityCompat.shouldShowRequestPermissionRationale(BaseMapActivity.this, permissionsRequired[1])
) {
boolean foreground = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
boolean background = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED;
if (foreground || background) {
proceedAfterPermission();
} else {
androidx.appcompat.app.AlertDialog.Builder builder = new AlertDialog.Builder(BaseMapActivity.this);
builder.setTitle("Need App Location Permission");
builder.setMessage("App name need location permission to show your current location");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ActivityCompat.requestPermissions(BaseMapActivity.this, permissionsRequired, PERMISSION_CALLBACK_CONSTANT);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
finish();
}
});
builder.show();
}
} else {
proceedAfterPermission();
}
}
}
V)
private void proceedAfterPermission() {
//Do your stuff after permission
}
Related
I am adding Location and ExternalWrite permissions to my application. I would like for users to be able to acquire both permissions in one application session. Currently the application must be closed and reopened for the external write permission request dialog to appear.
Code in MainActivity is as follows,
public boolean checkExternalWritePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(this)
.setTitle(R.string.title_externalwrite_permission)
.setMessage(R.string.text_externalwrite_permission)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_EXTERNAL_WRITE);
}
})
.create()
.show();
} else {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},MY_PERMISSIONS_REQUEST_EXTERNAL_WRITE);
}
return false;
} else {
return true;
}
}
...and
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
new AlertDialog.Builder(this)
.setTitle(R.string.title_location_permission)
.setMessage(R.string.text_location_permission)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
However, calling these from OnCreate,
#Override
protected void onCreate(Bundle savedInstanceState) {
...
checkLocationPermission();
checkExternalWritePermission()
}
after a fresh install (or a permissions reset) results in only the first function in OnCreate being called. The second is not called without the application being closed and restarted. Question: How can I get both permissions granted in one application session? Thanks in advance.
This works.
private boolean requestPermissions() {
int iExtStorage = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int iCoarseLocation = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION);
int iFineLocation = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (iExtStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (iFineLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
if (iCoarseLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty())
{
ActivityCompat.requestPermissions(this,listPermissionsNeeded.toArray
(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
This issue happens when I deliberately don't do anything when the permission request screen pops up, the app will just crash after a few seconds.
The permission requests pop up after transitioned from another activity (LoginActivity) to MapsActivity.
LoginActivity
if statement to check the validity
if valid
Intent intent = new Intent(LoginActivity.this,MapActivity.class);
startActivity(intent);
finish();
MapActivity
...
public void onMapReady(GoogleMap map) {
mMap = map;
getLocationPermission();
updateLocationUI();
getDeviceLocation();
}
private void getLocationPermission() {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
Just realised how to solve this with a simpled solution lmao...
In my original code, I have onRequestPermissionResult() already btw.
MapActivity
private boolean mLocationPermissionGranted;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
updateLocationUI();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
...
getLocationPermission();
if(mLocationPermissionGranted){
updateLocationUI();
getDeviceLocation();
}
}
No more crashing now :)
i am checking the permission this way and this is working properly try this :-
if (checkLocationPermission()) {
Log.e("Tag", "Camera and External storage Permission's are allowed");
} else {
requestLocationPermission();
}
this is the method checkLocationPermission:-
private boolean checkLocationPermission() {
int result = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
this is request method for location:-
private void requestLocationPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale
(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.DialogTheme);
alertDialog.setMessage("You Have To Give Permission From Your Device Setting To go in Setting Please Click on Settings Button");
alertDialog.setCancelable(false);
alertDialog.setPositiveButton("Go To Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
});
alertDialog.show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1012);
}
}
and finally onRequestPermissionsResult:-
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.DialogTheme);
alertDialog.setMessage("You Have To Give Permission From Your Device Setting To go in Setting Please Click on Settings Button");
alertDialog.setCancelable(false);
alertDialog.setPositiveButton("Go To Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
});
alertDialog.show();
}else{
// do your stuff in case accept permission
}
}
if (Build.VERSION.SDK_INT >= 23) {
if (checkPermission()) {
Log.e("permission", "Permission already granted.");
} else {
requestPermission();
}
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(SolutionBrouchereActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
viewOrDownloadPDF();
return true;
} else {
return false;
}
}
private void requestPermission() {
ActivityCompat.requestPermissions(getParent(), new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
}
This functions not worked after denying permission on the splash screen and not able to open permission prompt dialog in another activity.
You can call the shouldShowRequestPermissionRationale method in your new Activity if user did not grant the permission on Splash Screen.
Reference: https://developer.android.com/training/permissions/requesting
If your target SDK version is >=23 then you need to ask for permissions at run time. Otherwise Android will not ask for permission like old Android does.
If this is the case then you should be able to see that no permissions have been granted if you go to Settings > Apps > "Your app" > Permissions.
If you don't want to ask permissions you can reduce your target sdk version to 22 to get the old permission system. You can still compile with sdk version 23 though.
So for >=23 Use this code:
This code will automatically detect which dialog should be shown, because there is a particular limit in android to show that permission dialog. If particular number of attempts made then it will not show permission dialog, and we will have to move user to settings it self.
This code will help you to achieve both scenarios :
CustomPermissionManager.java :
public class CustomPermissionManager {
public static final int STORAGE_PERMISSION = 8;
public HashMap<Integer, ArrayList<PermissionManagerUtil.OnPermissionInterface>> onPermissionInterfaces = new HashMap<>();
public HashMap<Integer, Boolean> hasAlreadyAskedPermission = new HashMap<>();
private MainActivity context;
public void init(MainActivity context) {
this.context = context;
}
private boolean isAskedForFirstTime(String permissionName) {
if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean(permissionName, false)) {
PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(permissionName, true).commit();
return true;
}
return false;
}
public void requestStoragePermission(Activity activity, boolean showAlertForSettingsIfNeeded, PermissionManagerUtil.OnPermissionInterface onPermissionInterface) {
if (PermissionManagerUtil.instance.checkStoragePermission()) {
onPermissionInterface.onPermissionGranted();
return;
}
boolean isAskedFirstTime = isAskedForFirstTime(Manifest.permission.READ_EXTERNAL_STORAGE);
if (showAlertForSettingsIfNeeded && !isAskedFirstTime && !ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.READ_EXTERNAL_STORAGE)) {
// if user clicked on "never ask again" then popup will not show by android
//https://stackoverflow.com/questions/33224432/android-m-anyway-to-know-if-a-user-has-chosen-never-to-show-the-grant-permissi
showAlertDialogWithAppSettings(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
} else {
if (onPermissionInterfaces.get(STORAGE_PERMISSION) == null) {
onPermissionInterfaces.put(STORAGE_PERMISSION, new ArrayList<>());
}
if (onPermissionInterface != null) {
onPermissionInterfaces.get(STORAGE_PERMISSION).add(onPermissionInterface);
}
if (!hasAlreadyAskedPermission.containsKey(STORAGE_PERMISSION)) {
hasAlreadyAskedPermission.put(STORAGE_PERMISSION, true);
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION);
}
}
}
private void callPermissionManagerCallBack(int requestCode, int[] grantResults) {
if (onPermissionInterfaces.containsKey(requestCode) && onPermissionInterfaces.get(requestCode) != null) {
for (PermissionManagerUtil.OnPermissionInterface onPermissionInterface : onPermissionInterfaces.get(requestCode)) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onPermissionInterface.onPermissionGranted();
} else {
onPermissionInterface.onPermissionNotGranted();
}
}
hasAlreadyAskedPermission.remove(requestCode);
onPermissionInterfaces.get(requestCode).clear();
}
}
private void showAlertDialogWithAppSettings(String permission) {
showAlertDialogWithAppSettings(context, permission);
}
#SuppressLint("RestrictedApi")
private void showAlertDialogWithAppSettings(Activity context, String permission) {
String title = "Allow permissions";
String message = "Please allow this permission to enable this feature.";
switch (permission) {
case Manifest.permission.WRITE_EXTERNAL_STORAGE:
title = "Allow Storage Permission";
message = "Please allow permission to do.... task";
break;
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton("Go to settings", (dialog, which) -> {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", context.getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
});
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss());
builder.show();
}
public boolean checkStoragePermission() {
int resultExternalStorage = PermissionChecker.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
return resultExternalStorage == PackageManager.PERMISSION_GRANTED;
}
}
Call it like this :
CustomPermissionManager customPermissionManager = new CustomPermissionManager();
customPermissionManager.init(context);
customPermissionManager.requestCameraPermission(true, new OnPermissionInterface() {
#Override
public void onPermissionGranted() {
//permission granted
viewOrDownloadPDF();
}
#Override
public void onPermissionNotGranted() {
// permission not granted
}
});
// To check permission is given or not
boolean isGranted = customPermissionManager.checkStoragePermission();
You can add other permission too in future like here STORAGE_PERMISSION is added, by adding same type of method.
Put this function in common file and call whenever you use it will again check
public static boolean checkPermission(final Activity context)
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //||ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED
if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.READ_EXTERNAL_STORAGE)||ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)||ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.CALL_PHONE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("External storage permission is necessary");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
Check permission dialog box appears again and again inspite of giving permission and clicking all dialog box as accept it closes the app.
I have a helper method (copied from here) to check multiple permissions and see if any of them are not granted.
public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CAMERA};
if(!hasPermissions(this, PERMISSIONS)){
Log.d("permission","permission");
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
I want it to load the same activity i.e. the MainActivity after granting permission.
Can anyone point why the permission is being asked multiple times.
Kind of late to this Party but give this code a try
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
} else {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 666); // Comment 26
}
}
onAvail();
onLoad();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 666: // User selected Allowed 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();
snackbarView.setBackgroundColor(Color.WHITE);
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
// User selected the Never Ask Again Option Change settings in app settings manually
} else if (Build.VERSION.SDK_INT >= 23 && !shouldShowRequestPermissionRationale(permissions[0])) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this, R.style.MyAlertDialogStyle);
alertDialogBuilder.setTitle("Change Permissions in Settings");
alertDialogBuilder
.setMessage("Click SETTINGS to Manually Set\n\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);
}
});
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, R.style.MyAlertDialogStyle);
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) {
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;
}};
Just check that the permission you have mentioned here
String[] PERMISSIONS = {Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CAMERA};
should be given in manifest file.
Please do the following changes in the corresponding places.
if (hasPermissions(this, PERMISSIONS)) {
// you have permissions
//Do your work.
}
replace **hasPermissions()** method with following code
public static boolean hasPermissions(Context context, String... permissions) {
int result;
List<String> listPermissionsNeeded = new ArrayList<>();
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
result = ContextCompat.checkSelfPermission(context, permission);
if (result != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(permission);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), PERMISSION_ALL);
return false;
}
}
return true;
}
replace **onRequestPermissionsResult()** with following code
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
Log.d("requestCode", String.valueOf(requestCode));
switch (requestCode) {
case PERMISSION_ALL: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
//Do your work.
Toast.makeText(MainActivity.this, "Permission Recieved", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Until you grant the permission, we cannot proceed further", Toast.LENGTH_SHORT).show();
}
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
i have an old project with target sdk 21, now i have to put run time permission in that so can anyone suggest me any best and simple way to do that.
Create two variables like
private static final int REQUEST_CODE_PERMISSION = 1;
String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;
after create method like this
private void getPermission() {
if(Build.VERSION.SDK_INT>= 23) {
if (checkSelfPermission(mPermission) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{mPermission,
},
REQUEST_CODE_PERMISSION);
return;
}
else
{
/* your code if permission already access
}
}
}
After override onRequestPermissionsResult method like this
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.e("Req Code", "" + requestCode);
if (requestCode == REQUEST_CODE_PERMISSION) {
if (grantResults.length == 1 &&
grantResults[0] == MockPackageManager.PERMISSION_GRANTED ) {
methodRedirect();
}
else{
this.getPermission();
}
}
}
In this way even user deny permission, it will show again.
You can manage multiple permission like this.
You can handle permission on Splash Screen or First Screen.
if multiple permission then handle all one time.
if user denied any permission then it show message some permission required.
hope it will help you.
Here is example how to handle multiple permission.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
if(checkAndRequestPermissions()){
//all permission granted
}else{
//require all permission.
}
}
private boolean checkAndRequestPermissions() {
int camerapermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
int phonestate = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
int location = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
int recordaudio = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
int permissionLocation = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
List<String> listPermissionsNeeded = new ArrayList<>();
if (camerapermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CAMERA);
}
if (phonestate != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
}
if (location != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (recordaudio != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.RECORD_AUDIO);
}
if (permissionLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<>();
perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_PHONE_STATE, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.RECORD_AUDIO, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
// Fill with actual results from user
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for both permissions
if (perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
) {
Log.d(TAG, "camera & location services permission granted");
// here you can do your logic all Permission Success Call
moveToNxtScreen();
} else {
Log.d(TAG, "Some permissions are not granted ask again ");
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showDialogOK("Some Permissions are required for Open Camera",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
dialog.dismiss();
break;
}
}
});
} else {
explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
}
}
}
}
}
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
private void explain(String msg) {
final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
dialog.setMessage(msg)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Utils.startInstalledAppDetailsActivity(LoginActivity.this);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
dialog.create().dismiss();
finish();
}
});
dialog.show();
}