ShareIntentUtil【調用系統自帶的分享的工具類】

版權聲明:本文爲HaiyuKing原創文章,轉載請註明出處!html

前言

根據參考資料的文章,整理了調用系統自帶分享的工具類(實現了適配7.0FileProvider的功能),須要搭配《Android6.0運行時權限(基於RxPermission開源庫)》。java

效果圖

代碼分析

須要注意的代碼主要包括:react

ShareIntentUtil中適配7.0FileProvider的相關代碼。android

使用步驟

1、項目組織結構圖

注意事項:git

一、  導入類文件後須要change包名以及從新import R文件路徑github

二、  Values目錄下的文件(strings.xml、dimens.xml、colors.xml等),若是項目中存在,則複製裏面的內容,不要整個覆蓋微信

2、導入步驟

(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開源庫)》導入相關文件。

3、使用方法

佈局文件

<?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
                    }
                });
    }
}

混淆配置

app

參考資料

Android分享---調用系統自帶的分享功能ide

探索Android調用系統的分享功能工具

Intent.resolveActivity

項目demo下載地址

https://github.com/haiyuKing/ShareWithSystemDemo

相關文章
相關標籤/搜索