前陣子只要升級到Android 4.4後,APP有使用外接SDCard的使用者將面臨一陣哀鴻遍野
你的APP從此就不work了.....原來,Android 4.4 KitKat,Google改變了一些存取外接SDCard的策略
目的是希望每個APP有自己私有的存取路徑,也就是只能固定在/SDCard/Android/data/packageName/底下
以便於當你做Uninstall APP,所有的儲存資料系統才會一併幫你移除
也就是說要在你的packageName下才能使用mkdir這樣的程式指令建立你要的存取路徑與檔案
但前提是,怎樣才能產生這個packageName在/SDCard/Android/data這個路徑下?因為mkdir只能用在packageName下呀
上網google了一下,卻都沒有找到有人說該如何解?
一堆說要root之後改/etc/permission下的platform.xml檔,但我是開發人員,怎麼會讓使用者使用我的app還要先root呢?
甚至還有人說目前只能等goole改API才有辦法再做存取外接SDCard
也是因為這句話,讓我整個思考方向都錯了,開始在想是否可以用非正解的方式來解這個問題
當時我想到的就是是否可以從底層NDK直接下Linux的指令
但實際實作後還是無法在Android 4.4的Linux上正確執行mkdir指令
透過tool adb.exe直接進入手機去看,發現他的存取權限如下:
1
2
3
| shell@K00Y:/storage/MicroSD/Android $ ls -l ls -l drwxrwx--x root sdcard_r 2014-08-22 14:48 data |
也就是說除了root外,能有read和write的權限就只有sdcard_r這個群組的使用者
因此上層APP運行的時候,存取時不確定是用哪個使用者與群組,但一定不是sdcard_r這個群組
因此上層APP運行的時候,存取時不確定是用哪個使用者與群組,但一定不是sdcard_r這個群組
還在思考為什麼同時,就在Android Developer發現一篇針對External Storage的介紹
裡面有一段是這麼說的:
Beginning with Android 4.4, however, you can access both locations by calling getExternalFilesDirs(), which returns a
File
array with entries each location.
進入getExternalFilesDirs()的document文件看,他的描述是:
Returns absolute paths to application-specific directories on all external storage devices where the application can place persistent files it owns. These files are internal to the application, and not typically visible to the user as media.
似乎好像說使用getExternalFilesDirs()這個API就能回傳所有可以存取到的internal/external storage路徑
因此就拿來試試看,發現呼叫這個API後,他自己會在external storage建立這樣的ㄧ個路徑/SDCard/Android/data/packageName/files
也就是說,你要的/SDCard/Android/data/packageName/已經被建出來了 @@"
這樣的話就可以讓你的APP隨意在packageName下建立任何資料夾與檔案了....(OX,浪費我這麼多時間在想怎麼解)
後來試用了一下如果不在Android 4.4他會如何運作,結果發現呼叫這個API後他會carsh = ="
在仔細看了一下document文件,才發現這個API是適用API level 19(Android 4.4.2),之前的版本是不能直接拿來使用的
但卻有一個getExternalFilesDir()跟getExternalFilesDirs()很相似的API,而且適用API level 8(Android 2.2)以後
但在Android4.4以前似乎只會建路徑在primary external filesystem
不過之前的就沒什麼影響了,因為我們可以自己寫程式任意mkdir
也難怪Android Developer會提到說在Manifest加入
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest>
外接存取的權限最多只針對sdk API18以下有效果,API18也就是Android4.4這個設定已經不是那麼重要了
因為API19後Android已經不需要經使用者同意了,APP已經被限定只能隨意存取與寫入自己packageName下的路徑
其他的地方你就休想做存取了,這次事件後,又一次的體會到開發有問題還是要先找Android Developer
很多問題的解法都會在官方的文件中就已經告訴你了....... ~"~