7.0上的文件URI的困难

时间:2017-06-27 12:52:53

标签: android file android-permissions file-uri

为了尽可能短,我使用以下代码将文件上传到DropBox:

PackageManager manager = getPackageManager();
                                File f = new File(getContext().getExternalFilesDir("diabetix"),"TESTINTENT.xml");
                                Intent intent = new Intent(Intent.ACTION_SEND);
                                intent.setType("text/*");
                                intent.setPackage("com.dropbox.android");
                                intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(getContext(),"david.projectclouds.MainActivity",f));
                                startActivity(Intent.createChooser(intent, "title"));

意图打开很好,但它不保存文件并输出错误(不在日志中,Dropbox应用程序执行此操作)。

由于OneDrive存在类似问题,我决定打印出我的文件URI(使用OneDrive获取NoFileSpecified错误)。

内容://david.projectclouds.MainActivity/file/diabetix/Temp.xml

这是我的URI。我看了一些例子,似乎是正确的。使用FileExplorer应用程序时,该文件也存在。

我用它来显示权限:

    public void requestReadWritePermissions(){
 // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_EXTERNAL_STORAGE)
            +ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED) {

        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.READ_EXTERNAL_STORAGE)||(ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE))) {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
            Toast.makeText(this, "App needs this permission to run", Toast.LENGTH_SHORT);
        }else{
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        REQUEST_WRITE_PERMISSIONS);
            System.out.println("PERMISSION_GRANTED");

            }
        } else {


            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    REQUEST_READ_PERMISSIONS);

        }
    }

相同的代码在7.0以下的手机上工作正常(认为它是5.0)。

有什么想法吗?有人可以查看我的权限吗?删除它们会输出相同的错误。它只请求一个"请求访问媒体,文件,照片.."它应该显示"写媒体等。"太?

2 个答案:

答案 0 :(得分:1)

您是否捕获了requestPermission结果?当你调用requestPerimission时,你还需要覆盖onRequestPermissionsResult,如下所示:

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CODE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //granted. here you need to call the method, which uploads file to DropBox
                }
                else{
                    // no granted. Handle this somehow.     
                }
                break;
            }

        }
    }

请阅读this教程:

答案 1 :(得分:1)

使用Android 7.0+时,有一项新政策。您必须使用FileProviderSee here了解更多详情。

简而言之,您可以在AndroidManifest.xml中定义它并在resources.xml文件夹下创建一个新的xml(可能需要创建一个)。在那里,您可以定义应与其他应用共享的路径。

来自文档

<manifest>
    ...
    <application>
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.mydomain.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            ...
        </provider>
        ...
    </application>
</manifest>

paths.xml文件夹下的xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

要获取新URI,您可以使用{/ 1}}这样的方法

#FileProvider.getUriForFile

URI看起来像这样

FileProvider.getUriForFile(yourContext, "your.package.name" + ".provider", yourFile);

最后,您必须将标记content:///fileprovider/pathname/actualPathToFile添加到Intent.FLAG_GRANT_READ_URI_PERMISSION)。就是这样。