I. Introduction
From Android Q (ie Android 10) to start the application to access external storage of private directory (that is
Context.getExternalFilesDir()
) need not applyREAD_EXTERNAL_STORAGE
orWRITE_EXTERNAL_STORAGE
permission. At the same time, under normal circumstances, even if the application an applicationREAD_EXTERNAL_STORAGE
orWRITE_EXTERNAL_STORAGE
authority, can only access external storage of private directory, if visited other external storage in addition to the private directory, it will throwFileNotFoundException
an exception
Second, the anomalies
1, if your application settings targetSdkVersion = 29
, accessing external non-proprietary directory stored in the android Q phone, even if there is permission to read and write external memory, still will throw a similar following FileNotFoundException
exception:
java.io.FileNotFoundException: /storage/emulated/0/min77/51850812e89ff8ead2002c15ebf417ac: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:496)
at java.io.FileInputStream.<init>(FileInputStream.java:159)
at com.sswl.sdk.utils.Logger.readFileStream(Logger.java:107)
at com.sswl.sdk.utils.Logger.readProterties(Logger.java:82)
at com.sswl.sdk.utils.Logger.loadLogConfig(Logger.java:26)
at com.sswl.sdk.utils.Logger.w(Logger.java:67)
at com.sswl.sdk.network.http.NetworkRequest.doPostRequest(NetworkRequest.java:68)
at com.sswl.sdk.network.http.NetworkRequest.doPostRequest(NetworkRequest.java:47)
at com.sswl.sdk.network.http.NetworkRequest.doRequest(NetworkRequest.java:35)
at com.sswl.sdk.network.http.NetworkRequest.doRequest(NetworkRequest.java:28)
at com.sswl.sdk.network.http.HttpRequestAsyncTask.doInBackground(HttpRequestAsyncTask.java:65)
at com.sswl.sdk.network.http.HttpRequestAsyncTask.doInBackground(HttpRequestAsyncTask.java:21)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7419)
at libcore.io.IoBridge.open(IoBridge.java:482)
... 16 more
Third, the exception analysis
1, Android Q only allows applications to read private directory of your external storage. This does not require external memory read and write permissions;
2, when the application after being granted permission to read and write external memory, and can only read files in the following directory: 存储在MediaStore.Images的图片
, 存储在MediaStore.Video的视频文件
, 存储在MediaStore.Audio的音频文件
3, and if you want to read external storage file other than the above, it will throw FileNotFoundException
an exception
Fourth, the solution
1, a program: the application is set to 29 or less targetSdkVersion
2, Scheme II: Application of the AndroidManifest.xml node setting android: requestLegacyExternalStorage = "true"
<!-- This attribute is "false" by default on apps targeting
Android 10 or higher. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
Fifth, the extension issue
1. If using the program two to solve the above problems, the package is normally no problem, but if the use apktool 反编译回编译
occurs 找不到android:requestLegacyExternalStorage属性异常
, the latest version is currently apktool 2.4.0,
estimates subsequent versions will be compatible with Q Android
2, Solution:
1) In the first Android Studio, a new API 29 of the simulator
2) running the created simulator
3) using the command adb pull the framework-res.apk extracted from local simulator computer system / framework
adb pull system/framework/framework-res.apk C:\Users\Administrator.USER-20190314H
O\Desktop\1
4) from the simulator to pull out of the framework-res.apk renamed 1.apk
, and then copied to: C:\Users\当前用户名\AppData\Local\apktool\framework
directory, and then re-compiled with apktool back to
[Note]: If there androidQ phone, you can also directly from the phone Pull