WRITE_EXTERNAL_STORAGE 即使在清单中设置了棒棒糖,它也无法正常工作

WRITE_EXTERNAL_STORAGE not working on lollipop even though it's set in the manifest

我正在尝试将图像从应用程序本地数据文件夹保存到外部存储。我的清单包含以下内容(在清单的应用程序标签之前):

<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />

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

当我尝试以下操作时

try {
        InputStream in = new FileInputStream(filePath);
        File outPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File outFile = new File(outPath, "mypicture.jpg");


        //try fails at this line
        OutputStream out = new FileOutputStream(outFile);

        byte[] buf = new byte[1024];
        int len;

        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }

        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
} catch (IOException e) {
    e.printStackTrace();
}

我收到这个错误:

java.io.FileNotFoundException: /storage/emulated/0/Pictures/mypicture.jpg: open failed: EACCES (Permission denied)

我也尝试了一个稍微不同的输出路径:

 String sdCardPath = Environment.getExternalStorageDirectory() + "/MyFolder";
 new File(sdCardPath).mkdirs();
 File outFile = new File(sdCardPath, "mypicture.jpg");

但这也给我一个错误:

java.io.FileNotFoundException: /storage/emulated/0/MyFolder/mypicture.jpg: open failed: ENOENT (No such file or directory)

设备是运行 Android 4.4.2,所以在运行时不需要请求权限(据我所知不能请求他们)。

为了允许将文件保存到外部存储器,是否还缺少其他东西?

在Android6,需要在运行时请求权限。如果你 运行 在 4.4 上,仍然有那个错误,我认为你还没有创建文件夹。

 String sdCardPath = Environment.getExternalStorageDirectory() + "/MyFolder";
 new File(sdCardPath) .mkdirs(); //create folders where write files
 File outFile = new File(sdCardPath, "mypicture.jpg");

这应该不是必需的,但请尝试在您的 Manifest 中添加此权限。

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

有时 Android 会攻击我们。

试试这个:

 String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/MyFolder");    
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";

File file = new File (myDir, fname);
if (file.exists ()) file.delete (); 
file.createNewFile();
try {
       FileOutputStream out = new FileOutputStream(file);
       FileInputStream in = new FileInputStream(filePath);
        byte[] buf = new byte[1024];
        int len;

        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }

        in.close();
        out.flush();
        out.close();

} catch (Exception e) {
       e.printStackTrace();
}

同时为清单添加读写权限

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

问题的原因是通过 gradle 引入的外部库有自己的清单请求 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18">

我自己的清单仅在未包含 maxSdkVersion="18" 时有效,因此添加该参数的清单合并导致了此错误。我的解决方案是将我自己的清单更改为:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="23" tools:replace="android:maxSdkVersion" />

我假设 maxSdkVersion="18" 意味着任何设备 运行 SDK 19-22 都没有此权限(23+ 能够在运行时请求它)。