I try to recive from android the public music directory by:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
At my android 4.2 device it's /storage/emulated/0/Music and works well.
At android 5.0.1 device it's /storage/sdcard0/Music and readonly.
Why? I know that at 4.4 was restricted to write to the internal memory but it is public director, isn't it?
I'm not sure but on developer.android.com it is stated:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Beginning with Android 4.4, these permissions are not required if you're reading or writing only files that are private to your app.
It is possible that not private location (to your app) still needs this permission?
By the way despite of this statment, I had to add this permission to work well in my app on Android 5.0.1.
Problem was that device sequrity politic is prevent access to Music directory to non system signed applications by emulated/0/Music (emulated file system). Can access to it by /data/0
Related
Mkdirs() function is not working on Android 11. every thing is working fine on Android 10 and lower.
Code:
***String path =Environment.getExternalStorageDirectory().getAbsolutePath() + "/My_directory/";
File temp_file = new File(path);
if (!temp_file.exists()){
Boolean can_create= temp_file.mkdir();
}***
the above code returns true in case of Android 10 or lower. but returns false in case of Android 11.
Manifest permissions:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Noting that runtime permission is considered for same (READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE).
Manifest application:
<application
android:requestLegacyExternalStorage="true"
The only way I am able to write in external storage is using getExternalFilesDir() but this is not the root directory.
according to this developer website, we can't create folders any more in the root directory!
Questions so far after checking this:
1- Is it confirmed that in Android 11 we can't create any folder on the root directory? any work around?
2-If yes, what is the way forward to save data in external storage, excluding getExternalFilesDir() ?
3- Why android:requestLegacyExternalStorage="true" is not working?
***String path =Environment.getExternalStorageDirectory().getAbsolutePath() + "/My_directory/";
You cannot create directories in root of external storage on Android 11 devices.
Instead create your own directories in one of the public directories of external storage.
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "My_directory");
Why android:requestLegacyExternalStorage="true" is not working?
android:requestLegacyExternalStorage is no longer works on Android 11+. It is just a helper on Android 10 to give developers more time before migrating to scoped storage. On scoped storage, you need to use URI for creating, renaming, moving files, etc. Thus java.io.File is almost useless now.
Is it confirmed that in Android 11 we can't create any folder on the root directory? any workaround?
No workaround.
BTW, to reduce scoped storage complexity, I've created a library named Simple Storage. It works across API levels.
I uploaded several files to folder "/sdcard/Books/LadySusan" on my android emulator. When I check if file in folder exist, expression
new File("/sdcard/Books/LadySusan/ladysusan_1_austen_64kb.mp3").exists()
returns true, file exists in folder, but when I use
new File("/sdcard/Books/LadySusan").listFiles()
it returns empty array, not null but File[0]. I have permissions to read files from SD card
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and code to request them. Any idea what can be wrong?
Finally I found. It seems to me there is a bug in Android SDK (10.0+). When I started emulator with Android 9.0, it returns files as I expected.
It is not a bug. As of Android 10, external storage access is scoped to app files and media.
This means that your application can only access the files in the app-specific directory (which can be retrieved in code with getExternalFilesDir()) or media in the media store.
As long as you target an Android version lower than API level 30 (Android 11) you can get away with accessing the external storage via the following permission:
<application android:requestLegacyExternalStorage="true" ... >
I have inherited an Android project without having much idea about the development on this platform. First I want to explain why I want to debug a system app if you have any idea about the problem:
This project is a system app and has to change Settings.Secure.LOCATION_MODE's value. Now the customer has problems with this feature and wants to solve it.
The device is Android 5.1 with manufacturer's special permissions and the APK file is in system/priv-app folder.
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> is in AndroidManifest.xml.
I get this exception: "Permission denial: writing to secure settings requires android.permission.WRITE_SECURE_SETTINGS".
In the main actitvity this condition is checked:
public boolean isSystemApp() {
return (getApplicationInfo().flags & (ApplicationInfo.FLAG_SYSTEM |
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
}
So I want to debug the system app running it in the system/priv-app to have privileges. Is it posible?
We have an app that uses external storage to store some temporary files: images, binary data. The code for that has been working for a few years without big changes until recently. On Android Q it doesn't work:
File f = new File(Environment.getExternalStorageDirectory().toString() + File.separator + MainActivity.APP_DIR)
f.mkdirs();
// do sth with f
The mkdirs now returns just false.
Required permission is provided in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
The code works fine on previous versions of Android. Is there some system level change to this type of access? If so, what is the workaround?
There was huge privacy change in android Q by introducing Scoped Storage.
Since Q beta 4 it's possible to opt-out of that feature by:
targeting API 28 (or lower)
using requestLegacyExternalStorage manifest attribute (while targetting API 29):
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
edit: as mentioned in other answer this does not work if app is targeting API 30 - Android 11 devices will ignore legacy storage flag.
edit 2: heads up for anyone planning to publish on play store - soon usage of this flag will be restricted (new and updated apps won't be accepted) unless its required for core functionality (e.g. file manager)
UPDATE: Since Android 11 scoped storage is enforced. Apps that target Android 10 (API level 29) can still request the requestLegacyExternalStorage attribute. This flag allows apps to temporarily opt-out of the changes associated with scoped storage, such as granting access to different directories and different types of media files. After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage flag.
In API level 29 direct access to shared/external storage devices is deprecated. When an app targets Build.VERSION_CODES.Q, the path returned from getExternalStorageDirectory() method is no longer directly accessible to apps.
Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.
It's a best practice to use scoped storage unless your app needs access to a file that doesn't reside in the app-specific directory.
Those who face the issue with managing files in Android-Q may read through this article to know further.
In the new Android update API 30 you can only write in your app-specific files
File directory = new File(context.getFilesDir(), "YOUR_DIR");
directory.mkdirs();
or in the external storage of your app Android/data
File directory = 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
I'm trying to read from a file in Unity that I've written to the Downloads folder in Android.
I'm writing the file natively with another apk and I've copied the url that I wrote to: "/storage/emulated/0/Download/file" but when I try File.Exists(thatUrl) it's returning false.
So apparently the permission: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> means something different in Unity than it does it the native Android SDK. Having that permission allows you to read from the INTERNAL storage as well as the external.