requestLegacyExternalStorage is not working in Android 11 - API 30 - java

Google has introduced some changes recently related to storage APIs in API 29 like scoped storage and we opted out by adding 'requestLegacyExternalStorage=true' in Manifest. But now when I targetSdkVersion 30, this no longer seems to work. Some of the files in the download directories were not listing (File.listFiles) after this change.

But now when I targetSdkVersion 30, this no longer seems to work
That is correct. Android 11 (API 30+) requestLegacyExternalStorage=true does nothing and you can no longer "opt-out". It was available in Android 10 to give developers a transition/grace period to be able to migrate to the scoped storage model.
Option 1: Migrate data in your app whilst still targeting API 29, then once you're migrated data is compatible with scoped storage you should be able to release an update targetting API 30 - https://developer.android.com/training/data-storage/use-cases
This can come with its own problems if users skip this version and updates directly from a previous version to the latest and you're stuck with un-migrated data you can't access.
Option 2: It seems that Google sees this obvious caveat and has included a preserveLegacyExternalStorage=true option when targetting API 30 to allow you to migrate data. https://developer.android.com/reference/android/R.attr#preserveLegacyExternalStorage
Going forward you can reference this table for deciding what storage "framework" to use based on the use-case: https://developer.android.com/training/data-storage
There is a potential that some apps simply won't be able to successfully migrate, based on how they interacted with the File API as Google's solution will not encompass all current use-cases and there might not be a migration path.
For instance, I released an app a couple of years ago that allowed users to update album artwork using MediaStore and ContentResolver to update the data for the album artwork image - this was stored in shared storage. Having looked at the Android 10+ AOSP MediaProvider source code it seems that apps that used to use MediaStore to update album artwork to point to a data file no longer works, simply because the MediaProvider internally creates its own artwork in a hidden .thumbnails folder looking directly at the mp3's and using a MediaExtractor, and never references the ContentValues that were inserted to reference the artwork. So even though you can update the artwork yourself, query the MediaStore for it and see it, other apps have to use ContentResolver#loadThumbnail in API 29+ that does not reference your updated values and either creates an artwork lazily, or picks the already generated file in the .thumbnails folder. Obviously, none of this is documented, and I got a massive backlash to my app with negative reviews, yet these changes were breaking changes and completely out of my control and took me looking through AOSP source code to find that Android had fundamentally changed behaviour.
(This wasn't a rant, but an example of how these changes offered no migration path because of fundamental undocumented behaviour to AOSP).

As stated in https://developer.android.com/about/versions/11/privacy/storage there are some changes regarding storage on Android 11:
Android 10 devices
requestLegacyExternalStorage will continue to work regardless of target sdk
Android 11 devices
new installation targetting sdk 29: requestLegacyExternalStorage value is respected
new installation targetting sdk 30: requestLegacyExternalStorage is always false
upgrade from targetting sdk 29 to 30: if preserveLegacyExternalStorage is set then requestLegacyExternalStorage is true (this is pure migration case and this state won't be preserved should user uninstall/reinstall the app)
You're pretty much forced to implement scoped storage at this point. Unless you're ready to migrate just keep targetting sdk 29 as there's no way to enforce legacy storage on Android 11 devices with target sdk 30.
update: play store requires target sdk 30 as of August 2021

Don't do this until early 2021 (said by google):-
If you want to target to android 11, you should use the MANAGE_EXTERNAL_STORAGE permission.
Visit this page for more details: https://developer.android.com/training/data-storage/manage-all-files

Applications that run on Android 11 but target Android 10 (API level 29) can still request the requestLegacyExternalStorage attribute. This flag allows applications 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 updating application to target Android 11, the system ignores the requestLegacyExternalStorage flag.

No need to call "requestLegacyExternalStorage=true" which is not working for Android 11+.
There is a new update in https://github.com/apache/cordova-plugin-media to cover the saving file path issue for android 11+.
If you update "/platforms/android/app/src/main/java/org/apache/cordova/media/AudioHandler.java" and "/platforms/android/app/src/main/java/org/apache/cordova/media/AudioPlayer.java" in your project, then it should be working.
https://raw.githubusercontent.com/apache/cordova-plugin-media/4093f7e14fe65f94ffbef072ed188a0205e78a59/src/android/AudioHandler.java
https://raw.githubusercontent.com/apache/cordova-plugin-media/4093f7e14fe65f94ffbef072ed188a0205e78a59/src/android/AudioPlayer.java

Related

android SDK version

How can I fix this problem?
Your 1 version code com.fass.vpnn app includes the SDK
com.unity3d.ads:unity-ads, which collects personal or sensitive data,
including but not limited to Advertising ID, Android ID identifiers,
or an SDK that one of your libraries uses . Persistent device
identifiers cannot be linked to other personal and sensitive user data
or resettable device identifiers as described in the User Data Policy.
Starting at midnight (UTC) on January 11, 2023, new app versions
containing SDK versions that do not comply with the User Data Policy
may be blocked from being made available. If the SDK is available from
your provider, you may want to consider upgrading to a
policy-compliant version of this SDK that does not contain the
offending code or removing it from your app.
Depending on your SDK provider, you can downgrade to 4.0.1 and/or
contact your SDK provider to see if a suitable version will be
available later. Google cannot endorse or recommend third-party
software.
ACTION REQUIRED: Install a new compatible version AND disable the
non-compliant version.
Read the User Data policy for more details and learn how to submit an
updated app for review here.
If you've reviewed the policy and think our decision may have been
incorrect, please contact our policy support team.
I've read some users' comments about this, but they didn't work for me.

Unable to share media file outside app with our app in Redmi device for android 11

Whenever we share a media file with our app, that file we should have access to display, but in the Xioami device we are unable to access those files, whereas for other device like vivo, oppo, realme, oneplus etc. is working fine and able to display or read those file.
For android 10 version it's working fine in redmi device but for android 11 (SDK 30) it's not working.
Even popular app like Whatsapp, facebook, Instagram, Telegram and Singal also unable to attach file from out side the application.
Can anyone please give your feedback and help how we can fix this problem in future.
Below is my code to get media uri
String action = getIntent().getAction();
String type = getIntent().getType();
if (Intent.ACTION_SEND.equals(action) {
if (type.equals("text/plain")) {
String textMessage = getIntent().getStringExtra(Intent.EXTRA_TEXT);
} else if(type.startsWith("image/")) {
Uri imageUri = (Uri) getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
String path = imageUri.getPath();
} else if(type.startsWith("video/")) {
Uri videoUri = (Uri) getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
String path = videoUri.getPath();
}
}
We also have used custom parser to get file path from uri but didn't work.
File provider also included in xml directory.
If this is only happening with targeting API 30 and was working fine before with API 29, then it may be due to one of the changes introduced with API 30, as listed by Google. In particular, from your description, it may be because of APP_DATA_DIRECTORY_ISOLATION.
As https://developer.android.com/about/versions/11/privacy/storage#other-private-dirs explains:
Android 9 (API level 28) started to restrict which apps could make the files in their data directories on internal storage world-accessible to other apps. Apps that target Android 9 or higher cannot make the files in their data directories world-accessible.
Android 11 expands upon this restriction. If your app targets Android 11, it cannot access the files in any other app's data directory, even if the other app targets Android 8.1 (API level 27) or lower and has made the files in its data directory world-readable.
and
On Android 11, apps can no longer access files in any other app's dedicated, app-specific directory within external storage.
How can you test if it is APP_DATA_DIRECTORY_ISOLATION or some other API level 30 feature that is related to the issue (at least on the Xiaomi device)? You can actually built a debug app targeting API level 29 and toggle on/off individual API level 30 features to check, as explained in My Android app is not working properly once I set targetSDK as API 30; how do I figure out the reason(s)?
Why only on Xiaomi and not other devices? Maybe related to differences in implementation, but if you can at least test the API level 30 feature changes on the Xiaomi device, that can help in the troubleshooting.

How to take access to internal storage in android 11?

I want to access full access of internal storage but I have tried so many things didn't able to access in android 11. then I used solid explorer also available in the play store which is giving full access to internal storage. can someone tell me how to achieve this in android 11.
You have two options, either acquire MANAGE_EXTERNAL_STORAGE which needs some approval from google play AFAIK!
Or set the targetSdk to 29 and use requestLegacyExternalStorage
https://developer.android.com/about/versions/11/privacy/storage
Apps that run on Android 11 but 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.
But remember, you can use targetSdk 29 until August 2021 (November if it's an update) and after that you have to targetSdk 30
https://developer.android.com/distribute/best-practices/develop/target-sdk
In other words, Google is trying to prevent apps from accessing external storage for privacy concerns. I guess we should follow Google's guidelines (forget about the user's files)

Q: Android Project Minimum SDK - API-15 (ICS) versus API-16 (JellyBean)

Hello fellow Android Devs!
My Question/Topic today is about the "Minimum SDK" we set for our Projects..
For years now, "API-15" (IceCreamSandwich/4.0.3) has been typical, covering 97.4% of users.
However, I've recently noticed now that "API-16" (JellyBean 4.1) has caught up, at 95.2%!
Over the past few years, the percentages were MUCH further apart, making API-15 the go-to.
SO, MY QUESTION IS:
Are there any advantages to setting API-16 as my Project's "Minimum SDK", instead of API-15?
For example, less need for certain support libs, or better compatability with anything, etc. etc.?
Basically, ANY reason at all why choosing API-16 as my "Minimum SDK" might benefit anything?
..Thoughts?
I've worked on apps with both 15 and 16 as the minSdkVersion. I would recommend a minApi of 16, particularly if you use SQLite.
Api 16 has:
SQLite 3.7.11. You now have setForeignKeyConstraintsEnabled for your SQLiteDatabase.
Up navigation. Api 16 supports android:parentActivityName in the manifest, so you don't also have to have metadata tags.
Font families in xml. For your password EditText, you can now set android:fontFamily=sans-serif, so it no longer defaults to monospace.
The drawback is that the Samsung Galaxy S2 runs on API 15, so if this is an important demographic for you, you'd be missing out on them if you use minApi 16. All of my new projects are minApi 16.
Android 4.1 (API 16) has Has offline voice recognition. Offline voice recognition enables you to perform voice actions, like dictating texts or using various voice commands, without an internet connection.

How to update Android OS on the device through an App

Is there any way to update the Android OS through an App(Using Android API or any other API/) after checking if a newer Android version is available in the market/Playstore
The Use Case required to be supported here is as follows:
The App starts and checks the version of the installed Android OS
It then finds the version of available Android OS in the
Playstore/other repository for that device
Then it compares the two version and if the available version is
newer, then it installs the new Android version on the device
How can it be implemented , especially the third point ? I do not want to root the device for that, so if there is any way to achieve this, please help ....
There is no API. If your device has an update feature built in (most do), you can decompile the update service and see how it works. If your device does not have an update feature, then you can look at custom ROMs for your device. Once you get ahold of a ROM or an update.zip you want to use, the process cannot be done automatically. The updating takes place in the system recovery mode where the user will have to select the .zip to update. However, if you can decompile and figure out how your manufacturer's update service works, maybe you can pull off an automated process.
There aren't any tutorials or documentation for this, as it is 100% dependent on phone model/OS. You can probably find a flashable ROM for your device, however, but the process is rarely automated. Actually, take a look at ROM Manager in this case, it is a somewhat automated upgrade app. I tried it before and it bricked my phone. Good luck
You would need to know where to ask if there is a newer version. And then is there an upgrade available for that particular device. At that point you could broadcast a request to update. Does not the device know when an update is available?
For updating your android version you would need
Custom Android on you device.(Some more info)
Rooted device.why need rooting?
Now for installing we would need to flash ROM.You would also need to have check for version of the OS available, which depend upon your logic .Generally Samsung ,Sony they use custom android and the updates are pushed over app center( or something like that,not much knowledge) in your case it may be any cloud service or server to check version for your custom android.
When we have a new version, after user accepts to upgrade, a new img file would be downloaded to your device which would be used to upgrade the OS.Please note you would also need a recovery backup method too.There are some Commands that can be used to extract and download the OS through your code.
I haven't implemented it yet but this is the procedure i could find.
I hope this would help others.
UPDATE
I have got some new information about how can we initiate the update through code. the Link and there's this another link that can be great help.
In both the examples they are using SystemRcovery class with intallerPackage API.

Categories

Resources