Android中的EACCES权限被拒绝

时间:2012-10-12 06:51:18

标签: android sd-card

在外部SD卡中写入文件时,我收到错误EACCESS权限被拒绝。我已经设置了权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 但是,当我读取文件时,我成功地能够读取它但无法写入文件。我用于在SD卡中写入文件的代码是:

String path="mnt/extsd/Test";

                try{
                    File myFile = new File(path, "Hello.txt");              //device.txt
                    myFile.createNewFile();
                    FileOutputStream fOut = new FileOutputStream(myFile);

                    OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
                    myOutWriter.append(txtData.getText());
                    myOutWriter.close();
                    fOut.close();
                    Toast.makeText(getBaseContext(),"Done writing SD "+myFile.getPath(),Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    Toast.makeText(getBaseContext(), e.getMessage(),Toast.LENGTH_SHORT).show();
                    System.out.println("Hello"+e.getMessage());
                }
            }

外部存储卡的路径为mnt/extsd/。这就是为什么我无法使用Environment.getExternalStorageDirectory().getAbsolutePath()给我一条路径mnt/sdcard,而这条路径是我平板电脑中的内部存储路径。请说明为什么会这样,我该如何解决这个问题

4 个答案:

答案 0 :(得分:14)

我记得自从Honeycomb以来Android获得了部分多存储支持,主存储(从Environment.getExternalStorageDirectory获得的存储,通常是内部eMMC卡的一部分)仍然受到权限WRITE_EXTERNAL_STORAGE的保护,但辅助存储(如真正的可移动SD卡)受新权限android.permission.WRITE_MEDIA_STORAGE保护,保护级别为signatureOrSystem,另请参阅this article中的讨论。

如果是这种情况,那么普通应用似乎不可能在没有平台签名的情况下向真实SD卡写入任何内容......

答案 1 :(得分:7)

从API级别19开始,Google has added API

  • Context.getExternalFilesDirs()
  • Context.getExternalCacheDirs()
  • Context.getObbDirs()

不得允许应用程序写入辅助外部存储设备,但合成权限允许的特定于程序包的目录除外。以这种方式限制写入可确保系统在卸载应用程序时清理文件。

以下是使用绝对路径在外部SD卡上获取应用程序特定目录的方法。

Context _context = this.getApplicationContext();

File fileList2[] = _context.getExternalFilesDirs(Environment.DIRECTORY_DOWNLOADS);

if(fileList2.length == 1) {
    Log.d(TAG, "external device is not mounted.");
    return;
} else {
    Log.d(TAG, "external device is mounted.");
    File extFile = fileList2[1];
    String absPath = extFile.getAbsolutePath(); 
    Log.d(TAG, "external device download : "+absPath);
    appPath = absPath.split("Download")[0];
    Log.d(TAG, "external device app path: "+appPath);

    File file = new File(appPath, "DemoFile.png");

    try {
        // Very simple code to copy a picture from the application's
        // resource into the external file.  Note that this code does
        // no error checking, and assumes the picture is small (does not
        // try to copy it in chunks).  Note that if external storage is
        // not currently mounted this will silently fail.
        InputStream is = getResources().openRawResource(R.drawable.ic_launcher);
        Log.d(TAG, "file bytes : "+is.available());

        OutputStream os = new FileOutputStream(file);
        byte[] data = new byte[is.available()];
        is.read(data);
        os.write(data);
        is.close();
        os.close();
    } catch (IOException e) {
        // Unable to create file, likely because external storage is
        // not currently mounted.
        Log.d("ExternalStorage", "Error writing " + file, e);
    }
}

上面的日志输出如下所示:

context.getExternalFilesDirs() : /storage/extSdCard/Android/data/com.example.remote.services/files/Download

external device is mounted.

external device download : /storage/extSdCard/Android/data/com.example.remote.services/files/Download

external device app path: /storage/extSdCard/Android/data/com.example.remote.services/files/

答案 2 :(得分:0)

我删除android:maxSdkVersion="18"中的uses-permission解决了这个问题 在清单文件中。 即用这个:

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

而不是:

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

答案 3 :(得分:0)

检查用户是否具有外部存储权限。如果没有,则使用cache dir保存文件。

drawable