Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Android中获得对可移动媒体上DCIM目录的写访问权?_Android_Permissions - Fatal编程技术网

如何在Android中获得对可移动媒体上DCIM目录的写访问权?

如何在Android中获得对可移动媒体上DCIM目录的写访问权?,android,permissions,Android,Permissions,我的代码如下: public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); writeFile();

我的代码如下:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        writeFile();
    }



    public void writeFile()  {

        File removableRoot = RootsUtil.getRemovableRoots(this)[0];
        File DCIMDirectory = new File(removableRoot, "DCIM");
        File cameraDirectory = new File(DCIMDirectory, "Camera");

        if( cameraDirectory.exists() ) {
            try {
                String filename = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()) + ".txt";


                //cameraDirectory.mkdirs();
                File file = new File(cameraDirectory, filename);
                FileWriter writer = null;

                writer = new FileWriter(file);
                PrintWriter printWriter = new PrintWriter(writer);
                printWriter.println("Hello World");

                printWriter.close();
                writer.close();

                System.out.println("Number of files: " + cameraDirectory.listFiles().length);

            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
cameraDirectory
等于if和它存在之前的
/storage/9C33-6BBD/DCIM/Camera
。这是我的
相机
应用程序存储其文件的地方

我也尝试将文件写入此目录,但失败,出现以下异常:

java.io.FileNotFoundException: /storage/9C33-6BBD/DCIM/Camera/20170204_192001.txt: open failed: EACCES (Permission denied)
    at libcore.io.IoBridge.open(IoBridge.java:452)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
    at java.io.FileWriter.<init>(FileWriter.java:42)
    at com.inthemoon.trycamerawrite.MainActivity.writeFile(MainActivity.java:48)
    at com.inthemoon.trycamerawrite.MainActivity.onCreate(MainActivity.java:28)
    at android.app.Activity.performCreate(Activity.java:6876)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
    at android.app.ActivityThread.access$1100(ActivityThread.java:222)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:158)
    at android.app.ActivityThread.main(ActivityThread.java:7229)
    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 libcore.io.IoBridge.open(IoBridge.java:438)
    ... 17 more

然后允许用户手动选择DCIM/Camera,但这没有帮助。

您试图直接写入可移动存储的文件系统。这将不起作用,除非选择应用程序特有的目录(例如,
getExternalFilesDirs()
返回的目录)

使用
ACTION\u OPEN\u DOCUMENT\u TREE
不会神奇地授予您文件系统访问权限。它所做的是为您提供一个
Uri
,您可以将其与
ContentResolver
DocumentFile
和kin一起使用,以基于该
Uri
处理文档和集合

ACTION\u OPEN\u DOCUMENT\u TREE
是文档的一部分,包含在文档中


Android 7.0+还提供了一种更简单的方式,用户可以通过这种方式在可移动存储上授予您访问类似于
DCIM/
的内容的权限。但是,它也给了您一个
Uri
,您仍然可以使用
ContentResolver
DocumentFile
,等等来处理基于该
Uri

其他文件夹工作的内容和集合?您在清单中授予了写存储权限吗?您的目标sdk是什么?在gradle?
cameraDirectory.mkdirs()中。不要盲目地调用mkdirs()。首先检查目录是否存在。并检查返回值,因为它可能无法创建目录,在这种情况下返回false。如果是的话,向说这句话的用户敬酒。然后返回。不要继续你的代码,因为试图在一个不存在的目录中创建一个文件是没有意义的。@greenapps抱歉,我不得不继续尝试,因为似乎没有人知道我需要的答案;当我找到它时,它的价值就越大:)我对
Uri
没有任何异议。我只是想知道,如果有一个
Uri
,我可以如何将“Hello world”文本写入引用文件:)这可能吗?@Dims:同样,它不是一个文件。使用
fromTreeUri()
为所选树创建
文档文件。创建一个
文档文件
,指向要写入的树中的位置。对该
DocumentFile
调用
getUri()
,以获取文档的
Uri
。将其传递到
ContentResolver
上的
openOutputStream()
。然后,写入流,
flush()
流和
close()
流。好吧,那么为什么我不能用
uri.fromFile(myPoorFile)
创建uri,然后从“将它传递到openOurputStream”这几个字继续你的食谱?@Dims:因为你没有对文件系统的直接写访问权。从
ACTION\u OPEN\u DOCUMENT\u树
getUri()
获取的
Uri
将有一个
内容
方案。您正在告诉
内容提供者
要写什么;它基于
Uri
将内容写入任何有意义的地方。对于可移动存储,系统提供的可移动存储提供程序对其具有写访问权限,而您的应用程序对其上的任意位置没有写访问权限。@Dims:安装期间没有。此外,当您的
targetSdkVersion
达到23或更高版本时,您引用的
danger
权限需要与Android 6.0+上的用户进行运行时交互。关于
ACTION\u OPEN\u DOCUMENT\u树
,一旦获得
Uri
,调用以获得对该树的持久访问。
private static final int RQS_OPEN_DOCUMENT_TREE = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE, Uri.fromFile(cameraDirectory));
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        startActivityForResult(intent, RQS_OPEN_DOCUMENT_TREE);

        //writeFile();
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        writeFile();
    }