I want to write logs to the SD card like this
String filePath = "/storage/FC30-3DA9" + "/logs" + "/logcat.txt";
in Manifest
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and i request them from the user.
I can read the file from the card, but I can't write it. When I try to write a file, I get permission denied.
The path Environment.getExternalStorageDirectory() leads to the internal memory of the phone. I have root.
Yes. Since Android Kitkat removable micro sd cards are read only.
Only at Android 11 devices they are writable again.
But there is one exception: your app specific directory on the card.
Look at the second item returned by getExternalFilesDirs().
If you use Storage Access Framework instead your app can write everywhere.
Related
I uploaded an android photo compress application in play store and I checked every thing is ok, but some users have issue that the application can not save compressed photos, I checked that and I found this error
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: FileSystemException: Cannot create file, path = '/storage/emulated/0/My Folder/photo.jpg' (OS Error: Operation not permitted, errno = 1)
This is permissions AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
<uses-permission android:name="android.permission.CAMERA"/>
This line inside application tag
android:requestLegacyExternalStorage="true"
I looked for some solutions and founded this permission line
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
But when ask for this permission android shows to user warning the application will access to all files without asking permission, I feel this is worrying for users and some may be afraid of this permission, however I uploaded the application but it was rejected because using MANAGE_EXTERNAL_STORAGE permission.
you are right regarding MANAGE_EXTERNAL_STORAGE permission. Your app will be removed from play store if you don't have valid reasons. You may have to create a video and explain why you need these permission, and how scoped storage can't help you.
Now, you should know one thing that you are trying to create a folder directly inside internal storage. This will work in lower android versions but will fail in Android 10 or above even when you have WRITE_EXTERNAL_STORAGE granted.
Try creating your files inside public directories like Download or Documents. If the files downloaded doesn't need to be accessed by users then you can always save in your package folder context.getExternalFilesDir(null)
Hope this helped you! If you have any further doubts feel free to comment down below.
I'm trying to achieve some clean up tools. More and more manufacturers have forbidden rooting devices due to some "security reason", it's forbidden NOT to request for unlock.
After API 28, This code will make error:
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 1); // Request permission or not, Will got same result
File rootFolder = Environment.getExternalStorageDirectory(); // That is working fine
rootFolder.listFiles(); // That will return null
Sure, I can use this:
android:requestLegacyExternalStorage="true"
But I belive that will be killed in future.
So, Any elegant way to manage SDCard?
On Android 10 Environment.getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() will return storage paths but paths are not readable or writable.
For Android 10 you can continue to use paths provided by Environment.getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() if you add android:requestLegacyExternalStorage="true" to application tag in manifest file. At runtime your app can call Environment.isExternalStorageLegacy() to check if the request has been done.
Another (not known) possibility (only for Android 10) is to add <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> to manifest file.
The user has to go to the advanced settings of the app and enable from Advanced settings Install unknown apps | Allow from this source.
The nice thing with this is that the user can switch the access rights. You can make it easier for the user if you implement an intent for
Settings.ACTION_APPLICATION_DETAILS_SETTINGS where he can change the settings.
A funny thing is that Environment.isExternalStorageLegacy() returns true then too.
Compiling for Android 11 both options do not work on an Android 11 device. (But they continue to work for Android 10 devices). The paths of Environment.getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() are usable again in read mode and very often in write mode too. And this is great as one can simply list the contents of directories like Download or Pictures or DCIM/Camera again using the File class.
But adding <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> to manifest file and implementing an intent for
Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION will give your app read/write access for all files even on removable micro sd card.
(Finally you can remove the google ban not being able to read/write your own micro sd card on your own Android device using your own app).
Environment.isExternalStorageManager() can be used to check if the permission is on/off.
As long as you do not try to upload your app to the play store you are fine.
use android:requestLegacyExternalStorage="true" in your Manifest below <application
I am new to Xamarin Android, but have some experience with C# and WinForms. I have a modern Android device using Android 9. I can use the built-in File Manager to see my SD card. I can also use that app to create a folder on my SD card (for example "Test Folder"). What I have not been able to do is access that folder using my C# Xamarin Android code. Should I be able to, or is this frowned upon? Is there a generic solution that will work on other devices that also have an SD card?
The Android.OS.Environment.GetExternalStoragePublicDirectory method does not seem to recognize the presence of the removable, external storage. I have also tried
new Intent(Intent.ActionOpenDocumentTree);
This allows me to "see" the new folder, but I can't seem to do anything with the URI that I get back.
To create Folder in External Storage (if External Storage is available otherwise it creates in internal storage)
public void createMainFolder (){
String myfolderLoc=Environment.getExternalStorageDirectory()+"/"+yourFolderName;
File f=new File(myfolderLoc);
if(!f.exists()) {
if (!f.mkdir()) {
//folder can't be created
} else {
//folder has been created
}
}
}
And to get the path of the folder :
public String getAppmainFolderName(){
return Environment.getExternalStorageDirectory()+"/"+yourFolderName;
}
Don't forget to add Storage Permission in your manifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and check Storage Permission is granted or not before accessing your External Storage (required for android 6.0 and above).
Request App Permission Android Doc.
Hope this will help you. 🙂
I test my application on a virtual nexus 5 with Marshmallow
I got a notification about a virtual sd card being ready and I tried choosing both internal and external storage.
I uploaded a text file to sdcard/Download by dragging and dropping to the emulator.
I added <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> and even <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> to my manifest.
When I try to read a file a sd card using code such as this
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard,"Download/gradle.build");
try {
BufferedReader br = new BufferedReader(new FileReader(file))
...}
I get an open failed... EACCESS - permission denied exception thrown.
Why can't I read a file from the sdcard? Thanks.
Request permission at runtime is a feature added in android version 6.0 The idea is when the app is installed customers just grant permission without knowing the security risk. Dangerous permission must be granted at runtime so hopefully users know the risk, in this case you want to use SD storage because (give reason here). Good luck.
Since you are targetting devices marshmallow or above you have to give permissions at runtime and permissions declared in manifest does not mean anything. So have to give permission like below before accessing any of the file related read or write.
first check if permission already given by checking this
// Assume this Activity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck==PackageManager.PERMISSION_GRANTED){
//this means permission is granted and you can do read and write
}else{
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}
here is permission guide
I have created an android application which downloads images from URLs given and download and save it into my sdcard. The image is to be saved into /mnt/sdcard/TempImages folder. and the image is then loaded into imageview for viewing it in my android activity. Till, today morning the application was working very fine, but from today morning onward, when I try to run the application, the image cannot be viewed in my activity. I have been loading the images from my own web server and I have given full permission for read or write access to the files in the server. So there is no problem from the server side. The problem is from the client side. This is the error log while trying to run the application. How should I add permission for my application in the /mnt/sdcard/TempImages folder for read and write access.
W/System.err(458): java.io.FileNotFoundException: /mnt/sdcard/TempImages/-1267781495 (Permission denied)
Make sure your app has the proper permissions to be allowed to write to external storage:
It should look something like this in your manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
add WRITE_EXTERNAL_STORAGE permission in manifest
Make sure you add the correct permission on your app manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />