【问题标题】:Android 6.0.1 read/write external SD cardAndroid 6.0.1 读/写外置SD卡
【发布时间】:2017-02-10 02:01:23
【问题描述】:

我在三星 SM-T350 上运行 Marshmellow 6.0.1,并尝试在外部 sd 卡 (/mnt/media_rw/38E5-07B6) 上创建一个文件。

AndroidManifest.xml

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

我在运行时请求许可,然后用户授予他们。我可以从系统偏好中仔细检查。在代码中,我检查以确保用户在继续之前授予了权限。

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], int[] grantResults) {
    check against PackageManager.PERMISSION_GRANTED
}

当我尝试像这样写入外部 SD 卡时:

File exportFile = new File("/mnt/media_rw/38E5-07B6/junk.txt");
exportFile.createNewFile();

我明白了:

java.io.IOException: open failed: EACCES (Permission denied)
  at java.io.File.createNewFile(File.java:939)
  at com.myapp.util.FileUtils.copyFile(FileUtils.java:42)
  at com.myapp.service.ExportService$1.onClick(ExportService.java:47)
  at android.view.View.performClick(View.java:5714)
  at android.widget.TextView.performClick(TextView.java:10926)
  at android.view.View$PerformClick.run(View.java:22589)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:148)
  at android.app.ActivityThread.main(ActivityThread.java:7325)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
  at libcore.io.Posix.open(Native Method)
  at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
  at java.io.File.createNewFile(File.java:932)
  at com.myapp.util.FileUtils.copyFile(FileUtils.java:42) 
  at com.myapp.service.ExportService$1.onClick(ExportService.java:47) 
  at android.view.View.performClick(View.java:5714) 
  at android.widget.TextView.performClick(TextView.java:10926) 
  at android.view.View$PerformClick.run(View.java:22589) 
  at android.os.Handler.handleCallback(Handler.java:739) 
  at android.os.Handler.dispatchMessage(Handler.java:95) 
  at android.os.Looper.loop(Looper.java:148) 
  at android.app.ActivityThread.main(ActivityThread.java:7325) 
  at java.lang.reflect.Method.invoke(Native Method) 
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

当我使用 adb shell 挂载设备时,我抓取了 pid,然后转储 /proc/{pid}/status,我可以看到我的用户没有写入 SD 卡所需的 AID_SDCARD_RW (1015) 权限。

Groups: 3003 9997 50143

我还在 /system/etc/permissions/permissions.xml 中找到了这个

<permission name="android.permission.WRITE_MEDIA_STORAGE" >
    <group gid="media_rw" />
    <group gid="sdcard_rw" />
</permission>

没有android.permission.WRITE_EXTERNAL_STORAGE,但是有permission:android.permission.WRITE_MEDIA_STORAGE

毕竟,我的问题是:有没有人遇到过权限在清单中的问题,他们已经对新的权限模型进行了更改,他们仍然无法写入 SD 卡?我怎样才能(不生根,因为不应该需要它)让它工作?

【问题讨论】:

    标签: android android-permissions android-sdcard


    【解决方案1】:

    首先,有一个 WRITE_EXTERNAL_STORAGE 权限。其次,您假设外部存储是 /mnt/media_rw/38E5-07B6。外部存储没有可靠的硬编码路径。您应该改为请求目录。第三,即使您添加了权限,您也不会对磁盘​​上​​的任何地方都有写权限 - 您仅限于公共目录和您的应用程序目录。第四,在较新版本的 Android 中,您还必须请求运行时权限。

    所以你有很多问题需要解决。

    【讨论】:

    • 第一: 已经在问题中了
    • 第三:这甚至不是真的。 ES File explorer(play.google.com/store/apps/…) 可以写入 SD 卡上的任何位置,它是一个 3rd 方应用程序第四:我要求权限。我仔细检查了权限。 > 我在运行时请求许可,用户授予许可。我可以从系统偏好中仔细检查。在代码中,我检查以确保用户在继续之前授予了权限。再次在问题中
    • 第二:我知道挂载点是对的,因为我用adb附加并运行mount命令,可以看到卡id
    • @whatthemess 这次也许挂载点是对的。下次插入它可能不会。你不能假设 Android 上的挂载点,任何资源都没有硬编码路径。至于 WRITE_EXTERNAL_STORAGE,你说你在问题中没有它。如果你的意思是别的,你需要更清楚。
    • @whatthemess 至于能否写入整个 sd 卡——不太可能,但这取决于 OEM 如何设置系统。如果他们决定让 sdcard 成为外部存储的子集,并可能授予对它的世界写入访问权限。但是不要指望它在所有设备上都能像这样工作,KitKat 已经改变了。请参阅 possiblemobile.com/2014/03/android-external-storage 以获得关于它的好文章。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    • 2011-11-07
    • 1970-01-01
    • 2011-06-11
    相关资源
    最近更新 更多