Android11,12分享图片到其他应用

875 阅读1分钟

工作中有一个需求是分享一些图片到其他应用,但是由于是Android11的系统,看了网上很多内容,有点混乱,所以在此记录一下实现方法。

1.从网络上下载图片到本地,如果是存储在内部存储和外部存储的app下的私有目录里(也就是沙盒目录),是不需要申请读写权限的,可以直接写入和读取SD卡中的文件。

2.对于外部存储沙盒里的文件,可以通过file provider来分享给其他应用。 首先在清单文件里声明以下代码

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

然后在res文件夹下的xml文件夹创建file_provider_paths.xml文件

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-cache-path  name="external_cache_path" path="."/>
    <!--配置root-path。这样子可以读取到sd卡和一些应用分身的目录,否则微信分身保存的图片,就会导致 java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/999/tencent/MicroMsg/WeiXin/export1544062754693.jpg,在小米6的手机上微信分身有这个crash,华为没有
-->
    <root-path name="root-path" path="" />
</paths>

我的应用存储的图片路径/storage/emulated/10/Android/data/packgname,所以必须加上root-path。

下载图片之后,path路径转换为uri分享出去

val contentUri = FileProvider.getUriForFile(
    context,
    context.getPackageName() + ".fileprovider",  // 要与`AndroidManifest.xml`里配置的`authorities`一致,假设你的应用包名为com.example.app
    file
)

3.其他应用只要添加,并且拿到uri,解析显示。

<queries>
    <package android:name="com.xx.xx.fileprovider" />
</queries>
private Bitmap getInputStrem(String icon) {
        if(icon == null){
            return null;
        }
        Uri fileUri = Uri.parse(icon);
        Bitmap bm = null;
        try {//获得uri图片并显示
            InputStream is = getContentResolver().openInputStream(fileUri);
            bm= BitmapFactory.decodeStream(is);
            Log.e(TAG,"bm is null?:"+( bm== null));
            return bm;
        } catch(FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("fatal e.getMessage() = " + e.getMessage());
        }
        return null;
    }
//拿到uri的图片,显示在textview上
if(iconUri != null){
            Bitmap bm = getInputStrem(iconUri);
            if(bm != null){
                Log.e(TAG,"updateButton--填充图片====");
                //根据Bitmap对象创建ImageSpan对象
                ImageSpan imageSpan=new ImageSpan(this,bm);
                //创建一个SpannableString对象,以便插入用ImageSpan对象封装的图像
                SpannableString spannableString=new SpannableString("icon");
                //用ImageSpan对象替换icon
                spannableString.setSpan(imageSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                //将图像显示在TextView组件上
                textview.setText(spannableString);

            }
        }