zoukankan      html  css  js  c++  java
  • ShareIntentUtil【调用系统自带的分享的工具类】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

    根据参考资料的文章,整理了调用系统自带分享的工具类(实现了适配7.0FileProvider的功能),需要搭配《Android6.0运行时权限(基于RxPermission开源库)》。

    效果图

    代码分析

    需要注意的代码主要包括:

    ShareIntentUtil中适配7.0FileProvider的相关代码。

    使用步骤

    一、项目组织结构图

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    (1)将ShareIntentUtil.java文件复制到项目中

    package com.why.project.sharewithsystemdemo.util;
    
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.os.Build;
    import android.support.v4.content.FileProvider;
    import android.widget.Toast;
    
    import java.io.File;
    import java.util.ArrayList;
    
    /**
     * Created by haiyuKing
     * Used 调用系统自带的分享的工具类
     * 增加适配7.0FileProvider的功能
     */
    
    public class ShareIntentUtil {
    
        //指定分享到的软件包名
        public static final String PACKAGE_QQ = "com.tencent.mobileqq";//分享到QQ
        public static final String PACKAGE_QZONE = "com.qzone";//分享会到QQ空间
        public static final String PACKAGE_WBLOG = "com.tencent.WBlog";//分享到腾讯微博
        public static final String PACKAGE_WXIN = "com.tencent.mm";//分享到微信
        public static final String PACKAGE_WEIBO = "com.sina.weibo";//分享到新浪微博
        public static final String PACKAGE_BAIDUYUN = "com.baidu.netdisk";//分享到百度云
    
        //分享文本
        public static void shareText(Context mContext, String shareText, String shareTitle){
            Intent shareIntent = new Intent(Intent.ACTION_SEND);
            shareIntent.setType("text/plain");
            shareIntent.putExtra(Intent.EXTRA_TEXT, shareText);
            //适配7.0FileProvider
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件【很重要】
            }
            mContext.startActivity(Intent.createChooser(shareIntent, shareTitle));//可以设置标题
        }
    
        //分享文本到指定应用
        public static void shareTextTo(Context mContext, String shareText, String shareTitle, String packageName){
            Intent shareIntent = new Intent(Intent.ACTION_SEND);
            shareIntent.setPackage(packageName);
            shareIntent.setType("text/plain");
            shareIntent.putExtra(Intent.EXTRA_TEXT, shareText);
            //适配7.0FileProvider
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件【很重要】
            }
    
            //通过Intent的resolveActivity方法,并想该方法传入包管理器可以对包管理器进行查询以确定是否有Activity能够启动该Intent
            //https://blog.csdn.net/qq_15796477/article/details/72953514
            PackageManager pm = mContext.getPackageManager();
            ComponentName cn = shareIntent.resolveActivity(pm);
            if(cn == null){
                Toast.makeText(mContext,"未安装该应用",Toast.LENGTH_SHORT).show();
            }else {
                mContext.startActivity(Intent.createChooser(shareIntent, shareTitle));//可以设置标题
            }
        }
    
        //分享单张图片
        public static void shareOneImg(Context mContext, String imgPath, String shareTitle){
            File file = new File(imgPath);
            if (!file.exists()) {
                Toast.makeText(mContext,"文件不存在",Toast.LENGTH_SHORT).show();
                return;
            }
    
            //由文件得到uri
            Uri imageUri = getUri(mContext,file);
    
            Intent shareIntent = new Intent();
            shareIntent.setAction(Intent.ACTION_SEND);
            shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
            shareIntent.setType("image/*");
            //适配7.0FileProvider
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件【很重要】
            }
            mContext.startActivity(Intent.createChooser(shareIntent, shareTitle));//可以设置标题
        }
    
        //分享多张图片
        public static void shareMultImg(Context mContext, ArrayList<String> imgPathList, String shareTitle){
    
            ArrayList<Uri> uriList = new ArrayList<>();
    
            for(int i=0;i<imgPathList.size();i++){
                File file = new File(imgPathList.get(i));
                if (!file.exists()) {
                    Toast.makeText(mContext,"文件不存在",Toast.LENGTH_SHORT).show();
                    return;
                }
                uriList.add(getUri(mContext,file));
            }
    
            Intent shareIntent = new Intent();
            shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
            shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList);
            shareIntent.setType("image/*");
            //适配7.0FileProvider
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件【很重要】
            }
            mContext.startActivity(Intent.createChooser(shareIntent, shareTitle));//可以设置标题
        }
    
        //分享单个文件
        public static void shareOneFile(Context mContext, String filePath, String shareTitle){
            File file = new File(filePath);
            if (!file.exists()) {
                Toast.makeText(mContext,"文件不存在",Toast.LENGTH_SHORT).show();
                return;
            }
    
            //由文件得到uri
            Uri fileUri = getUri(mContext,file);
    
            Intent shareIntent = new Intent();
            shareIntent.setAction(Intent.ACTION_SEND);
            shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
            shareIntent.setType("*/*");
            //适配7.0FileProvider
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件【很重要】
            }
            mContext.startActivity(Intent.createChooser(shareIntent, shareTitle));//可以设置标题
        }
    
        //获取到uri--适配7.0FileProvider
        private static Uri getUri(Context mContext, File file){
            Uri uri;
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                String authority = mContext.getApplicationInfo().packageName + ".provider";
                uri = FileProvider.getUriForFile(mContext.getApplicationContext(), authority, file);
                //intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件【很重要】
            } else {
                uri = Uri.fromFile(file);
            }
    
            return uri;
        }
    }
    ShareIntentUtil.java

    (2)在AndroidManifest.xml中添加权限以及配置7.0FileProvider【注意:provider中的android:authorities值:${applicationId}.provider,其中${applicationId}代表的真实值就是APP的build.gradle中的applicationId(包名)值

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.why.project.sharewithsystemdemo">
    
        <!-- =================ShareIntentUtil用到的权限========================== -->
        <!-- 允许程序读取外部存储文件 -->
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
    
            <!-- =================7.0上读取文件========================== -->
            <!--参考资料https://blog.csdn.net/lmj623565791/article/details/72859156-->
            <!--authorities:{app的包名}.provider
            grantUriPermissions:必须是true,表示授予 URI 临时访问权限
            exported:必须是false
            resource:中的@xml/provider_paths是我们接下来要添加的文件-->
            <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>
    
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    (3)将provider_paths文件复制到项目的res/xml目录下【适配7.0FileProvider】

    <?xml version="1.0" encoding="utf-8"?>
    <!--参考资料https://blog.csdn.net/lmj623565791/article/details/72859156-->
    <!--<root-path/> 代表设备的根目录new File("/");-->
    <!--<files-path/> 代表context.getFilesDir()-->
    <!--<cache-path/> 代表context.getCacheDir()-->
    <!--<external-path/> 代表Environment.getExternalStorageDirectory()-->
    <!--<external-files-path>代表context.getExternalFilesDirs()-->
    <!--<external-cache-path>代表getExternalCacheDirs()-->
    
    <!--path:需要临时授权访问的路径(.代表所有路径)-->
    <!--name:就是你给这个访问路径起个名字-->
    <paths>
        <root-path name="root" path="." />
        <files-path name="files" path="." />
        <cache-path name="cache" path="." />
        <external-path name="external" path="." />
        <external-files-path name="external_file_path" path="." />
        <external-cache-path name="external_cache_path" path="." />
    </paths>

    (4)参考《Android6.0运行时权限(基于RxPermission开源库)》导入相关文件。

    三、使用方法

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">
    
        <Button
            android:id="@+id/btn_share_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="分享文本"
            android:layout_marginTop="10dp"/>
    
        <Button
            android:id="@+id/btn_share_one_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="分享单张图片"
            android:layout_marginTop="10dp"/>
    
        <Button
            android:id="@+id/btn_share_mult_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="分享多张图片"
            android:layout_marginTop="10dp"/>
    
        <Button
            android:id="@+id/btn_share_to_qq"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="分享到qq"
            android:layout_marginTop="10dp"/>
    
        <Button
            android:id="@+id/btn_share_one_file"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="分享单个文件"
            android:layout_marginTop="10dp"/>
    
    </LinearLayout>
    activity_main.xml

    在Activity中使用【先申请权限,然后执行相关方法:注意,Demo中指定了文件路径,实际项目中一般是动态获取的

    package com.why.project.sharewithsystemdemo;
    
    import android.Manifest;
    import android.os.Bundle;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Toast;
    
    import com.tbruyelle.rxpermissions2.RxPermissions;
    import com.why.project.sharewithsystemdemo.util.ShareIntentUtil;
    
    import java.io.File;
    import java.util.ArrayList;
    
    import io.reactivex.functions.Action;
    import io.reactivex.functions.Consumer;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = MainActivity.class.getSimpleName();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            onePermission();
    
            initEvents();
        }
    
        private void initEvents() {
            //分享文本
            findViewById(R.id.btn_share_text).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ShareIntentUtil.shareText(MainActivity.this,"这是一段分享的文字","分享文本");
                }
            });
    
            //分享单张图片
            findViewById(R.id.btn_share_one_img).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //Environment.getExternalStorageDirectory()=/storage/emulated/0
                    Log.e("why","Environment.getExternalStorageDirectory()="+Environment.getExternalStorageDirectory());
                    String imagePath = Environment.getExternalStorageDirectory() + File.separator + "DCIM/Camera/IMG_20160723_103940.jpg";
    
                    ShareIntentUtil.shareOneImg(MainActivity.this,imagePath,"分享单张图片");
    
                }
            });
    
            //分享多张图片
            findViewById(R.id.btn_share_mult_img).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //Environment.getExternalStorageDirectory()=/storage/emulated/0
                    Log.e("why","Environment.getExternalStorageDirectory()="+Environment.getExternalStorageDirectory());
    
                    ArrayList<String> imgPathList = new ArrayList<>();
    
                    String path = Environment.getExternalStorageDirectory() + File.separator;
                    imgPathList.add(path+"DCIM/Camera/IMG_20160723_103940.jpg");
                    imgPathList.add(path+"DCIM/Camera/IMG_20170820_121408.jpg");
                    imgPathList.add(path+"DCIM/Camera/IMG_20171001_080012.jpg");
    
                    ShareIntentUtil.shareMultImg(MainActivity.this,imgPathList,"分享多张图片");
                }
            });
    
            //分享到qq
            findViewById(R.id.btn_share_to_qq).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    ShareIntentUtil.shareTextTo(MainActivity.this,"这是一段分享的文字","分享到QQ",ShareIntentUtil.PACKAGE_QQ);
    
                }
            });
    
            //分享单个文件
            findViewById(R.id.btn_share_one_file).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //Environment.getExternalStorageDirectory()=/storage/emulated/0
                    Log.e("why","Environment.getExternalStorageDirectory()="+Environment.getExternalStorageDirectory());
                    String filePath = Environment.getExternalStorageDirectory() + File.separator + "why/AndroidNotesForProfessionals.pdf";
    
                    ShareIntentUtil.shareOneFile(MainActivity.this,filePath,"分享单个文件");
    
                }
            });
        }
    
    
        /**只有一个运行时权限申请的情况*/
        private void onePermission(){
            RxPermissions rxPermissions = new RxPermissions(MainActivity.this); // where this is an Activity instance
            rxPermissions.request(Manifest.permission.READ_EXTERNAL_STORAGE) //权限名称,多个权限之间逗号分隔开
                    .subscribe(new Consumer<Boolean>() {
                        @Override
                        public void accept(Boolean granted) throws Exception {
                            Log.e(TAG, "{accept}granted=" + granted);//执行顺序——1【多个权限的情况,只有所有的权限均允许的情况下granted==true】
                            if (granted) { // 在android 6.0之前会默认返回true
                                // 已经获取权限
                                Toast.makeText(MainActivity.this, "已经获取权限", Toast.LENGTH_SHORT).show();
                            } else {
                                // 未获取权限
                                Toast.makeText(MainActivity.this, "您没有授权该权限,请在设置中打开授权", Toast.LENGTH_SHORT).show();
                            }
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            Log.e(TAG,"{accept}");//可能是授权异常的情况下的处理
                        }
                    }, new Action() {
                        @Override
                        public void run() throws Exception {
                            Log.e(TAG,"{run}");//执行顺序——2
                        }
                    });
        }
    }

    混淆配置

    参考资料

    Android分享---调用系统自带的分享功能

    探索Android调用系统的分享功能

    Intent.resolveActivity

    项目demo下载地址

    https://github.com/haiyuKing/ShareWithSystemDemo

  • 相关阅读:
    springboot文件上传: 单个文件上传 和 多个文件上传
    Eclipse:很不错的插件-devStyle,将你的eclipse变成idea风格
    springboot项目搭建:结构和入门程序
    POJ 3169 Layout 差分约束系统
    POJ 3723 Conscription 最小生成树
    POJ 3255 Roadblocks 次短路
    UVA 11367 Full Tank? 最短路
    UVA 10269 Adventure of Super Mario 最短路
    UVA 10603 Fill 最短路
    POJ 2431 Expedition 优先队列
  • 原文地址:https://www.cnblogs.com/whycxb/p/9554954.html
Copyright © 2011-2022 走看看