写入SD卡总是失败

Writing to SD Card always failing

我正在尝试从任何位置(包括内部设备存储)移动文件 到 SD 卡,

为此我有

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

在我的清单中,并通过使用 :

检查是否授予许可来检查它是否有效

Contex.checkCallingOrSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE")Contex.checkCallingOrSelfPermission("android.permission.READ_EXTERNAL_STORAGE")

我已经尝试了 3 种不同的方法来做到这一点:

  1. Files.move(original, newPath1), Guava自带com.google.common.io
  2. 这个方法:

    public static void move(File src, File dst) throws IOException {
        FileInputStream inStream = new FileInputStream(src);
        FileOutputStream outStream = new FileOutputStream(dst);
        FileChannel inChannel = inStream.getChannel();
        FileChannel outChannel = outStream.getChannel();
        inChannel.transferTo(0, inChannel.size(), outChannel);
        inStream.close();
        outStream.close();
    }
    
  3. original.renameTo(newPath1);

我阅读了很多关于此的 SO 帖子,但我尝试的所有解决方案均无效,我确保已安装 SD 卡,并且在尝试时我没有将我的设备连接到 PC。我什至用 SD 卡尝试了 2 种不同的设备。请注意,我可以使用完全相同的路径使用 BitmapFactory.decode() 访问图像,并且可以将该图像加载到 imageview。

我总是收到 EACCES(权限被拒绝)。我不知道还能做什么来解决这个问题:(

11-13 11:11:54.358 19192-19372/xaday.ofek.ron.xaday W/System.err: java.io.FileNotFoundException: /storage/sdcard1/DCIM/thai2/IMG-20150702-WA0001.jpg: open failed: EACCES (Permission denied)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:465)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at com.google.common.io.Files$FileByteSink.openStream(Files.java:245)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at com.google.common.io.Files$FileByteSink.openStream(Files.java:233)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at com.google.common.io.ByteSource.copyTo(ByteSource.java:248)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at com.google.common.io.Files.copy(Files.java:458)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at com.google.common.io.Files.move(Files.java:673)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at xaday.ofek.ron.xaday.XaDayIntentService.handleActionMove(XaDayIntentService.java:128)
11-13 11:11:54.369 19192-19372/xaday.ofek.ron.xaday W/System.err:     at xaday.ofek.ron.xaday.XaDayIntentService.onHandleIntent(XaDayIntentService.java:84)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err:     at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err:     at android.os.Looper.loop(Looper.java:211)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err:     at android.os.HandlerThread.run(HandlerThread.java:61)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err:     at libcore.io.Posix.open(Native Method)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:451)
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err:   ... 12 more
11-13 11:11:54.370 19192-19372/xaday.ofek.ron.xaday W/System.err: java.io.FileNotFoundException: /storage/sdcard1/DCIM/thai2/IMG-20150702-WA0001.jpg: open failed: EACCES (Permission denied)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:465)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at xaday.ofek.ron.xaday.FileUtils.move(FileUtils.java:36)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at xaday.ofek.ron.xaday.XaDayIntentService.handleActionMove(XaDayIntentService.java:136)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at xaday.ofek.ron.xaday.XaDayIntentService.onHandleIntent(XaDayIntentService.java:84)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at android.os.Looper.loop(Looper.java:211)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at android.os.HandlerThread.run(HandlerThread.java:61)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at libcore.io.Posix.open(Native Method)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:451)
11-13 11:11:54.371 19192-19372/xaday.ofek.ron.xaday W/System.err:   ... 9 more

为了确保我没有以某种方式锁定文件,我使用了另一个文件管理器应用程序来执行相同的文件移动 - 并且成功了!为什么它对我不起作用?!

有人有想法吗?

在 Android Kitkat (4.4) 上,Google 更改了开发人员访问可移动存储(SD 卡)的方式。引用自 source.android.com:

The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions. Restricting writes in this way ensures the system can clean up files when applications are uninstalled.

因此,即使有WRITE_EXTERNAL_STORAGE权限,您也无法在KitKat及更高版本上写入SD卡。

在Android Lollipop (5.0)上,Google添加了一组新的API,允许开发者通过Storage Access Framework管理SD卡上的文件.

这个 Whosebug 答案详细解释了如何使用新的 APIs 和现有的限制:

How to use the new SD card access API presented for Android 5.0 (Lollipop)?

"uses-permission" 标签是否在 manifest.xml 中的 "application" 标签之外?