I cannot create new folder any way, it always return false when use mkdirs. I am using Android 6.0.1 in android studio debug mode.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />`
String folder_main = "NewFolder";
Boolean success = false;
File f = new File(Environment.getExternalStorageDirectory(),folder_main
);
if (!f.exists()) {
Log.d("path","not exist");
success=f.mkdirs();
}
else
{
Log.d("path","exist");
}
Log.d("path",success.toString());
I didn't use write permission since in this docs
Starting in API level 19, this permission is not required to
read/write files in your application-specific directories returned by
getExternalFilesDir(String) and getExternalCacheDir().
The doc says you can read/write files only in the directories returned by getExternalFilesDir(String) and getExternalCacheDir() without write permission. But you get directory path by Environment.getExternalStorageDirectory().
Javadoc of Environment.getExternalStorageDirectory() says.
Writing to this path requires the WRITE_EXTERNAL_STORAGE permission, and starting in KITKAT, read access requires the READ_EXTERNAL_STORAGE permission, which is automatically granted if you hold the write permission.
Starting in KITKAT, if your application only needs to store internal data, consider using getExternalFilesDir(String), getExternalCacheDir(), or getExternalMediaDirs(), which require no permissions to read or write.
Related
I'm unable to create directory in android 10. It's working on devices till android Oreo.
I tried two ways for creating folders.
Using File.mkdir():
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
if (!f.isFile()) {
if (!(f.isDirectory())) {
success = f.mkdir();
}
Here, the variable success is always false which means the directory isn't created.
Using Files.createDirectory():
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
if (!f.isFile()) {
if (!(f.isDirectory())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try {
Files.createDirectory(Paths.get(f.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), R.string.unable_to_download, Toast.LENGTH_LONG).show();
}
} else {
f.mkdir();
}
}
which causes this exception:
pzy64.pastebinpro W/System.err: java.nio.file.AccessDeniedException: /storage/emulated/0/Pastebin
pzy64.pastebinpro W/System.err: at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:391)
pzy64.pastebinpro W/System.err: at java.nio.file.Files.createDirectory(Files.java:674)
I've implemented the run-time permissions and
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
are all set.
As was first disclosed back in March 2019, you no longer have access by default to arbitrary locations on external storage or removable storage on Android 10+. This includes Environment.getExternalStorageDirectory() and other methods on Environment (e.g., getExternalStoragePublicDirectory().
For Android 10 and 11, you can add android:requestLegacyExternalStorage="true" to your <application> element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work.
Otherwise, your choices are:
Use methods on Context, such as getExternalFilesDir(), to get at directories on external storage into which your app can write. You do not need any permissions to use those directories on Android 4.4+. However, the data that you store there gets removed when your app is uninstalled.
Use the Storage Access Framework, such as ACTION_OPEN_DOCUMENT and ACTION_CREATE_DOCUMENT.
If your content is media, you can use MediaStore to place the media in standard media locations.
For Android 10, you can add
android:requestLegacyExternalStorage="true"
to your element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work. This fix will not work on Android R and higher though, so this is only a short-term fix.
There are more restrictions in Android API 30
you can only write in your app-specific files
File dir_ = new File(context.getFilesDir(), "YOUR_DIR");
dir_.mkdirs();
or in the external storage of your app Android/data
File dir_ = new File(myContext.getExternalFilesDir("FolderName"),"YOUR_DIR");
UPDATE
this answer provided another solution https://stackoverflow.com/a/65744517/8195076
UPDATE
another way is to grant this permission in manifest
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
like this answer https://stackoverflow.com/a/66968986/8195076
This works for me and I think it's functional on Android 10>
ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Folder Example");
String path = String.valueOf(resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues));
File folder = new File(path);
boolean isCreada = folder.exists();
if(!isCreada) {
folder.mkdirs();
}
You can use public directory to save files in Android 11 like this:
dir = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getPath()
+ "/foldername");
if (!dir.exists()) {
dir.mkdir();
Toast.makeText(getApplicationContext(), "not exist", Toast.LENGTH_SHORT).show();
}
Since Q beta 4 it's possible to opt-out of that feature by:
targeting api 28 (or lower)
using requestLegacyExternalStorage manifest attribute:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
only use
android:requestLegacyExternalStorage="true"
in manifests
I'm unable to create directory in android 10. It's working on devices till android Oreo.
I tried two ways for creating folders.
Using File.mkdir():
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
if (!f.isFile()) {
if (!(f.isDirectory())) {
success = f.mkdir();
}
Here, the variable success is always false which means the directory isn't created.
Using Files.createDirectory():
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
if (!f.isFile()) {
if (!(f.isDirectory())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try {
Files.createDirectory(Paths.get(f.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), R.string.unable_to_download, Toast.LENGTH_LONG).show();
}
} else {
f.mkdir();
}
}
which causes this exception:
pzy64.pastebinpro W/System.err: java.nio.file.AccessDeniedException: /storage/emulated/0/Pastebin
pzy64.pastebinpro W/System.err: at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:391)
pzy64.pastebinpro W/System.err: at java.nio.file.Files.createDirectory(Files.java:674)
I've implemented the run-time permissions and
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
are all set.
As was first disclosed back in March 2019, you no longer have access by default to arbitrary locations on external storage or removable storage on Android 10+. This includes Environment.getExternalStorageDirectory() and other methods on Environment (e.g., getExternalStoragePublicDirectory().
For Android 10 and 11, you can add android:requestLegacyExternalStorage="true" to your <application> element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work.
Otherwise, your choices are:
Use methods on Context, such as getExternalFilesDir(), to get at directories on external storage into which your app can write. You do not need any permissions to use those directories on Android 4.4+. However, the data that you store there gets removed when your app is uninstalled.
Use the Storage Access Framework, such as ACTION_OPEN_DOCUMENT and ACTION_CREATE_DOCUMENT.
If your content is media, you can use MediaStore to place the media in standard media locations.
For Android 10, you can add
android:requestLegacyExternalStorage="true"
to your element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work. This fix will not work on Android R and higher though, so this is only a short-term fix.
There are more restrictions in Android API 30
you can only write in your app-specific files
File dir_ = new File(context.getFilesDir(), "YOUR_DIR");
dir_.mkdirs();
or in the external storage of your app Android/data
File dir_ = new File(myContext.getExternalFilesDir("FolderName"),"YOUR_DIR");
UPDATE
this answer provided another solution https://stackoverflow.com/a/65744517/8195076
UPDATE
another way is to grant this permission in manifest
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
like this answer https://stackoverflow.com/a/66968986/8195076
This works for me and I think it's functional on Android 10>
ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Folder Example");
String path = String.valueOf(resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues));
File folder = new File(path);
boolean isCreada = folder.exists();
if(!isCreada) {
folder.mkdirs();
}
You can use public directory to save files in Android 11 like this:
dir = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getPath()
+ "/foldername");
if (!dir.exists()) {
dir.mkdir();
Toast.makeText(getApplicationContext(), "not exist", Toast.LENGTH_SHORT).show();
}
Since Q beta 4 it's possible to opt-out of that feature by:
targeting api 28 (or lower)
using requestLegacyExternalStorage manifest attribute:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
only use
android:requestLegacyExternalStorage="true"
in manifests
After countless searching I've managed to find path to my sdcard not the android emulated storage. But when I try to make .txt folder there it ends up with error
/storage/37F0-1515/DCIM/100MEDIA/test.txt: open failed: EACCES (Permission denied)
I don't know why because I have permissions for
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and also I've enabled the permissions with
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, request2);
}
Here is the code that I'm using
File sdCard = new File("/storage/37F0-1515/DCIM/100MEDIA");
File dir = new File(sdCard.getAbsolutePath());
if (!dir.exists()) {
dir.mkdirs();
}
final File file = new File(dir, "test" + ".txt");
try {
BufferedWriter bufferedWriter = null;
bufferedWriter = new BufferedWriter(new FileWriter(file));
bufferedWriter.write("test");
bufferedWriter.close();
}
catch(Exception e){Log.v("myApp", e.toString());}
I don't know why android won't let me write to sdcard. Do I need some other permissions ?
I don't know why because I have permissions for
Those permissions are for external storage, not removable storage.
I don't know why android won't let me write to sdcard
You do not have arbitrary filesystem access to removable storage on Android 4.4+.
Try using these methods-
Check if the uses-permission statements are in the right place, they should be below <manifest> and above <application> tags. The correct format -
<manifest>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
<application>
...
<activity>
...
</activity>
</application>
</manifest>
Starting from Android Kitkat, there is a new storage policy -
The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions. Restricting writes in this way ensures the system can clean up files when applications are uninstalled.
This can however be exploited without rooting(although I have not tried this one), as mentioned here
EDIT -
The above mentioned exploit won't work for Android 5+. There is no standard solution to this problem. Some exploits may be available but they will be device-specific/not reliable/root-access dependent.
However, tools like the Storage Access Framework can be used.
When I am trying to write into external SDcard from android native code, I am getting permission denied in fopen.
mFp = fopen("/storage/extSdCard/Output/test.txt", "wb");
if I print strerror(errno) it gives ->
fopen(/storage/extSdCard/Output/test.txt) failed: Permission denied
Please note that I have also given the permissions in my Application manifest :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
....
</manifest>
and also :
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
is returing true.
Please check if the external storage is an external card that is inserted or the sdcard that comes with the device.If it is an sdcard that comes with the device itself try your path as "/mnt/drive_path" and check if you native method is able to write to your storage.
I'm unable to create directory in android 10. It's working on devices till android Oreo.
I tried two ways for creating folders.
Using File.mkdir():
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
if (!f.isFile()) {
if (!(f.isDirectory())) {
success = f.mkdir();
}
Here, the variable success is always false which means the directory isn't created.
Using Files.createDirectory():
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
if (!f.isFile()) {
if (!(f.isDirectory())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try {
Files.createDirectory(Paths.get(f.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), R.string.unable_to_download, Toast.LENGTH_LONG).show();
}
} else {
f.mkdir();
}
}
which causes this exception:
pzy64.pastebinpro W/System.err: java.nio.file.AccessDeniedException: /storage/emulated/0/Pastebin
pzy64.pastebinpro W/System.err: at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:391)
pzy64.pastebinpro W/System.err: at java.nio.file.Files.createDirectory(Files.java:674)
I've implemented the run-time permissions and
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
are all set.
As was first disclosed back in March 2019, you no longer have access by default to arbitrary locations on external storage or removable storage on Android 10+. This includes Environment.getExternalStorageDirectory() and other methods on Environment (e.g., getExternalStoragePublicDirectory().
For Android 10 and 11, you can add android:requestLegacyExternalStorage="true" to your <application> element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work.
Otherwise, your choices are:
Use methods on Context, such as getExternalFilesDir(), to get at directories on external storage into which your app can write. You do not need any permissions to use those directories on Android 4.4+. However, the data that you store there gets removed when your app is uninstalled.
Use the Storage Access Framework, such as ACTION_OPEN_DOCUMENT and ACTION_CREATE_DOCUMENT.
If your content is media, you can use MediaStore to place the media in standard media locations.
For Android 10, you can add
android:requestLegacyExternalStorage="true"
to your element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work. This fix will not work on Android R and higher though, so this is only a short-term fix.
There are more restrictions in Android API 30
you can only write in your app-specific files
File dir_ = new File(context.getFilesDir(), "YOUR_DIR");
dir_.mkdirs();
or in the external storage of your app Android/data
File dir_ = new File(myContext.getExternalFilesDir("FolderName"),"YOUR_DIR");
UPDATE
this answer provided another solution https://stackoverflow.com/a/65744517/8195076
UPDATE
another way is to grant this permission in manifest
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
like this answer https://stackoverflow.com/a/66968986/8195076
This works for me and I think it's functional on Android 10>
ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Folder Example");
String path = String.valueOf(resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues));
File folder = new File(path);
boolean isCreada = folder.exists();
if(!isCreada) {
folder.mkdirs();
}
You can use public directory to save files in Android 11 like this:
dir = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getPath()
+ "/foldername");
if (!dir.exists()) {
dir.mkdir();
Toast.makeText(getApplicationContext(), "not exist", Toast.LENGTH_SHORT).show();
}
Since Q beta 4 it's possible to opt-out of that feature by:
targeting api 28 (or lower)
using requestLegacyExternalStorage manifest attribute:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
only use
android:requestLegacyExternalStorage="true"
in manifests