通过第三方应用打开指定格式(本例为pdf格式)的文件


android 第三方 打开文件 安卓打开第三方应用_android 第三方 打开文件

private void openFile(File file){
        if (!file.exists()){
            return;
        }
        Uri path;
        Intent intent = new Intent(Intent.ACTION_VIEW);//选择打开方式,如果让某些应用来响应并显示内容的话,就可以用这个Action
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//如果不声明这个权限,会导致选择的应用无法获取到你指定的这个文件
        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
            //7.0及更高版本,需要通过FileProvider生成Uri,前缀为content://
            path = FileProvider.getUriForFile(this, "com.example.pdfhelper.fileprovider", file);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }else {
            //低版本可直接通过文件生成Uri,前缀为file://
            path = Uri.fromFile(file);
        }
        intent.setDataAndType(path, "application/pdf");//设置类型,如果不确定类型的话,可以声明为"application/*"
        startActivity(intent);
    }
//之前写错了,让第三方应用打开文件,使用的是ACTION_SEND(不正确的),其实应该是ACTION_VIEW,ACTION_SEND是通过第三方应用分享文件
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_STREAM,path);//分享文件和打开文件,他们设置文件的方式是不一样的,一个是通过Extra,一个是通过Data

provider需要在配置清单application节点下声明

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.pdfhelper.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"
                />
        </provider>

FileProvider.getUriForFile()方法的第二个参数就是声明的Provider的authorities
同时要在res目录下新建一个xml目录,再新建filepaths文件
filepaths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="external"
        path="." />
</paths>

paths节点下的元素是设置好的

android 第三方 打开文件 安卓打开第三方应用_android_02


使用时可以根据自己的需要来声明,不需要用到的节点可以不声明

external-path对应的是手机的外部存储,即Environment.getExternalStorageDirectory()

name可以自己随便定义,path填"."就代表是外部存储的根目录

在通过provider生成uri时,会根据文件路径和声明的path路径进行匹配,最后找到最符合的一个路径。

如果没有特殊需求的话,path中声明一个.就可以了。

比如我们把一个文件放在Environment.getExternalStorageDirectory()目录下,名字是a.txt,后面我们通过fileProvider分享给其他应用时,uri就会是content://com.clinks.app.fileprovider.external/a.txt

  • content://是固定的开头
  • com.clinks.app.fileprovider是我们在配置清单中声明的Provider的android:authorities的内容
  • external是我们声明的一个节点的name。因为我们的文件在Environment.getExternalStorageDirectory()的路径下,所以会自动匹配到xml中的external-path,它的name是external(我们自己声明的,可以是随便的内容)
  • /a.txt是我们的文件名和它相对于Environment.getExternalStorageDirectory()目录的路径

如果我们自己写的逻辑,在Environment.getExternalStorageDirectory()下建一个叫parent的文件夹,并且所有要打开和分享的文件都会放在这个文件夹中,那我们就可以在xml中完善path的值

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="external"
        path="./parent" />
</paths>

这样我们最后生成的uri还是content://com.clinks.app.fileprovider.external/a.txt
当然我们不完善path,也不会报错的,不完善的情况下,uri是content://com.clinks.app.fileprovider.external/parent/a.txt