2017-05-03 145 views
3

ContextCompat.getExternalFilesDirs(context, null)說:所有的外接存儲設備,其中應用程序可以將其擁有持久的文件爲什麼有些ContextCompat.getExternalFilesDirs無法訪問?

返回絕對路徑,特定於應用程序的目錄。

例如一個華爲Honor運行Android 5.1.1返回來自該方法執行以下操作:

/storage/emulated/0/Android/data/my.package.name/files 
/storage/sdcard1/Android/data/my.package.name/files 

第二目錄是可移動SD卡。但是,如果我試圖讀取或寫入該目錄,我會得到一個例外:android.system.ErrnoException: open failed: EACCES (Permission denied)

該應用程序確實有WRITE_EXTERNAL_STORAGE。這在運行Android 4.4.4的三星Galaxy Note 4上運行得很好。這與Android 6.0的可選許可無關,因爲這是5.1.1上顯示的問題。

該API說the application can place persistent files it owns但它似乎並非如此。

我也聽過其他設備的報告,包括更多的現代三星設備。這僅僅是原始設備製造商沒有正確實施,或者是有什麼我錯過了Android的複雜的存儲框架?

這是一些代碼,將在這個和一些設備上演示這一點。

File removable = ContextCompat.getExternalFilesDirs(context, null)[1]; 
if (removable.exists() && removable.canRead() && removable.canWrite()) { 
    File test = new File(removable, "test"); 
    test.createNewFile(); // Throws the exception mentioned above 
} 

任何嘗試在該目錄中創建,移動mkdir文件都失敗。

+0

「如果我試圖讀取或寫入到該目錄」 - 該目錄?你列出他們中的兩個。 「該應用程序確實有WRITE_EXTERNAL_STORAGE」 - 這與Android 4.4+上的這些位置無關。 – CommonsWare

+0

糟糕。上面更新。第二個,這是一個可移動的SD卡。 – cottonBallPaws

+0

那麼,你應該有讀/寫訪問權限。您可能會考慮發佈失敗的代碼以及完整的堆棧跟蹤。恕我直言,更有可能的是,製造商將可拆卸存儲裝置拆除而不是外部存儲裝置。 – CommonsWare

回答

1

好吧,我包你的代碼在本次活動:

package com.commonsware.myapplication; 

import android.app.Activity; 
import android.os.Bundle; 
import android.support.v4.content.ContextCompat; 
import android.util.Log; 
import android.widget.Toast; 
import java.io.File; 
import java.io.IOException; 

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    File removable = ContextCompat.getExternalFilesDirs(this, null)[1]; 
    if (removable.exists() && removable.canRead() && removable.canWrite()) { 
     File test = new File(removable, "test"); 
     try { 
     test.createNewFile(); // Throws the exception mentioned above 
     } 
     catch (IOException e) { 
     Log.e(getClass().getSimpleName(), "Exception creating file", e); 
     Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show(); 
     } 
    } 
    } 
} 

它運行在華爲Honor 5X優良,運行Android 6.0.1:

$ adb shell ls -al /storage/1A30-3598/Android/data/com.commonsware.myapplication/files 
-rwxrwx--x u0_a29 sdcard_rw  0 2017-05-03 18:02 test 

所以,我的猜測是,這是設備特定的不兼容性。

+0

似乎這樣...然後... – cottonBallPaws

+0

@CommonsWare看到我的答案是這樣的問題,像 – Grendel

0

由於多種原因,我想詢問@CommonsWare如何在沒有ArrayIndexOutOfBoundsException的情況下運行代碼:length = 1; index = 1錯誤需要將[0]設置爲[0]我們已經測試了這個概念,現在有一段時間來編寫一種方法,讓用戶選擇內部存儲或外部存儲有人可以解釋這是如何工作的或爲什麼它不工作我們 以上回答需要格式化,這樣

 File removable = ContextCompat.getExternalFilesDirs(this,null)[0]; 
    if (removable.exists() && removable.canRead() && removable.canWrite()) { 

     THE_PATH = String.valueOf(removable); 
     THE_PATH = THE_PATH + "/Documents/"; 

    }else { 
     Toast.makeText(getApplicationContext(),"NO SD CARD", 
    Toast.LENGTH_LONG).show(); 

    } 
+0

這不提供一個問題的答案。要批評或要求作者澄清,請在其帖子下方留言。 - [來自評論](/ review/low-quality-posts/18983815) –

+0

如果您有新問題,請點擊[Ask Question](問問題)(https://stackoverflow.com/questions/ask)按鈕。如果有助於提供上下文,請包含此問題的鏈接。 - [來自評論](/ review/low-quality-posts/18983815) –

相關問題