有没有办法在Android的SD卡上随处写?

时间:2016-10-03 10:55:11

标签: android android-permissions android-sdcard

自KitKat以来,我在Android和SD卡上阅读了很多东西。但最后,我找不到一个明确的全球答案,所以我会试着从你们那里得到一个相关的答案。

我想在SD卡上的任意位置写一个文件,一个文本文件。

让我们通过这个简单的例子专注于Android 6。清单中存在写入权限

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

我有这个辅助方法

private void writeFile(File parent)
{
    try
    {
        File f = new File(parent, "test.txt");
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(f));
        outputStreamWriter.write("test");
        outputStreamWriter.close();
        Log.i(TAG, "File created : " + f.getAbsolutePath());
    }
    catch (IOException e)
    {
        Log.e(TAG, "File write failed", e);
    }
}

在测试活动中:

if (Build.VERSION.SDK_INT >= 23)
{
    if (ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
        || ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
    {
        ActivityCompat.requestPermissions(MainActivity.this, new String[] {
            android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
            android.Manifest.permission.READ_EXTERNAL_STORAGE }, 1);
    }
    else
    {
        File path = getExternalFilesDirs(Environment.DIRECTORY_PICTURES)[1];
        writeFile(path);

        path = getExternalFilesDirs(null)[1];
        writeFile(path);

        writeFile(new File("/storage/3635-3533/"));
    }
}
是 /!

首次发布,permission asked,一切正常(对不起法国设备)

第二次发布,这是结果

10-03 12:40:10.414: I/TESTSDCARD(26006): File created : /storage/3635-3533/Android/data/com.example.testsdcard/files/Pictures/test.txt
10-03 12:40:10.415: I/TESTSDCARD(26006): File created : /storage/3635-3533/Android/data/com.example.testsdcard/files/test.txt
10-03 12:40:10.426: E/TESTSDCARD(26006): File write failed
10-03 12:40:10.426: E/TESTSDCARD(26006): java.io.FileNotFoundException: /storage/3635-3533/test.txt: open failed: EACCES (Permission denied)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at libcore.io.IoBridge.open(IoBridge.java:459)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at com.example.testsdcard.MainActivity.writeFile(MainActivity.java:61)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at com.example.testsdcard.MainActivity.onCreate(MainActivity.java:50)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.app.Activity.performCreate(Activity.java:6367)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2397)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2504)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.app.ActivityThread.access$900(ActivityThread.java:165)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.os.Handler.dispatchMessage(Handler.java:102)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.os.Looper.loop(Looper.java:150)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at android.app.ActivityThread.main(ActivityThread.java:5546)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at java.lang.reflect.Method.invoke(Native Method)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
10-03 12:40:10.426: E/TESTSDCARD(26006): Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at libcore.io.Posix.open(Native Method)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
10-03 12:40:10.426: E/TESTSDCARD(26006):    at libcore.io.IoBridge.open(IoBridge.java:445)
10-03 12:40:10.426: E/TESTSDCARD(26006):    ... 16 more

正如您所看到的,使用getExternalFilesDirs的两个测试都有效(不应该感到惊讶,应该是这样) 但是第三个尝试写入SD卡的根目录却失败了。

我做错了吗?有没有办法执行此操作?希望不使用存储访问框架,这对我的应用程序环境来说真的很痛苦。

此外,存储访问框架是否允许在没有大量代码的情况下对文件执行每个基本操作(写入,删除,重命名...)?

1 个答案:

答案 0 :(得分:1)

  

我想在SD卡上的任意位置写一个文件,一个文本文件。

这在Android 4.4+附带的设备上是不可能的,除非在root设备上。

  

清单中有写入权限

该权限适用于外部存储。外部存储不是可移动存储。

  

我做错了吗?

是的,只要您对可移动存储上的任意位置没有读/写权限。

  

存储访问框架是否允许在没有大量代码的情况下对文件执行每个基本操作(写入,删除,重命名...)?

没有人,但你知道你会考虑什么&#34;大量的代码&#34;成为。一般来说,如果您获得了用户对一段内容(或其容器)的许可,您可以执行在DocumentFile上看到的各种操作。