android文件分享在android7.0以上版本报错的解决方案

最近在使用蓝牙进行文件分享时,出现了一个奇怪的问题。一样的代码在android5.1上能够顺利运行,可是在android7.0上就运行失败。出现以下的错误:android

Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/bluetooth/data.txt exposed beyond app through ClipData.Item.getUri()

出现这个问题的时候我马上意识到这是一个兼容的问题,因而在网上找了一些方法,并解决了这个问题,我受到启发的网址是:安全

​ 出现FileUriExposedException这样的异常,缘由是Andorid7.0的“私有目录被限制访问”,“StrictMode API 政策”。
因为从Android7.0开始,直接使用真实的路径的Uri会被认为是不安全的,会抛出一个FileUriExposedException这样的异常。须要使用FileProvider,选择性地将封装过的Uri共享到外部。

即之前的共享代码是这样写的:app

Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("*/*");
sharingIntent.setComponent(new ComponentName("com.android.bluetooth","com.android.bluetooth.opp.BluetoothOppLauncherActivity"));
sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(path)));
startActivity(sharingIntent);

 

在android7.0版本以上时,不使用Uri.fromFile(),使用如下的代码:ide

Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("*/*");
sharingIntent.setComponent(new ComponentName("com.android.bluetooth","com.android.bluetooth.opp.BluetoothOppLauncherActivity"));
sharingIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(BluetoothChat.this,"你的包名" + ".fileprovider", new File(path)));
sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(sharingIntent);

 

​ 若是是Andorid7.0或以上,则再也不使用Uri.fromFile()方法获取文件的Uri,而是经过使用FileProvider(support.v4提供的类)的getUriForFile()。同时要添加多这么一行代码ui

sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

 

因为FileProvider是继承ContentProvider,属于四大组件之一,须要在AndroidManifest.xml中配置,配置以下:this

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="你的包名.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <!--元数据-->
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths"/>
    </provider>

 

其中android:resource="@xml/file_provider_paths"的内容你能够在res目录下新建一个xml文件夹,在文件夹中新建一个file_provider_paths.xml文件便可,以下图所示spa

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path path="" name="myFile"></external-path>
    </paths>
</resources>

 

  上述代码中path=” “,是有特殊意义的,它代码根目录,也就是说你能够向其它的应用共享根目录及其子目录下任何一个文件了,若是你将path设为path=”pictures”, 那么它表明着根目录下的pictures目录(eg:/storage/emulated/0/pictures),若是你向其它应用分享pictures目录范围以外的文件是不行的。

.net

分享文件代码以下:code

    // 調用系統方法分享文件
    public static void shareFile(Context context, File file) {
        try{
            if (null != file && file.exists()) {
                Log.w("ppp-params", file.getPath());
                Intent share = new Intent(Intent.ACTION_SEND);
                share.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(context,"app.zhaohangwuliu.com.appada" + ".fileprovider", file));
                share.setType("*/*");//此处可发送多种文件
                share.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                context.startActivity(Intent.createChooser(share, "分享文件"));
            } else {
                //Toast.makeText(context, "分享文件不存在", Toast.LENGTH_SHORT).show();
            }
        }catch (Exception ex){
            Log.w("ppp-params", ex);
        }

    }

 

转: http://www.javashuo.com/article/p-uxzngmyy-ma.htmlxml

相关文章
相关标签/搜索