2014-11-19 15 views
9

Meine App schreibt (und liest) Cache-Dateien in den Speicherort getExternalCacheDir(). Bevor Android Lollipop (API 21) Ich habe mit dieser Berechtigung mit Erfolg:Warum benötige ich die Berechtigung WRITE_EXTERNAL_STORAGE mit getExternalCacheDir() auf Android Lollipop?

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" /> 

Die maxSdkVersion ist da, weil diese Berechtigung nicht nach API v18 benötigt werden soll: http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE

Aber auf Android Lollipop (5,0) ich erhalte eine Zugriffsberechtigung wie so (mit meinem Logausgabe den tatsächlichen Pfad zu zeigen, verwendet wird):

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) 

ich das sehen sowohl im Emulator und auf meinem Nexus 4. Hat sich etwas verändert, oder War ich etwas wron g die ganze Zeit? Ich möchte nur auf den Cache meiner eigenen App zugreifen.

Update: Ich sehe das jetzt nur auf meinem Gerät (Nexus 4 mit dem Standard Android 5.1.1, die sogar eine frische Android Reflash hatte, seit ich dieses Problem hatte). Ich sehe das nicht mehr im Emulator - natürlich wurden die Systembilder mehrmals aktualisiert.

+0

Wenn Sie das android nicht hinzufügen: maxSdkVersion = „18“ Eigenschaften es dann funktionieren? –

+0

Ja. Ich muss immer WRITE_EXTERNAL_STORAGE anfordern, damit dies funktioniert. Ich frage mich, ob es eine Möglichkeit gibt zu sagen, dass es für <18 but > 20 benötigt wird, wenn es wirklich für 21 (Lollipop) benötigt wird. – murrayc

+0

Ja gemäß Dokumentation Ab API-Stufe 19 ist diese Berechtigung nicht erforderlich, um Dateien in Ihren anwendungsspezifischen Verzeichnissen zu lesen/schreiben, die von getExternalFilesDir (String) und getExternalCacheDir() zurückgegeben werden nicht ohne diese Erlaubnis arbeiten. –

Antwort

5

Wir haben gleiches Verhalten auf 21 (Lollipop) API auf einem 5 Nexus gesehen:

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) 

Bis Google Android Push 5.0 zum AOSP werden wir nicht in der Lage sein, wenn sie einen Fehler zu trainieren oder absichtlichen (aber ohne Papiere) zu ändern, aber ich diesen Fehler unabhängig angehoben haben: https://code.google.com/p/android/issues/detail?id=81357

Hinzufügen WRITE_EXTERNAL_STORAGE Erlaubnis, die oben genannte Ausnahme geworfen verhindert, sondern benötigt eine gesonderte Genehmigung Endbenutzer bestehende Anwendungen zu aktualisieren. Da unsere App diese Berechtigung nicht verwendet und wir sie nicht hinzufügen möchten, verwenden wir den internen Cache für alle Geräte außer KitKat.

Als Nebenwirkung, fand ich dies ein interessanter Hintergrund die in KitKat eingeführten Änderungen: http://www.doubleencore.com/2014/03/android-external-storage/

+0

Ich schätze die Bestätigung, dass ich nicht die einzige mit diesem Problem bin, aber das scheint nur eine Neuausgabe des Problems und keine Antwort zu sein. – murrayc

+0

@murrayc Ich habe auch den Fehler mit Google angesprochen, obwohl es natürlich zu spät war, um Lollipop zu reparieren, da es bereits in der Wildnis war.Der Fallback, nur internen Cache zu verwenden, war für unsere Bedürfnisse ausreichend. – fingertricks

+0

Ja, danke. Welches Zeichen hast du, dass sie es repariert haben, zu spät oder nicht? – murrayc