为什么我需要在Android上使用棒棒糖getExternalCacheDir()的WRITE_EXTERNAL_STORAGE许可? [英] Why do I need the WRITE_EXTERNAL_STORAGE permission with getExternalCacheDir() on Android Lollipop?
问题描述
我的应用程序写入(并读取)高速缓存文件getExternalCacheDir()位置。 Android的棒棒糖(API 21)之前,我一直在使用这个权限成功:
My app writes (and reads) cache files to the getExternalCacheDir() location. Before Android Lollipop (API 21) I've been using this permission with success:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
该maxSdkVersion是因为有不应API V18后需要这个权限:
<一href=\"http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE\" rel=\"nofollow\">http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE
但在Android棒棒堂(5.0)我收到像这样的访问权限(与我的日志输出,显示使用的实际路径):
But on Android Lollipop (5.0) I'm getting an access permission like so (with my log output to show the actual path used):
11-19 13:01:59.257 4462-4541/com.murrayc.galaxyzoo.app E/android-galaxyzoo﹕ createCacheFile(): IOException for filename=/storage/emulated/0/Android/data/com.murrayc.galaxyzoo.app/cache/52
java.io.IOException: open failed: EACCES (Permission denied)
at java.io.File.createNewFile(File.java:941)
at com.murrayc.galaxyzoo.app.provider.ItemsContentProvider.createCacheFile(ItemsContentProvider.java:528)
我看到这个无论是在模拟器和我的Nexus 4已经改变的东西,或者是我错了一直在做什么?我只是想访问自己的应用程序的缓存。
I see this both in the emulator and on my Nexus 4. Has something changed, or was I doing something wrong all along? I just want to access my own app's cache.
更新:我现在看到这只是我的设备(的Nexus 4运行标准的Android 5.1.1,它甚至有一个新鲜的Android复燃,因为我第一次有这个问题)上。我再也看不到这在模拟器中 - 当然系统映像已经更新好几次
Update: I now see this only on my device (Nexus 4 running the standard Android 5.1.1, which has even had a fresh Android reflash since I first had this problem). I no longer see this in the emulator - of course the system images have been updated several times.
推荐答案
我们已经在看到API 21(棒棒堂)相同的行为是Nexus 5:
We've seen same behaviour on API 21 (Lollipop) on a Nexus 5:
java.io.FileNotFoundException: /storage/emulated/0/Android/data/[package name]/cache/http/journal.tmp: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:456)
at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
at com.android.okhttp.internal.DiskLruCache.rebuildJournal(DiskLruCache.java:346)
at com.android.okhttp.internal.DiskLruCache.open(DiskLruCache.java:239)
at com.android.okhttp.HttpResponseCache.<init>(HttpResponseCache.java:140)
at android.net.http.HttpResponseCache.install(HttpResponseCache.java:199)
...
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4518)
at android.app.ActivityThread.access$1500(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Posix.java)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at libcore.io.IoBridge.open(IoBridge.java:442)
at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
at com.android.okhttp.internal.DiskLruCache.rebuildJournal(DiskLruCache.java:346)
at com.android.okhttp.internal.DiskLruCache.open(DiskLruCache.java:239)
at com.android.okhttp.HttpResponseCache.<init>(HttpResponseCache.java:140)
at android.net.http.HttpResponseCache.install(HttpResponseCache.java:199)
...
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4518)
at android.app.ActivityThread.access$1500(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
直到谷歌推Android的5.0到AOSP我们将不能够如果制定出一个错误或故意(但无证)的变化,但我已经提出了这个错误不管:
的https://$c$c.google.com/p /安卓/问题/细节?ID = 81357
添加WRITE_EXTERNAL_STORAGE许可prevents抛出上述异常,但需要最终用户许可升级现有的应用程序。由于我们的应用程序不使用这个权限,我们不希望它,我们正在回落添加到使用内部缓存所有除奇巧设备。
Adding WRITE_EXTERNAL_STORAGE permission prevents the above exception being thrown, but will require end user permission to upgrade existing apps. Since our app doesn't use this permission and we don't want to add it, we're falling back to using internal cache for all except KitKat devices.
顺便说一句,我这个发现一个有趣的背景,在奇巧引入的变化:的 http://www.doubleencore.com/2014/03/android-external-storage/
As an aside, I found this an interesting background to the changes introduced in KitKat: http://www.doubleencore.com/2014/03/android-external-storage/
这篇关于为什么我需要在Android上使用棒棒糖getExternalCacheDir()的WRITE_EXTERNAL_STORAGE许可?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!