【问题标题】:Can't open external storage file in Android N using FileProvider无法使用 FileProvider 在 Android N 中打开外部存储文件
【发布时间】:2019-07-24 06:42:47
【问题描述】:

我无法使用 Android N 打开外部存储中的文件。

文件路径

file:///storage/emulated/0/Download/SamplePDFFile_5mb.pdf

初步实施 完美适用于低于 7 的 Android 版本

File file = new File (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "SamplePDFFile_5mb.pdf");
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);

相同的实现不适用于 7,但有以下例外。

android.os.FileUriExposedException

所以我发现了类似的问题并关注this,以便将应用程序定位的新安卓安全功能修复为 24 或更高。

新实施

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "SamplePDFFile_5mb.pdf");
//old way
//Uri uri = Uri.fromFile(file);
//new way
Uri uri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", file);

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/pdf");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

provider_paths.xml

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

AndroidManifest.xml

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

即使在 Android Manifest、provider_paths.xml 和 FileProvider 中添加了必需的标签后,我也无法打开该文件。打开活动自行关闭。logcat 中没有错误或消息。

【问题讨论】:

    标签: android android-intent android-external-storage android-fileprovider


    【解决方案1】:
    public void getGROUPSTORAGEPremission(){
        int hasWriteContactsPermission = Splash_activity.this.checkSelfPermission(Manifest.permission_group.STORAGE);
        if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
            Splash_activity.this.requestPermissions(new String[]{  Manifest.permission_group.STORAGE},
                    PERMISSION_GROUPSTORAGE);
        } else {
           File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "SamplePDFFile_5mb.pdf");
         //old way
         //Uri uri = Uri.fromFile(file);
         //new way
         Uri uri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", file);
    
           Intent intent = new Intent(Intent.ACTION_VIEW);
           intent.setDataAndType(uri, "application/pdf");
           intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
           startActivity(intent);
        }
    
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_GROUPSTORAGE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission Granted
                File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "SamplePDFFile_5mb.pdf");
         //old way
         //Uri uri = Uri.fromFile(file);
         //new way
          Uri uri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", file);
    
           Intent intent = new Intent(Intent.ACTION_VIEW);
           intent.setDataAndType(uri, "application/pdf");
           intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
           startActivity(intent);
            } else {
                // Permission Denied
                //Toast.makeText(mContext, "PERMISSION_GROUPSTORAGE Denied", Toast.LENGTH_SHORT).show();
            }
        }
     }
    

    N后需要检查运行时权限。

    【讨论】:

    • 你是对的,兄弟。在这种情况下,我完全忘记了 Android 权限。谢谢你。你拯救了我的一天:-)
    【解决方案2】:

    也许迟到了,但我通过向意图添加临时权限来解决它,方法是执行以下操作:

        Uri path = FileProvider.getUriForFile(MainActivity.this, "com.example.root.somepackage.provider", pdfFile);
        Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
        pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // GRANT TEMPORARY READ PERMISSION
        pdfIntent.setDataAndType(path, "application/pdf");
    
        try{
            startActivity(pdfIntent);
        }
    

    这很有帮助:Granting Content Provider URI Permissions

    【讨论】:

      【解决方案3】:

      这个简单的解决方案帮助我解决了这类问题。希望它能帮助您并节省您的时间。

      public void open_file(String filename) {
          File path =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
          File file = new File(path, filename);
      
          // Get URI and MIME type of file
          Uri uri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".fileprovider", file);
          String mime = context.getContentResolver().getType(uri);
      
          // Open file with user selected app
          Intent intent = new Intent();
          intent.setAction(Intent.ACTION_VIEW);
          intent.setDataAndType(uri, mime);
          intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
          context.startActivity(intent);
      }
      

      【讨论】:

        猜你喜欢
        • 2017-07-04
        • 1970-01-01
        • 2017-02-21
        • 1970-01-01
        • 1970-01-01
        • 2014-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多