I am trying to delete some files on the SD card , but i ran out of ideas..
I tried File.delete() method, then I have tried file.getCanonicalFile().delete()
and many more ..
My application can just delete files on the device storage .
I have got the permissions defined in the Manifest file that is required like below.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and I am requesting for permission in the code also:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
new AlertDialog.Builder(this)
.setTitle(R.string.read_storage_message)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MainActivity.READ_STORAGE_PERMISSION_ID);
}
}
)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
AppKiller.kill();
}
}
).show();
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
new AlertDialog.Builder(this)
.setTitle(R.string.write_storage_message)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MainActivity.STORAGE_PERMISSION_ID);
}
}
)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
AppKiller.kill();
}
}
).show();
}
}
I am using the following method to delete the files, but as i mentioned before, I've used plenty of solutions found in Stack-overflow and others.
protected boolean delete(Context context) throws Exception {
boolean delete = false;
File file = new File(Environment.getExternalStorageDirectory().getPath() + getName());
if (file.exists()) {
delete = file.delete();
if (!delete) {
delete = file.getCanonicalFile().delete();
}
if (!delete) {
String deleteCmd = "rm -r " + file.getAbsolutePath();
Runtime runtime = Runtime.getRuntime();
runtime.exec(deleteCmd);
}
}
return delete;
}
could it be because i am asking for READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions, but in code i am just getting READ_EXTERNAL_STORAGE granted and the other is getting ignored from Android(it won't show permission WRITE_EXTERNAL_STORAGE popup with allow-deny options after I accept the first one) . Isn't it because they have the same permission's level in android ?
what could be wrong ?
If you want to delete file from SD Card you can use following code:
File file = new File("/sdcard/myfile.txt");
boolean deleted = file.delete();
Yes you cannot delete files from SD card on modern Android versions anymore using the File class.
Use the Storage Access Framework instead.
Have a look at Intent.OPEN_DOCUMENT_FILE and OPEN_DOCUMENT_TREE.
If you want to delete file from SD Card you can use following code:
File file = new File(selectedFilePath);
boolean deleted = file.delete();
where selectedFilePath is the path of the file you want to delete.
for example: selectedFilePath =
/sdcard/YourDirectory/TestFile.mp3
also you have to give permission if you are using >1.6 SDK
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
in AndroidManifest.xml file
Hope this may help you
Related
How I'm requesting
public void requestPermissionToWriteToFile() {
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
new AlertDialog.Builder(this)
.setTitle("Permission needed")
.setMessage("This permission is needed for camera use and internal file save")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_REQUEST_WRITE_FILES);
}
})
.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.WRITE_EXTERNAL_STORAGE},
PERMISSION_REQUEST_WRITE_FILES);
}
}
How I'm Checking
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == PERMISSION_REQUEST_WRITE_FILES){
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{Toast.makeText(this, "PERMISSION_GRANTED", Toast.LENGTH_SHORT).show();}
else
{Toast.makeText(this, "PERMISSION_DENIED", Toast.LENGTH_SHORT).show();}
}
}
As soon as the app boots up, the accesses is never granted and it just stays that way, when I call on the above method the dialog for permission wont come up (the permission isn't being asked). Even when I go to settings and change it from there it still won't grant me permission to WRITE_EXTERNAL_STORAGE. the above code is in my main class, the permission is in Manifest, what else is needed to fix this?
there was another thread like this but that didn't solve my problem jsyk.
Before trying the following code, add the missing G in STORAGE.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Then call this when your button is clicked:
if (androidx.core.content.ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE) == android.content.pm.PackageManager.PERMISSION_DENIED || androidx.core.content.ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == android.content.pm.PackageManager.PERMISSION_DENIED) {
androidx.core.app.ActivityCompat.requestPermissions(MainActivity.this, new String[] {android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1001);
} else {
//permission already granted
}
Also, add read external storage permission to avoid any issues:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
In phone settings permissions are granted. Phone with Android 8.0.
compileSdkVersion 28
minSdkVersion 16
targetSdkVersion 28
Manifest has:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
In my code this "permissions" variable equals -1 always:
int permissions = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
Starting with Android 6 (API 23) you must also request this permission at runtime. This video may help: https://youtu.be/WGz-alwVh8A
Ok, thanks to Larry Schiefer for runtime permissions.
Considering to android docs:
link 1
link 2
I made some changes to the method from link 2. Before doing something it checks permissions and if necessary asks user for confirmation, in other case it sets permissions forcibly.
public void requestRuntimePermission(final Context context, final String manifestPermission, final int requestCode) {
int permissions = ContextCompat.checkSelfPermission(context, manifestPermission);
if (permissions != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context,
manifestPermission)) {
android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(context);
builder.setMessage("Allow access?")
.setCancelable(true)
//Cancel
.setNegativeButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
//Ok
.setPositiveButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ActivityCompat.requestPermissions((Activity) context,
new String[]{manifestPermission},
requestCode);
}
});
android.support.v7.app.AlertDialog alert = builder.create();
alert.show();
} else {
// Permission has not been granted yet. Request it directly.
ActivityCompat.requestPermissions((Activity) context, new String[]{manifestPermission},
requestCode);
}
}
}
Example of usage:
requestRuntimePermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE, 0);
P.S. requestCode parameter in requestRuntimePermission can be used to identify which of permission allowed in onRequestPermissionsResult callback. (link 3)
I am coding an Android app (in Java) which uses OCR to convert handwriting into digital text. I am trying to take the String generated by the OCR function in my code and write it to a text file (the OCR portion is currently working). I would then like to create a folder (in phone's external storage, for example My Files on Samsung) and add the text file to this folder, which contains only the files the user has created (which the user should be able to access and share).
I have conducted some research on writing to phone's external storage (including other StackOverflow questions) but no tutorial has worked for me.
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
public File writeFolder ()
{
File file = null;
if (isExternalStorageWritable())
{
// Get the directory for the user's public directory.
file = new File(Environment.getExternalStorageDirectory() + File.separator + "OCR Documents");
}
if (!file.mkdirs())
Log.e(LOG_TAG, "Directory not created");
else
System.out.println(file.getAbsolutePath());
return file;
}
The code above is what I have, however after testing it, the AbsolutePath is null. It does not seem to be creating a folder on the phone's external storage. How would I go about this so that a folder is created and I can add files to that folder?
Your code to create the directory is fine.
But there's a chance you're missing permissions due to newer versions of Android requiring a User's consent before you can write files to the external storage.
First, make sure you have this permission in your Manifest.xml:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Afterwards, since WRITE_EXTERNAL_STORAGE is listed as a Dangerous Permission, as seen here: https://developer.android.com/guide/topics/permissions/overview#normal-dangerous , you'll also need to explicitly request the permission from the user.
Finally, to request the permission:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not 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; 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 {
// Permission has already been granted
}
You'll also need to handle the response of the request:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
The above code was copied from: https://developer.android.com/training/permissions/requesting
You should read that link more thoroughly since it provides a good explanation of what you need to explain to the user, since users are typically very wary when Apps ask for permissions to modify files in their storage.
You can try this,
private void getWirtePermissionAndCreateDir() {
if (Build.VERSION.SDK_INT < 23) {
createDir();
} else {
final String[] PERMISSIONS_STORAGE = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
//Asking request Permissions
ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, 9);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
boolean writeAccepted = false;
switch (requestCode) {
case 9:
writeAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (writeAccepted) {
createDir();
} else {
Toast.makeText(MainActivity.this, "You don't assign permission.", Toast.LENGTH_LONG).show();
}
}
private void createDir(){
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "OCR Documents");
file.mkdirs();
Toast.makeText(MainActivity.this, file.getAbsolutePath(), Toast.LENGTH_LONG).show();
}
You have to add getWirtePermissionAndCreateDir() instead of writeFolder() in activity body.
Below function will create folder and then create file in that folder and if folder already exists then simply create file.
private FileOutputStream fos;
//Function: create a file in a folder
private boolean createFileInFolder(String fileName, String folderName) {
if (isExternalStorageWritable()) {
String path = Environment.getExternalStorageDirectory() + "/" + folderName;
File folder = new File(path);
if (!folder.exists()) {
folder.mkdirs();
}
txtFile = new File(path, fileName);
try {
fos = new FileOutputStream(txtFile);
return true;
} catch (IOException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;
}
} else
return false;
}
//Function: IsExternalStorageWritable?
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
You may need to check permissions so also define these functions.
private boolean permission;
private final int MY_PERMISSIONS_REQUEST = 10;
//Function: checkPermission
private void checkPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST);
} else {
permission = true;
}
}
//Function: Permission Request Results
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
permission = true;
} else {
permission = false;
}
return;
}
}
}
In your manifest file don't forget to add this line.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
It seems that whenever I use MkDirs or save the file by itself (without making a directory), it fails. The app does have permission to write and read storage, as this was checked in the main activity and the activity will not even start if permission is not granted. I am running this on Android 8.1.0 on a Pixel 2 XL. Using DIRECTORY_DOWNLOADS, and others like that have also not worked. It feels like a permissions or other storage issue, but I am not so sure.
public void onInput(MaterialDialog dialog, CharSequence input) {
inputNormal = textContent.getText().toString();
File rootFolder = new File(Environment.getExternalStorageDirectory().toString(), "Sorbet");
if (!rootFolder.exists()) {
rootFolder.mkdirs();
}
try {
File file = new File(rootFolder, input.toString()+".txt");
BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));
writer.write(inputNormal);
writer.newLine();
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
For context, here is the code that I use to check permissions. This is fully working, as the dialog shows to grant permission, and the permission shows as granted in the system settings for the app.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int permissionCheck = ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck == PackageManager.PERMISSION_DENIED) {
Snackbar errorBar = Snackbar.make(findViewById(R.id.content_main), getString(R.string.snackbar_error),
Snackbar.LENGTH_LONG)
.setAction(getString(R.string.allow_access), new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
STORAGE_PERMISSION_RC);
}
});
errorBar.show();
}
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
startActivity(NoteCreateIntent);
}
}
});
}
else{
fab.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
startActivity(NoteCreateIntent);
}
});
}
I would try, just temporarily, switching the folder that you are putting files in from
Environment.getExternalStorageDirectory()
to
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
This directory (along with the music, videos, etc. directories) always seems to be well-defined, whereas the getExternalStorageDirectory varies from device to device.
I would suspect that getExternalStorageDirectory is just not returning the correct value. You should try saving in a different directory to ensure that the error is not due to some other part of your code.
If you can't save to the downloads folder, then the error is likely in some other part of your code.
If you can save to the downloads folder, then the error is most likely due to something weird with the path returned by getExternalStorageDirectory().
EDIT
Two more suggestions:
Log the value of rootFolder. You need to triple check to make sure that it is what you think it should be. Please edit the question with this value.
mkdirs returns a boolean indicating whether the directory was made. That command CAN fail, typically if there is a permissions issue. You should also log the return value of that command. If, for instance, mkdirs returns false, then you know where the problem lies.
The issue has been fixed. This was a permission issue with Android. In order to write files, you have to explicitly ask for WRITE_EXTERNAL_STORAGE, something that I dismissed.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
val permissionCheck = ContextCompat.checkSelfPermission(applicationContext,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
//Granted Permission
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
val sorbetDirectory = File(Environment.getExternalStorageDirectory().path + "/Sorbet")
sorbetDirectory.mkdirs()
}
//Denied Permission
if (permissionCheck == PackageManager.PERMISSION_DENIED) {
MaterialDialog.Builder(this)
.title(com.marlonjones.sorbet.R.string.titleP)
.content(com.marlonjones.sorbet.R.string.perm_content)
.positiveText(com.marlonjones.sorbet.R.string.ok)
.onPositive { dialog, which ->
ActivityCompat.requestPermissions(this#MainActivity,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
STORAGE_PERMISSION_RC)
}
.show()
}
}
Below code is working fine on pre-Marshmallow devices but not in Marshmallow.
These are the permissions in Manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Here is the code
public void saveImageToSDCard(Bitmap bitmap) {
File myDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
pref.getGalleryName());
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Wallpaper-" + n + ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
Uri uri = getImageContentUri(_context,file);
Log.d(TAG, "Wallpaper saved to: " + file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
And the same code works when I manually allow the storage permission
Here is the solution given by Nitesh Pareek.
private 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;
}
String[] PERMISSIONS = new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (!hasPermissions(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, 11);
return;
}
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
This is why it works in pre-lolipop versions, and doesn't on API 23. Permissions in Android Manifest alone are not enough, you need to add them at runtime as well. Refer here for more details.
give read write permissions on run time for marshmallow or newer version.
Do like below:-
String[] PERMISSIONS = new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (!hasPermissions(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, 11);
return;
}
private 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;
}
You need to take application permissions at runtime instead of taking when install/update as convention
Beginning in Android 6.0 (API level 23), users grant permissions to
apps while the app is running, not when they install the app. This
approach streamlines the app install process, since the user does not
need to grant permissions when they install or update the app
For more help: Requesting Permissions at Run Time
By focusing on the documentation and after doing some google searches, finally I have compiled the code below to handle runtime permissions efficiently
To make it work, you need to follow the instructions below:
Call this method to check if storage permission is granted by user?
If not, then you need to request for it
public static boolean isStoragePermissionGranted(Activity activity) {
boolean flag = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
flag = activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}
return flag;
}
Call this method to request storage permission
public static void requestStoragePermission(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (isStoragePermissionGranted(activity)) {
return;
}
// Fire off an async request to actually get the permission
// This will show the standard permission request dialog UI
activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CODE_STORAGE_PERMISSION);
}
}
Implement this method in your activity to handle response of permission callback
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE_STORAGE_PERMISSION:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
boolean shouldShowRationale = shouldShowRequestPermissionRationale(permissions[0]);
if (!shouldShowRationale) {
// user denied flagging NEVER ASK AGAIN, you can either enable some fall back,
// disable features of your app or open another dialog explaining again the permission and directing to
// the app setting
dialogReasonStoragePermissionToSettings(this);
} else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permissions[0])) {
// user denied WITHOUT never ask again, this is a good place to explain the user
// why you need the permission and ask if he want to accept it (the rationale)
dialogReasonStoragePermission(this);
}
} /*else {
// Do on permission granted work here
}*/
}
}
break;
}
}
public static void dialogReasonStoragePermission(final Activity activity) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(activity.getString(R.string.reason_storage_permission));
builder.setCancelable(false);
builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
requestStoragePermission(activity);
}
});
builder.setNegativeButton("Dismiss", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
public static void dialogReasonStoragePermissionToSettings(final Activity activity) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(activity.getString(R.string.reason_storage_permission));
builder.setCancelable(false);
builder.setPositiveButton("Go to Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
goToAppDetailsForPermissionSettings(activity);
}
});
builder.setNegativeButton("Dismiss", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
private static final int REQUEST_CODE_APP_DETAILS_PERMISSION_SETTING = 3995;
private static void goToAppDetailsForPermissionSettings(Activity activity) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
activity.startActivityForResult(intent, REQUEST_CODE_APP_DETAILS_PERMISSION_SETTING);
}
I am not providing you direct code for this but here is a reason API level 23 introduce a new Permission structure for more security below is a short but wast description of thing, in documentation here
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.
Code is good just you have to put something additional and that is Runtime Permissions for storage.
Read this blog to know everything from deep inside about Runtime Permissions gave me a clear picture about it, hope it helps you too.
Thanks