Android 通过Intent 打开File 文件

5,904 阅读3分钟

# intent 打开File 文件

在 Android 设备上如何打开 docx doc ppt xls mp3 mp4 等格式的文件?

# intent

Intent的理解和使用

Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动 作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的 交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。

如何通过intent 找到对应的组件 打开我们指定的文件?

举个例子:

 // 给移动客服10086拨打电话
 Uri uri = Uri.parse("tel:10086");
 Intent intent = new Intent(Intent.ACTION_DIAL, uri);
 startActivity(intent);

intent 分为 隐式 和 指定 因为不知道手机上有那些组件 App 能打开我们要打开的文件 所以只能隐式调用配置data type uri

 //android获取一个用于打开PDF文件的intent
    public static Intent getPdfFileIntent(File file) {
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
         Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = StorageUtils.getUriForFile(BaseApplication.getContext(), file);
        } else {
            uri = Uri.fromFile(file);
        }
        intent.setDataAndType(uri, "application/pdf");
        return intent;
    }
    
    //android获取一个用于打开音频文件的intent
    public static Intent getAudioFileIntent(File file) {
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.putExtra("oneshot", 0);
        intent.putExtra("configchange", 0);
         Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = StorageUtils.getUriForFile(BaseApplication.getContext(), file);
        } else {
            uri = Uri.fromFile(file);
        }
        intent.setDataAndType(uri, "audio/*");
        return intent;
    }
    
     //android获取一个用于打开视频文件的intent
    public static Intent getVideoFileIntent(File file) {
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.putExtra("oneshot", 0);
        intent.putExtra("configchange", 0);
         Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = StorageUtils.getUriForFile(BaseApplication.getContext(), file);
        } else {
            uri = Uri.fromFile(file);
        }
        intent.setDataAndType(uri, "video/*");
        return intent;
    }
    
     //android获取一个用于打开Excel文件的intent
    public static Intent getExcelFileIntent(File file) {
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
         Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = StorageUtils.getUriForFile(BaseApplication.getContext(), file);
        } else {
            uri = Uri.fromFile(file);
        }
        intent.setDataAndType(uri, "application/vnd.ms-excel");
        return intent;
    }

    //android获取一个用于打开PPT文件的intent
    public static Intent getPPTFileIntent(File file) {
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
         Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = StorageUtils.getUriForFile(BaseApplication.getContext(), file);
        } else {
            uri = Uri.fromFile(file);
        }
        intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
        return intent;
    }

注意: Android 7.0 以上 去除 file://uri 对外公开

对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在应用外部公开 file:// URI , 如果一项包含文件 URI 的 intent 离开应用,则应用出现故障,并出现 FileUriExposedException 异常。 要应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅 共享文件 FileProvider 实际上是 ContentProvider 的一个子类,它的作用也比较明显,file://Uri 不给用,那么换个 Uri 为 content:// 来替代。

Android 一起来看看 7.0 的新特性 FileProvider

 /**
     * 获取Android 7.0 以上的文件映射
     *
     * @param context 上下文
     * @param file    文件对象
     * @return 映射 uri
     */
    public static Uri getUriForFile(Context context, File file) {
        if (context == null || file == null) {
            throw new NullPointerException();
        }
        Uri uri;
        if (Build.VERSION.SDK_INT >= 24) {
            uri = FileProvider.getUriForFile(context.getApplicationContext(),
                    "you application id + fileprovider", file);
        } else {
            uri = Uri.fromFile(file);
        }
        return uri;
    }
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path
        name="hm_external_files"
        path="/"/>
    <external-path name="external_files" path="."/>
</paths>

 <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="you application id + fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>