【问题标题】:Difficulties with File URI on 7.07.0 上文件 URI 的困难
【发布时间】:2017-11-30 12:55:39
【问题描述】:

为了尽可能简短,我使用以下代码将文件上传到 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"));

intent 可以很好地打开,但它不会保存文件并输出错误(不在日志中,Dropbox 应用会这样做)。

由于我在使用 OneDrive 时遇到了类似的问题,所以我决定打印出我的文件 URI(使用 OneDrive 出现 NoFileSpecified 错误)。

content://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)。

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

【问题讨论】:

    标签: android file android-permissions file-uri


    【解决方案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教程:

    【讨论】:

      【解决方案2】:

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

      简而言之,您将在AndroidManifest.xml 中定义它并在xml 文件夹下创建一个新的resources.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>
      

      xml 文件夹下的paths.xml

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

      要获取新的 URI,您可以像这样使用 #FileProvider.getUriForFile 方法

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

      URI 如下所示

      content:///fileprovider/pathname/actualPathToFile

      最后,您必须将标志 Intent.FLAG_GRANT_READ_URI_PERMISSION) 添加到您的 Intent。就是这样。

      【讨论】:

      • 感谢您的宝贵时间。正如您在我的代码中看到的,我正在使用 FileProvider。但是我的paths.xml 是不同的。你能告诉我我应该使用什么作为 path="。" ?我是否将其保留为期间?如果不是我要添加什么?我还使用 intent.setFlags() 在您的答案中添加了该标志。但无济于事。
      • @Nephilim 请参阅此处的文档developer.android.com/reference/android/support/v4/content/…。有不同的路径类型。 . 字符只是为了方便。在我的示例中,它共享外部路径上的每个文件,例如SD卡。
      • 谢谢。我将其保留为 `` 。 `` 直到我设法修复这个错误。
      猜你喜欢
      • 2012-03-10
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多