2016-10-03 74 views
0

自從KitKat以來,我在Android和SD卡上讀了很多東西。但最終,我找不到明確的全球答案,所以我會試着從你們那裏得到相關的答案。有沒有什麼辦法可以在Android上的SD卡上隨意寫字?

我想編寫一個文件,文本文件,在SD卡上的任意位置。

讓我們專注於Android的6這個簡單的例子。寫權限出現在清單

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

我有這樣的helper方法

private void writeFile(File parent) 
{ 
    try 
    { 
     File f = new File(parent, "test.txt"); 
     OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(f)); 
     outputStreamWriter.write("test"); 
     outputStreamWriter.close(); 
     Log.i(TAG, "File created : " + f.getAbsolutePath()); 
    } 
    catch (IOException e) 
    { 
     Log.e(TAG, "File write failed", e); 
    } 
} 

而且在測試活動:

if (Build.VERSION.SDK_INT >= 23) 
{ 
    if (ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED 
     || ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) 
    { 
     ActivityCompat.requestPermissions(MainActivity.this, new String[] { 
      android.Manifest.permission.WRITE_EXTERNAL_STORAGE, 
      android.Manifest.permission.READ_EXTERNAL_STORAGE }, 1); 
    } 
    else 
    { 
     File path = getExternalFilesDirs(Environment.DIRECTORY_PICTURES)[1]; 
     writeFile(path); 

     path = getExternalFilesDirs(null)[1]; 
     writeFile(path); 

     writeFile(new File("/storage/3635-3533/")); 
    } 
} 

/\ 是爲第三測試的路徑!通過檢索正確的SD卡路徑硬編碼在主體這裏 /!\

首先推出,permission asked,一切正常(對不起法國設備)

第二次發射,這裏是結果

10-03 12:40:10.414: I/TESTSDCARD(26006): File created : /storage/3635-3533/Android/data/com.example.testsdcard/files/Pictures/test.txt 
10-03 12:40:10.415: I/TESTSDCARD(26006): File created : /storage/3635-3533/Android/data/com.example.testsdcard/files/test.txt 
10-03 12:40:10.426: E/TESTSDCARD(26006): File write failed 
10-03 12:40:10.426: E/TESTSDCARD(26006): java.io.FileNotFoundException: /storage/3635-3533/test.txt: open failed: EACCES (Permission denied) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at libcore.io.IoBridge.open(IoBridge.java:459) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at java.io.FileOutputStream.<init>(FileOutputStream.java:87) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at java.io.FileOutputStream.<init>(FileOutputStream.java:72) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at com.example.testsdcard.MainActivity.writeFile(MainActivity.java:61) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at com.example.testsdcard.MainActivity.onCreate(MainActivity.java:50) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.app.Activity.performCreate(Activity.java:6367) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2397) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2504) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.app.ActivityThread.access$900(ActivityThread.java:165) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.os.Handler.dispatchMessage(Handler.java:102) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.os.Looper.loop(Looper.java:150) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at android.app.ActivityThread.main(ActivityThread.java:5546) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at java.lang.reflect.Method.invoke(Native Method) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684) 
10-03 12:40:10.426: E/TESTSDCARD(26006): Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at libcore.io.Posix.open(Native Method) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) 
10-03 12:40:10.426: E/TESTSDCARD(26006): at libcore.io.IoBridge.open(IoBridge.java:445) 
10-03 12:40:10.426: E/TESTSDCARD(26006): ... 16 more 

正如你所看到的,使用getExternalFilesDirs工作兩個測試(不要驚訝,它應該到) 但第三個嘗試在SD卡的根目錄寫入失敗。

我做錯了嗎?有什麼方法可以執行此操作?希望不使用存儲訪問框架,這在我的應用上下文中對我來說是一個真正的痛苦。

旁邊,並存儲訪問框架允許沒有一個巨大的代碼量上的文件執行每個基本操作(寫,刪除,重命名......)?

+0

沒有根目錄,你沒有對'/ storage'的寫入權限 –

+0

你是指SD卡? – ToYonos

+0

嗯,有些設備沒有「SD卡」,所以我只是指文件系統 –

回答

1

我想寫一個文件,一個文本文件,在SD卡上的任意位置。

這對於Android 4.4+以上的設備是不可能的,除了可能在根設備上。

寫入權限存在於清單

即許可爲外部存儲設備。外部存儲不是可移動存儲。

難道我做錯了?

是的,只要您沒有對可移動存儲上任意位置的讀/寫訪問權限。

Storage Access Framework是否允許在沒有大量代碼的情況下對文件執行每個基本操作(寫入,刪除,重命名...)?

除了你知道你會認爲「大量的代碼」是什麼,沒有人會。一般來說,如果您獲得用戶對一段內容(或其容器)的許可,則可以執行您在DocumentFile上看到的各種操作。

+0

那麼文件管理器如何在沒有root權限的情況下執行這樣的操作呢?他們都使用DocumentFile方法? – ToYonos

+0

@ToYonos:你將不得不問這些特定應用程序的開發人員。請注意,設備附帶的文件管理器通常可以直接訪問可移動存儲。 – CommonsWare

+0

我用'DocumentFile'做了一些測試,它可以用於文件創建/修改。我猜想一些嚴重的重構是可以預期的:) – ToYonos

相關問題