2017-05-03 103 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) –

相关问题