版权声明:本文为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";//分享到QQpublic 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.0FileProviderif (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.0FileProviderif (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/72953514PackageManager 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;}//由文件得到uriUri imageUri = getUri(mContext,file);Intent shareIntent = new Intent();shareIntent.setAction(Intent.ACTION_SEND);shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);shareIntent.setType("image/*");//适配7.0FileProviderif (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.0FileProviderif (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;}//由文件得到uriUri fileUri = getUri(mContext,file);Intent shareIntent = new Intent();shareIntent.setAction(Intent.ACTION_SEND);shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);shareIntent.setType("*/*");//适配7.0FileProviderif (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.0FileProviderprivate 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"/><applicationandroid: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的包名}.providergrantUriPermissions:必须是true,表示授予 URI 临时访问权限exported:必须是falseresource:中的@xml/provider_paths是我们接下来要添加的文件--><providerandroid: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"><Buttonandroid:id="@+id/btn_share_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="分享文本"android:layout_marginTop="10dp"/><Buttonandroid:id="@+id/btn_share_one_img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="分享单张图片"android:layout_marginTop="10dp"/><Buttonandroid:id="@+id/btn_share_mult_img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="分享多张图片"android:layout_marginTop="10dp"/><Buttonandroid:id="@+id/btn_share_to_qq"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="分享到qq"android:layout_marginTop="10dp"/><Buttonandroid: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();@Overrideprotected 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() {@Overridepublic void onClick(View view) {ShareIntentUtil.shareText(MainActivity.this,"这是一段分享的文字","分享文本");}});//分享单张图片findViewById(R.id.btn_share_one_img).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//Environment.getExternalStorageDirectory()=/storage/emulated/0Log.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() {@Overridepublic void onClick(View view) {//Environment.getExternalStorageDirectory()=/storage/emulated/0Log.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,"分享多张图片");}});//分享到qqfindViewById(R.id.btn_share_to_qq).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {ShareIntentUtil.shareTextTo(MainActivity.this,"这是一段分享的文字","分享到QQ",ShareIntentUtil.PACKAGE_QQ);}});//分享单个文件findViewById(R.id.btn_share_one_file).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//Environment.getExternalStorageDirectory()=/storage/emulated/0Log.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 instancerxPermissions.request(Manifest.permission.READ_EXTERNAL_STORAGE) //权限名称,多个权限之间逗号分隔开.subscribe(new Consumer<Boolean>() {@Overridepublic 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>() {@Overridepublic void accept(Throwable throwable) throws Exception {Log.e(TAG,"{accept}");//可能是授权异常的情况下的处理
                    }}, new Action() {@Overridepublic void run() throws Exception {Log.e(TAG,"{run}");//执行顺序——2
                    }});}
}

混淆配置

参考资料

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

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

Intent.resolveActivity

项目demo下载地址

https://github.com/haiyuKing/ShareWithSystemDemo

