I am trying to save some arrays in an application to use them in other platform (C++) are serialized. I use a pick method to let the user choose the file name and directory, but first I am trying to define the root directory like this, since the handling of the Create Document needs Android 10 to start in the proper defined directory:
'''
String a = getExternalStorageDirectory().getPath();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try {
String public_dir = "sistemaderiegoandroid_arduino" + MyDocuments.fileSeparator;
file = new File(a, public_dir);
file.setWritable(true);
if (!file.mkdirs()) {
file.mkdir();
}
;
DocumentsContract.createDocument(context.getContentResolver(), DocumentsContract.buildRootUri(MyDocuments.AUTORITY,MyDocuments.ROOT), DocumentsContract.Document.MIME_TYPE_DIR,MyDocuments.INITIALURI);
fileUri = DocumentsContract.buildDocumentUri(MyDocuments.AUTORITY,MyDocuments.INITIALURI);
} catch (Exception e) {
errorMsg(MyDocuments.falloCrear + e.toString());
}
}else{
file = new File(a);
file.setWritable(true);
};
String StfileR = "arduino_data_resumen.bin";
String StfileT = "arduino_data_tiempo.bin";
String StfileH = "arduino_data_humedad.bin";
String StfileL = "arduino_data_luz.bin";
try{
createFile(fileUri, StfileT, CREATE_FILE_T);
createFile(fileUri, StfileL, CREATE_FILE_L);
createFile(fileUri, StfileH, CREATE_FILE_H);
createFile(fileUri, StfileR, CREATE_FILE_R);
} catch (Exception e) {
errorMsg(MyDocuments.falloCrear + e.toString());
}
try {
allData.saveData(context);
} catch (Exception e) {
errorMsg(MyDocuments.falloGrabar + e.toString());
}
private void createFile(Uri pickerInitialUri, String file_name, int result_option_Flag) {
//DocumentsUI
Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
intent.setType(MyDocuments.MINETYPE);
intent.putExtra(Intent.EXTRA_TITLE, file_name);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, RESULT_OK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, RESULT_OK);
}
// intent.putExtra(DocumentsContract.EXTRA_EXCLUDE_SELF,true);
startActivityForResult(intent, result_option_Flag);
};
'''
The permission in the manifest are:
'''
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission-sdk-23 android:name="android.permission.READ_EXTERNAL_STORAGE"/>
'''
and the provider is:
'''
<provider
android:name="com.sistemaderiegoandroid_arduino.MyDocuments"
android:authorities="com.sistemaderiegoandroid_arduino.documents"
android:grantUriPermissions="true"
android:exported="true"
android:permission="android.permission.MANAGE_DOCUMENTS">
<intent-filter>
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
</intent-filter>
</provider>
'''
To save the data in the file I use a FileDescriptor with the method getContentResolver().openFileDescriptor MODE_APPEND, this gives a ParcelFileDescriptor and with the method getFileDescriptor() I make the FileOuputStream like this:
'''
FileDescriptor fdR = null;
parcelFileDescriptorL = getContentResolver().openFileDescriptor(fileNameL, "MODE_APPEND", null);
fdL = parcelFileDescriptorL.getFileDescriptor();
arduinoDataL = new FileOutputStream(fdL);
serializatorDataL = new ObjectOutputStream(arduinoDataL);
for (int i = 0; i < allData.arrayDatosLuz.length; i++) {
serializatorDataL.writeObject(allData.arrayDatosLuz[i]);
serializatorDataL.flush();
fdL.sync();
}
;
serializatorDataL.close();
'''
The complete package is here:
https://github.com/DarioLobos/sistemariego
I added this grant permission request but anyway the phone don't ask for the permissions. I reset, in the applications manager of the phone the caches of restriction and permits, anyway don't ask for grant them when I install the program. Other application don't have problems while are installing and the phone request grant permissions.
'''
int granted = PackageManager.PERMISSION_GRANTED;
grantRequested =
ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) != granted;
if ((grantRequested)) {
if ((ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) != PackageManager.PERMISSION_GRANTED)) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle(grantDialog).setMessage(R.string.requestWriteSetting);
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (callBackFlag == 0) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
startActivity(intent);
callBackFlag++;
int granted = PackageManager.PERMISSION_GRANTED;
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == granted) {
grantRequested =
ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) != granted;
if (grantRequested) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN}, RESULT_OK);
} else {
if (grantRequested) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle(exit).setMessage(R.string.permitNotGranted);
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainActivity.this.finish();
System.exit(0);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
}
} else {
dialog.dismiss();
alertDialogBuilder.setTitle(exit).setMessage(R.string.permitNotGranted);
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainActivity.this.finish();
System.exit(0);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
});
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
boolean grantChecker = false;
if (grantResults.length > 0) {
grantChecker = true;
for (int i = 0; grantResults.length > i; i++) {
boolean a = grantResults[i] == PackageManager.PERMISSION_GRANTED;
grantChecker = grantChecker & a;
}
}
if (requestCode != RESULT_OK) {
int granted = PackageManager.PERMISSION_GRANTED;
if (!grantChecker & (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == granted)) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
ResumenFragment.errorMsg(permitHandling);
ActivityCompat.requestPermissions(this,
new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN}, RESULT_OK);
} else {
grantRequested =
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) != granted;
if (grantRequested) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle(exit).setMessage(R.string.permitNotGranted);
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainActivity.this.finish();
System.exit(0);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
;
}
}
}
'''
The Intents for result for OPENDOCUMENT and CREATEDOCUMENT give the information about the picked file in the overrided method onActivityResult. There using intent.getData() if obtained the URI for the file, then using contentResolver.openFileDescriptor can be open and with the method getFileDescriptor() do a FileOutputStream or FileInputStream sync. Like This:
'''
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
if (resultCode == Activity.RESULT_OK) {
// The result data contains a URI for the document or directory that
// the user selected.
if (resultData != null) {
Uri uriData = resultData.getData();
// String fileId =DocumentsContract.getDocumentId(uriData);
if (requestCode == CREATE_FILE_L) {
Data.fileNameL = uriData;
}
if (requestCode == CREATE_FILE_H) {
Data.fileNameH = uriData;
}
if (requestCode == CREATE_FILE_R) {
Data.fileNameR = uriData;
}
if (requestCode == CREATE_FILE_T) {
Data.fileNameR = uriData;
}
if (requestCode == PICK_FILE_T) {
Data.fileNameT = uriData;
}
if (requestCode == PICK_FILE_L) {
Data.fileNameL = uriData;
}
if (requestCode == PICK_FILE_H) {
Data.fileNameH = uriData;
}
if (requestCode == PICK_FILE_R) {
Data.fileNameR = uriData;
'''
I NEED TO KNOW THE PROPER WAY TO DEFINE THE ROOT DIRECTORY AND THE DIRECTORY DOWNLOAD AND THE THE PICK UP NAME AND DIRECTORY COLLECTED FROM THE INTENT RESULT. I did plenty trials without solution any help is welcome.
Related
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;
}
}
In Android the Camera action show a error:
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=android/com.android.internal.app.ResolverActivity } from ProcessRecord{beb99ec 32121:com.android.hawee/u0a369} (pid=32121, uid=10369) with revoked permission android.permission.CAMERA
at android.os.Parcel.readException(Parcel.java:1620)
I request permission on manifest as follows
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And on chooserDialog on click of camera
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
} else {
Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
activity.startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
}
On activity
#SuppressLint("NewApi")
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.frameContainer);
fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
And on Fragment
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (requestCode == Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
} else {
new CommonDialogOK(getActivity(), getString(R.string.Sorry), getString(R.string.Permissions_Not_Granted));
}
} else if (requestCode == Constants.PICK_IMAGE_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent gallery = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(gallery, Constants.IMAGE_CAPTURE_GALLERY);
} else {
new CommonDialogOK(getActivity(), getString(R.string.Sorry), getString(R.string.Permissions_Not_Granted));
}
}
}
But on click from ChooserDialog always get above error.
How can i ask permission for write to external and Image capture at same time.
If camera n external storage both are required for your app you should || them in if condition.
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
} else {
Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
activity.startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
}
Try this :-
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
in onCreate()
private void checkAndroidVersion() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkAndRequestPermissions();
}
}
This method
private boolean checkAndRequestPermissions() {
int camera = ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.CAMERA);
int wtite = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
int read = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
List<String> listPermissionsNeeded = new ArrayList<>();
if (wtite != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (camera != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CAMERA);
}
if (read != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(getActivity(), listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
then use this
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
Log.d("in fragment on request", "Permission callback called-------");
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<>();
// Initialize the map with both permissions
perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_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.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.d("in fragment on request", "CAMERA & WRITE_EXTERNAL_STORAGE READ_EXTERNAL_STORAGE permission granted");
// process the normal flow
//else any one or both the permissions are not granted
} else {
Log.d("in fragment on request", "Some permissions are not granted ask again ");
//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(getActivity(), Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)) {
showDialogOK("Camera and Storage Permission required for this app",
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.
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
Toast.makeText(getActivity(), "Go to settings and enable permissions", Toast.LENGTH_LONG)
.show();
// //proceed with logic by disabling the related features or quit the app.
}
}
}
}
}
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(getActivity())
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
And Finally on button click when u save profile or so
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!checkAndRequestPermissions()) {
}
else {
// do your stuff here
}
} else {
// do your stuff here
}
Try this code:
For Checking permission I created a separate class as below:
public class MarshMallowPermission {
public static final int RECORD_PERMISSION_REQUEST_CODE = 1;
public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2;
public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;
Activity activity;
public MarshMallowPermission(Activity activity) {
this.activity = activity;
}
public boolean checkPermissionForRecord(){
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public boolean checkPermissionForExternalStorage(){
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public boolean checkPermissionForCamera(){
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public void requestPermissionForRecord(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.RECORD_AUDIO)){
Toast.makeText(activity, "Microphone permission needed for recording. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.RECORD_AUDIO},RECORD_PERMISSION_REQUEST_CODE);
}
}
public void requestPermissionForExternalStorage(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(activity, "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
}
}
public void requestPermissionForCamera(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){
Toast.makeText(activity, "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE);
}
}
}
Then
MarshMallowPermission marshMallowPermission = new
MarshMallowPermission(this);
public void getPhotoFromCamera() {
if (!marshMallowPermission.checkPermissionForCamera()) {
marshMallowPermission.requestPermissionForCamera();
} else {
if (!marshMallowPermission.checkPermissionForExternalStorage()) {
marshMallowPermission.requestPermissionForExternalStorage();
} else {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File mediaStorageDir = new File(
Environment.getExternalStorageDirectory()
+ File.separator
+ getString(R.string.directory_name_corp_chat)
+ File.separator
+ getString(R.string.directory_name_images)
);
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
try {
mediaFile = File.createTempFile(
"IMG_" + timeStamp, /* prefix */
".jpg", /* suffix */
mediaStorageDir /* directory */
);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
startActivityForResult(takePictureIntent, PICK_FROM_CAMERA);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The answer needs more upvotes and should be the official answer about permissions with camera, the other answers don't solved the problem on Android 10.
And how we know, the answers/codes that work on new versions works on olders.
Help us to index this answer:
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
} else {
Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
activity.startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
}
I have tried everything I could find by researching. Nothing is working. I have an Activity with a FragmentDialog. In this dialog, I have an image view with a button. When this button is pressed, an alert pops up to take pic, choose pic from gallery or cancel. Both the cancel and the gallery buttons work great, but when I try to take a photo, I get the error message in the title:
FATAL EXCEPTION: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.lge.camera/.app.CameraActivity } from ProcessRecord{c6d8bdf 7649:com.devhopes.ryde/u0a152} (pid=7649, uid=10152) with revoked permission android.permission.CAMERA
Below is my DialogFragment and Manifest Code:
UsernameDialogFragment
public static class UsernameDialogFragment extends DialogFragment {
Context applicationContext = bDriverRegistrationActivity.getContextOfApplication();
private ImageView profilePic;
private int REQUEST_CAMERA = 0, SELECT_FILE = 1;
private Button btnSelect;
private String userChosenTask;
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case Utility.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if(userChosenTask.equals("Take Photo"))
cameraIntent();
else if(userChosenTask.equals("Choose from Library"))
galleryIntent();
} else {
//code for deny
}
break;
}
}
private void galleryIntent() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);//
startActivityForResult(Intent.createChooser(intent, "Select File"),SELECT_FILE);
}
private void cameraIntent() {
Intent intent = new Intent(ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_FILE)
onSelectFromGalleryResult(data);
else if (requestCode == REQUEST_CAMERA)
onCaptureImageResult(data);
}
}
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
profilePic.setImageBitmap(thumbnail);
}
#SuppressWarnings("deprecation")
private void onSelectFromGalleryResult(Intent data) {
Bitmap bm=null;
if (data != null) {
try {
bm = MediaStore.Images.Media.getBitmap(contextOfApplication
.getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
profilePic.setImageBitmap(bm);
}
private void selectImage() {
final CharSequence[] items = { "Take Photo", "Choose from Library",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
boolean result=Utility.checkPermission(getActivity());
if (items[item].equals("Take Photo")) {
userChosenTask ="Take Photo";
if(result) {
cameraIntent();
}
} else if (items[item].equals("Choose from Library")) {
userChosenTask ="Choose from Library";
if(result) {
galleryIntent();
}
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreateDialog(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View dialogView = inflater.inflate(R.layout.username_dialog, null);
// Select button
btnSelect = (dialogView).findViewById(R.id.btnSelectPhoto);
btnSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectImage();
}
});
// profile pic
profilePic = dialogView.findViewById(R.id.profile_pic);
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(dialogView);
// ... Add action buttons ...
builder.setPositiveButton(R.string.action_register, new DialogInterface.OnClickListener() {
#Override
public final void onClick(final DialogInterface dialog, int id) {
// save the username to Firebase and sign in user ...
// ... casting dialog interface to an alert dialog and casting
// the result of the findView to an EditText
EditText usernameField = (EditText)((AlertDialog) dialog).findViewById(username);
String username = usernameField.getText().toString();
// year
EditText yearField = (EditText)((AlertDialog) dialog).findViewById(R.id.year);
String year = yearField.getText().toString();
// color, make and model
EditText cmmField = (EditText)((AlertDialog) dialog).findViewById(R.id.cmm);
String cmm = cmmField.getText().toString();
// cell
EditText cellField = (EditText)((AlertDialog) dialog).findViewById(R.id.cell);
String cell = cellField.getText().toString();
// license plate no.
EditText plateField = (EditText)((AlertDialog) dialog).findViewById(R.id.licenseNo);
String licenseNo = plateField.getText().toString();
// profic pic
ImageView profil_pic = (ImageView)((AlertDialog) dialog).findViewById(R.id.profile_pic);
// TODO: set up profile pic to save to firebase
// ... get user's unique id
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
User aUser = new User(username, year, cmm, cell, licenseNo);
/* https://android-chat-af94c.firebaseio.com/android-chat-af94c/
users/pRsxsToJZPTzCdtft69f1grIJC13/profile/username
getInstance -> grabbing the url:
https://android-chat-af94c.firebaseio.com/android-chat-af94c/
*/
// above is the same as below ...
FirebaseDatabase.getInstance().getReference("drivers").child(userId).setValue(aUser);
Intent intent = new Intent(getActivity().getBaseContext(), PoliciesActivity.class);
startActivity(intent);
}
});
return builder.create();
}
} // UsernameDialogFragment
AndroidManifest permissions
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"
android:requiredFeature="true"/>
<uses-permission android:name="android.permission.STORAGE"/>
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
In the Android Monitor, it seems to point at 3 lines in particular:
startActivityForResult(intent, REQUEST_CAMERA);
public static class UsernameDialogFragment extends DialogFragment {
cameraIntent();
If you are targeting API Level 23 or more, then you should force get permissions like below(contains several permissions, you can add or remove based on your requirement). Put this in a separate class:
public static List<String> checkAndRequestPermissions(Context context) {
int camera = ContextCompat.checkSelfPermission(context, android.Manifest.permission.CAMERA);
int readStorage = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE);
int writeStorage = ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int fineLoc = ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION);
int coarseLoc = ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (camera != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.CAMERA);
}
if (readStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (writeStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (fineLoc != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
if (coarseLoc != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
return listPermissionsNeeded;
}
And in your activity:
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1; // Declare this integer globally
Add this method(to retrieve permissions):
private boolean permissions(List<String> listPermissionsNeeded) {
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray
(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
And force get permissions like this:
// In my case I've put the 'checkAndRequestPermissions' method in a separate class named 'PermissionUtils'
List<String> permissionList = PermissionUtils.checkAndRequestPermissions(this);
if (permissions(permissionList)) {
dispatchTakePictureIntent(); // call your camera instead of this method
}
If you are testing your app with Android 6.x or 7.x version you need to grant some permission (Location,camera etc..) at run time.You can find how to achieve this in here.
https://developer.android.com/training/permissions/requesting.html
Request the permissions you need at runtime. Code is from here so check it out
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.
}
}
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 set up:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
in the manifest. But the app has still problems writing to external storage.
Looking in application manager the storage permission for the app is thinned off. How to enable it? And why is this happening this now? Is it because of a new android version?
Settings->Applications->Application Manager-><App name>->Permissions
try this to get runtime permission:
if (ContextCompat.checkSelfPermission(sendNotificationActivity.this,Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)
{
if (!ActivityCompat.shouldShowRequestPermissionRationale(sendNotificationActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(sendNotificationActivity.this);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("Storage Permission is needed for sending Image.");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.parse("package:" + activity.getPackageName()));
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions(sendNotificationActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 541);
}
}
else {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, 2);
}
}
And override this:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case 541: {
for( int i = 0; i < permissions.length; i++ ) {
if( grantResults[i] == PackageManager.PERMISSION_GRANTED ) {
Log.d("Permissions CAMERA", "Permission Granted: " + permissions[i]);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, getPhotoFileUri(photoFileName));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, 1);
}
} else if( grantResults[i] == PackageManager.PERMISSION_DENIED ) {
Log.d( "Permissions CAMERA", "Permission Denied: " + permissions[i] );
}
}
break;
}
default: {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
break;
}
}