My application works fine until I got the following error message recently:
java.lang.SecurityException: Unsupported path /storage/emulated/0/xxxzip/1234/abcde.zip
My permission in manifest file:
<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" />
And I also request run-time permission:
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
return true;
} else {
ActivityCompat.requestPermissions(this, new String[]{ android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
return true;
}
}
The app crashes at the last line of this code:
Uri Download_Uri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
String downloadDir = savePath+"/zip/"+productId;
File direct = new File(downloadDir);
if(!direct.exists())
{
if(direct.mkdirs())
{
Log.d(TAG,"folder "+direct+" created");
}
}
int fileNamePos = url.lastIndexOf("/");
String fileName = url.substring(fileNamePos+1);
request.setDestinationUri(Uri.fromFile(new File(downloadDir + "/" + fileName)));
final long download_id = m_downloadManager.enqueue(request);
It was working previously and it's also working in simulator. Any idea?
By the way, here is the example of my download path: /storage/emulated/0/MyAppName/zip/1234. If I save to another folder like Downloads, it will be ok. So I think it's definitely the permission issue.
I added the permissions to write access to the external storage device in the Manifest, and granted them in my Android phone. I even ask for them at execution time if they don't exist.
However, I always get this exception:
java.io.FileNotFoundException: /storage/emulated/03b3d97bd-5186-4506-97dc-9994b7ce0761 (Permission denied)
Do you have an idea of why?
Code
try {
if (Build.VERSION.SDK_INT >= 23) {
int permissionCheck = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory() + image_uuid);
byte[] buffer = new byte[1024];
int bytesRead;
BitmapDrawable bitmapDrawable = (BitmapDrawable) temp.getDrawable();
etc. etc. etc.
And in the manifest file:
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You write file in sd card before you get permission.You must wait for the result of granting permission by using below code:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE/*1 in here*/: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
// write file here
} else {
// permission denied
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
see here
Recently, I have met a really strange problem about permission issue, it confused me a few days, I hope someone will help me figure out what is going on. Thanks!
Here is the problem:
For some reason, I need to apply the storage permission for save some photos, and I had added the permission to the AndroidManifestival.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Off course, I knew I have to apply for storage permission in code after Android 6.0, and here is my code for apply for permission:
public static boolean isGrantExternalRW(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && (context.checkSelfPermission(
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
((Activity)context).requestPermissions(new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, Constants.PERMISSION_REQUEST_CODE);
return false;
}
return true;
}
I had use this method before I saved photo, and the permission dialog had shown up and I had checked it. And I had checked the app permission in the app setting, it's ok.
And here is the method I used to save the bitmap to the file:
public static String savePhotoToSDCard(Bitmap bitmap, String photoName) {
String absolutePath = "";
String state = Environment.getExternalStorageState();
Log.e("file", "---------------------" + state);
File newsDir = new File(Environment.getExternalStorageDirectory().toString()
+ File.separator + "photo");
if (!newsDir.exists()) {
newsDir.mkdirs();
}
File picFile = new File(newsDir, photoName + ".png");
absolutePath = picFile.getAbsolutePath();
if (picFile.exists()) {
picFile.delete();
}
if (photoName.equals("avatar")) {
int ratio = 2;
Bitmap result = Bitmap.createBitmap(bitmap.getWidth() / ratio, bitmap.getHeight() / ratio, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Rect rect = new Rect(0, 0, bitmap.getWidth() / ratio, bitmap.getHeight() / ratio);
canvas.drawBitmap(bitmap, null, rect, null);
}
try {
FileOutputStream fileOutputStream = new FileOutputStream(picFile);
if (bitmap != null) {
if (bitmap.compress(Bitmap.CompressFormat.PNG, 30, fileOutputStream)) {
fileOutputStream.flush();
Log.d("Photo", "---------------------------fileOutputStream.flush");
fileOutputStream.close();
}
}
} catch (FileNotFoundException e) {
Log.e("File", "----------------------------" + e.toString());
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return absolutePath;
}
When I ran the app, it went wrong, here is the log:
java.io.FileNotFoundException: /storage/emulated/photo/avatar.png(permission denied)
But the most strange thing was that when I add the storage permission twice to AndroidManifestival.xml, it worked!
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
So, what's the problem? Please help.
Luckily, I solved my problem finally. Here was the reason:
The storage permission conflicts with the dependency below:
compile 'com.github.vungle:vungle-android-sdk:5.3.0'
When I added the dependency, system cannot recognized the storage permission which I have apply for(while I added twice in AndroidManifest.xml, it worked), but when I removed it, everything was ok ! This dependency was used to add ad into app, but now I have to abandon it.
call this method in splash screen or where you open camera .
public static boolean checkAndRequestPermissions(Context context) {
int cameraPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA);
int readfilePermission = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE);
int writefilePermission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (cameraPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CAMERA);
}
if (readfilePermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (writefilePermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions((Activity) context, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
In AndroidManifestival.xml you need to add
<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" />
can you try like this, i think you are deleting the file as soon as you are creating it.
if (new File(newsDir, photoName + ".png").exists()) {
new File(newsDir, photoName + ".png").delete();
}
File picFile = new File(newsDir, photoName + ".png");
absolutePath = picFile.getAbsolutePath();
and in the place of
Environment.getexternalstoragedirectory().toString()
use this
Environment.getexternalstoragedirectory().getabsolutepath()
I think the solution is similar to Requesting Permissions at Run Time.
Have you handled the permissions request response?
Related to these links you have to implement these steps correctly in your code:
First: try to use this to request the permission:
boolean permissionGranted = ActivityCompat.checkSelfPermission(this, Manifest.permission......) == PackageManager.PERMISSION_GRANTED;
if(permissionGranted) {
// {Some Code}
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission....}, 200);
}
Second: implementation of OnRequestPermissionsResultCallback
...implements ActivityCompat.OnRequestPermissionsResultCallback {
Third: override onRequestPermissionsResult method
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 200: {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// {Some Code}
}
}
}
}
I have a problem creating directory on SD card.
AndroidManifest.xml contains neccessary permissions:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application...
Also for Android 6.0 I ask these permissions at runtime:
int permissionCheck1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
int permissionCheck2 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_READWRITE_STORAGE);
} else {
init();
}
and waiting for results:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_READWRITE_STORAGE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
init();
} else {
Toast toast = Toast.makeText(this, "Read / Write storage permissions required", Toast.LENGTH_SHORT);
toast.show();
}
break;
default:
break;
}
}
My application determines two available storages:
internal - /storage/emulated/0
and external (removable SD card) - /storage/6052-CD5B
I create folders using
new File(parentDirectory, newDirectoryName).mkdirs();
Results:
I can create folder inside /storage/emulated/0.
I can create folder inside /storage/6052-CD5B/Android/data/myapp (this is my application folder).
But I can't create folder in /storage/6052-CD5B outside my application folder, e.g. images folder /storage/6052-CD5B/DCIM.
It seems that granted permissions give me access only to application-specific folder. Is it so? If not, how can I finally get write access to other SD card folders?
I try to create a folder in sdcard
File folder = new File(Environment.getExternalStorageDirectory().getPath() + File.separator + "folder");
Log.d(TAG, "FOLDER :" +folder);
folder.mkdir();
mkdir always return false. I added permission to manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I can create folder with adb tool.
Phone is Nexus 5 Android 6.0.1
what is wrong with code ?
In android 6.0+ you have to request permission at runtime, so in onCreate() request WRITE_EXTERNAL_STORAGE
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
And add this method (optional):
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted!
} else {
// permission denied!
Toast.makeText(MainActivity.this, "Permission denied to write External storage", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
You can use also Nammu to check the permissions