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.
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 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.
On Samsung T230 (Android 4.4.2) It works in both of the following
File firstFile = new File("mnt/extSdCard/Android/data/com.example.storagetest", "test.txt");
RandomAccessFile fileLittle = new RandomAccessFile(firstFile, "rw");
File scndFile = new File("mnt/extSdCard/Android/data/com.example.storagetest", "test2.txt");
scndFile.createNewFile();
I've tried a lot of these devices are working in this way. T230 is an example
On Hometech Tablet (Android 5.1.1) does not work.
File firstFile = new File("mnt/external_sd/Android/data/com.example.storagetest", "test.txt");
RandomAccessFile fileLittle = new RandomAccessFile(firstFile, "rw");
File scndFile = new File("mnt/external_sd/Android/data/com.example.storagetest", "test2.txt");
scndFile.createNewFile();
I get an error as follows:
open failed: EACCES (Permission denied)
Current AndroidManifest.xml
<application>
...
</application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I tried many different ways... requestPermissions() and android:maxSdkVersion does not change anything
Too much search but I could not reach a conclusion.
How can i create a file on SD Card.
Important: I can read files directly, but cant change or create new file.
How can i create a file on SD Card.
You don't. Devices that ship with Android 4.4+ do not allow arbitrary access to removable storage.
You can indirectly work with removable storage via the Storage Access Framework. There, you do not worry about exactly where the user is putting the data (external storage, removable storage, Google Drive, Dropbox, etc.).
i have a piece of code, which creates a file on the /sdcard on the ExternalStorage ("internal" 8GB Memory of a GalaxyTab2 7.0).
directory = new File(Environment.getExternalStorageDirectory(),
"/logs");
directory.mkdirs();
log = new File(directory.getPath() + "/" + this.filename);
boolean created = log.createNewFile();
At the last line i get following error:
... java.io.IOException: open failed: EACCES (Permission denied)
... at java.io.File.createNewFile(File.java:948)
I have
set the permission for writing external storage in the right place in manifest
checked, that the memory is not mounted at pc
checked, that the /logs/ folder hat the correct permissions at file explorer
read every single stackoverflow thread about the topic - nothing worked
Has anyone a hint, which can cause this behavior?
best regards
add below permission in manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I used a (self-written) library, which manages all the memory access. This library project has the WRITE_EXTERNAL_STORAGE permission. The App, which references this library must also have this permission, even if it is not directly accessing the 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