ShareIntentUtil【调用系统自带的分享的工具类】相关推荐

  1. 用原生JS实现网页调用系统自带的分享功能

    流量当下的网络大环境,如何让我们的网站更容易出现在网民的视野中?这里我们就用原生JS实现网页调用系统自带的分享功能,为网页增加一个分享功能! 语法参数: url 要共享的 URL( USVString ...

  2. ios开发调用系统自带的分享

    1.一般情况下提到分享,我们会想到去集成某些第三方的框架,例如很多第三方分享的集合例如友盟的,集成效果如下 这里只涉及到了常用的新浪.微信.及qq: 分享功能:三个平台都比较宽松,只有有appid,都 ...

  3. android安装自动打开网页,Android调用系统自带浏览器打开网页的实现方法

    Android调用系统自带浏览器打开网页的实现方法 在Android中可以调用自带的浏览器,或者指定一个浏览器来打开一个链接.只需要传入一个uri,可以是链接地址. 启动android默认浏览器 在A ...

  4. 安卓手机如何打开php文件夹,Android_Android中调用系统的文件浏览器及自制简单的文件浏览器,调用系统自带的文件浏览器- phpStudy...

    Android中调用系统的文件浏览器及自制简单的文件浏览器 调用系统自带的文件浏览器这很简单: /** 调用文件选择软件来选择文件 **/ private void showFileChooser() ...

  5. [转]mpvue中的小程序调用系统自带查看图片的功能

    mpvue中的小程序调用系统自带查看图片的功能 这里举个栗子: <template><div class="keting"><div class=&q ...

  6. Win7系统自带的录屏工具怎么打开操作教学分享

    Win7系统自带的录屏工具怎么打开操作教学分享.很多的用户不知道Win7系统其实有自带了一个录屏工具.我们通过代码打开它之后,就可以非常方便的进行内容录制了.一起来看看如何开启它的操作教学吧. 操作步 ...

  7. Android调用系统自带的文件管理器进行文件选择

    这几天在做的项目网盘.上传时需要用到调用系统自带的文件管理器来选择文件,后来就在考虑怎么调用,网上也搜了很久,没有很好的解决方法,后来在一瞬间发现了一篇不错的文章,借鉴了一下代码. [java] vi ...

  8. iOS程序中调用系统自带应用(短信,邮件,浏览器,地图,appstore,拨打电话,iTunes,iBooks )...

    在网上找到了下在记录下来以后方便用 在程序中调用系统自带的应用,比如我进入程序的时候,希望直接调用safar来打开一个网页,下面是一个简单的使用: 查看更多iPhone应用程序的调用和第三方应用程序的 ...

  9. 【安卓开发】调用系统原生的文件分享功能将文件分享给QQ或微信好友

    调用系统原生的文件分享功能将文件分享给QQ或微信好友 核心代码: //传入的fileName是文件名的全路径@SuppressLint("QueryPermissionsNeeded&quo ...

最新文章

  1. CCAI 2020 | 黄铁军:“仿真主义”下的人工智能发展之路
  2. python3语法手册_Python3 学习手册每日更新
  3. 集存款(复利单利)贷款为一体的计算器(最新版)
  4. HTTPS和TCP的关系
  5. LeetCode刷题实战(13):Roman to Integer
  6. 通用网站备案常见的备案场景及要求
  7. 计组之数据运算:8、c语言之强制类型转化、数据的存储与排序(大小端、字节对齐)
  8. 作用 react_react-styleguidist核心知识点详解
  9. 库克:iPhone 11在中国定价策略很成功 非常受欢迎
  10. svn增量打包部署_超详细的jenkins持续集成工作原理、功能、部署方式等介绍
  11. 与IP地址有关的那些点
  12. 【动态规划笔记】区间dp:括号匹配(删除字符和括号匹配)
  13. 适合新手绘制房间布置图的电脑软件
  14. 网管维修必备工具_7手机维修必备工具
  15. 计算机毕业设计java基于SSM超市订单管理系统
  16. Nginx代理高德API(无法地图选点)
  17. kali linux 磁盘,在硬盘上安装Kali Linux
  18. python解锁电脑屏幕_怎样解除电脑屏幕锁定_教你解除电脑屏幕锁定的方法-系统城...
  19. 手把手教你搭建SpringCloud项目(十六)集成Stream消息驱动
  20. Trinity简介(1)--用于无参考基因组的转录组de novo组装

热门文章

  1. 考研-英语经验贴2.0
  2. 关于微信卡券47001的问题
  3. 我爱无人机网 FH-0A编程编队无人机怎么样?使用什么语言?
  4. 紫薇星上的数据结构(7)
  5. 借助Zynq RFSoC DFE解决 5G 大规模部署难题
  6. soul网关系列(六):客户端注册soul流程分析
  7. Mezzanine多site管理问题
  8. 2008年8月6号,晴,今天天气已经变热了。少壮不努力,老大徒悲伤。 —— 汉乐府古辞《长歌行》
  9. 《FFmpeg从入门到精通》读书笔记(五)
  10. 非线性方程组求解方法,神经网络的非线性函数