溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用Android原生態(tài)實(shí)現(xiàn)分享轉(zhuǎn)發(fā)功能

發(fā)布時(shí)間:2021-12-08 17:06:17 來源:億速云 閱讀:107 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了如何使用Android原生態(tài)實(shí)現(xiàn)分享轉(zhuǎn)發(fā)功能,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

導(dǎo)讀:

之前剛學(xué)安卓時(shí),寫過一篇“Android調(diào)用系統(tǒng)shareAPI實(shí)現(xiàn)分享轉(zhuǎn)發(fā)功能”的文章,隨著安卓版本的迭代更新以及其他APP的優(yōu)化,安卓的這個(gè)shareAPI好像失效了,不怎么好使,已經(jīng)獲取不到有分享功能的APP列表,點(diǎn)擊分享也會直接崩潰。并不是說我之前那篇文章的代碼有錯(cuò),只能說是時(shí)代有了變化,舊的方法已經(jīng)不能滿足新的需求

 最近開發(fā)一個(gè)收款A(yù)PP,想把分享功能加入進(jìn)去,然后發(fā)現(xiàn)舊的方法已經(jīng)不行,這就難過了,網(wǎng)上一些大佬建議用第三方APP自帶的分享SDK,但是我覺得用第三方的SDK太麻煩了,每個(gè) APP都要申請接口賬號和接口密鑰,即便是使用其他人封裝好的分享框架,也是需要去申請賬號密鑰的,一點(diǎn)也不方便,還是喜歡安卓原生態(tài)寫法,簡單便捷、一勞永逸。

經(jīng)過我?guī)追芯浚罱K完美實(shí)現(xiàn)了,效果圖如下:

如何使用Android原生態(tài)實(shí)現(xiàn)分享轉(zhuǎn)發(fā)功能

 一、xml布局文件

1、res/layout目錄下創(chuàng)建share_dialog.xml

<?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:background="@drawable/shape_dialog_bg"
    android:orientation="vertical" >
 
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="分享到..." />
 
    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none" >
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
 
            <GridView
                android:id="@+id/sharePopupWindow_gridView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scrollbars="none" />
        </LinearLayout>
    </HorizontalScrollView>
 
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:alpha="0.3"
        android:background="#666" />
 
    <TextView
        android:id="@+id/sharePopupWindow_close"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="20dp"
        android:text="取消"
        android:textSize="16sp" />
 
</LinearLayout>

2、res/layout目錄下創(chuàng)建appinfo_item.xml

<?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="wrap_content"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingBottom="8dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="8dp">
 
    <ImageView
        android:id="@+id/appinfo_item_icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:scaleType="centerCrop"
        android:src="@drawable/logo"/>
 
    <TextView
        android:id="@+id/appinfo_item_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp"
        android:ellipsize="end"
        android:singleLine="true"
        android:textSize="12sp"
        android:text="分享到……"/>
</LinearLayout>

3、在res/values/styles.xml 中,添加以下代碼,用來實(shí)現(xiàn)彈出窗背景效果:

<style name="circleDialog" parent="android:style/Theme.Dialog">
        <!-- 背景透明,設(shè)置圓角對話框必須設(shè)置背景透明,否則四角會有背景色小塊-->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 沒有標(biāo)題 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 背景模糊 -->
        <item name="android:backgroundDimEnabled">true</item>
</style>

二、創(chuàng)建一個(gè)實(shí)體類 AppInfo.java,用來保存應(yīng)用信息

package net.zy13.skhelper.entity;
 
import android.graphics.drawable.Drawable;
 
/**
 * APP信息實(shí)體類
 */
public class AppInfo {
    private String appName;
    private String packageName;
    private String versionName;
    private int versionCode;
    private String launchClassName;
    private Drawable appIcon;
 
    public String getAppName() {
        return appName;
    }
 
    public void setAppName(String appName) {
        this.appName = appName;
    }
 
    public String getPackageName() {
        return packageName;
    }
 
    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }
 
    public String getVersionName() {
        return versionName;
    }
 
    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }
 
    public int getVersionCode() {
        return versionCode;
    }
 
    public void setVersionCode(int versionCode) {
        this.versionCode = versionCode;
    }
 
    public String getLaunchClassName() {
        return launchClassName;
    }
 
    public void setLaunchClassName(String launchClassName) {
        this.launchClassName = launchClassName;
    }
 
    public Drawable getAppIcon() {
        return appIcon;
    }
 
    public void setAppIcon(Drawable appIcon) {
        this.appIcon = appIcon;
    }
}

三、重寫PopupWindow控件SharePopupWindow.java,自定義分享的彈窗

package net.zy13.skhelper.view;
 
import java.io.File;
import java.util.List;
 
import android.app.ActionBar.LayoutParams;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
 
import androidx.core.content.FileProvider;
 
import net.zy13.skhelper.R;
import net.zy13.skhelper.adapter.AppInfoAdapter;
import net.zy13.skhelper.entity.AppInfo;
import net.zy13.skhelper.utils.LogUtil;
import net.zy13.skhelper.utils.MapTable;
import net.zy13.skhelper.utils.ShareUtil;
 
public class SharePopupWindow extends PopupWindow {
 
    //每行顯示多少個(gè)
    private static final int NUM = 5;
 
    private View mMenuView;
    private GridView mGridView;
    private TextView mTextViewClose;
    private AppInfoAdapter mAdapter;
 
    private List<AppInfo> mAppinfoList;
 
    private String imgpath;
    private String shareTitle;
    private String shareContent;
    public void setImgpath(String imgpath) {
        this.imgpath = imgpath;
    }
    public void setShareTitle(String shareTitle) {
        this.shareTitle = shareTitle;
    }
    public void setShareContent(String shareContent) {
        this.shareContent = shareContent;
    }
 
    /**
     * 構(gòu)造函數(shù)
     * @param context
     */
    public SharePopupWindow(final Context context) {
        super(context);
        LayoutInflater inflater = (LayoutInflater) context  .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mMenuView = inflater.inflate(R.layout.share_dialog, null);
        //獲取控件
        mGridView=(GridView) mMenuView.findViewById(R.id.sharePopupWindow_gridView);
        mTextViewClose=(TextView) mMenuView.findViewById(R.id.sharePopupWindow_close);
        //獲取所有的非系統(tǒng)應(yīng)用
        mAppinfoList = ShareUtil.getAllApps(context);
        //適配GridView
        mAdapter=new AppInfoAdapter(context, mAppinfoList);
        mGridView.setAdapter(mAdapter);
 
        //修改GridView
        changeGridView(context);
 
        mGridView.setOnItemClickListener(new OnItemClickListener() {
 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                                    long id) {
                // TODO Auto-generated method stub
                //使用其他APP打開文件
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                intent.setAction(Intent.ACTION_VIEW);
                //LogUtil.debug("圖片地址:"+imgpath);
                //我這里分享的是圖片,如果你要分享鏈接和文本,可以在這里自行發(fā)揮
                Uri uri = FileProvider.getUriForFile(context, "fileprovider", new File(imgpath));
                intent.setDataAndType(uri, MapTable.getMIMEType(imgpath));
                context.startActivity(intent);
            }
        });
        //取消按鈕
        mTextViewClose.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                dismiss();
            }
        });
        //設(shè)置SelectPicPopupWindow的View
        this.setContentView(mMenuView);
        //設(shè)置SelectPicPopupWindow彈出窗體的寬
        this.setWidth(LayoutParams.FILL_PARENT);
        //設(shè)置SelectPicPopupWindow彈出窗體的高
        this.setHeight(LayoutParams.WRAP_CONTENT);
        //設(shè)置SelectPicPopupWindow彈出窗體可點(diǎn)擊
        this.setFocusable(true);
        //設(shè)置窗口外也能點(diǎn)擊(點(diǎn)擊外面時(shí),窗口可以關(guān)閉)
        this.setOutsideTouchable(true);
        //設(shè)置SelectPicPopupWindow彈出窗體動畫效果
        this.setAnimationStyle(R.style.circleDialog);
        //實(shí)例化一個(gè)ColorDrawable顏色為半透明
        ColorDrawable dw = new ColorDrawable(0x00000000);
        //設(shè)置SelectPicPopupWindow彈出窗體的背景
        this.setBackgroundDrawable(dw);
    }
 
    /**
     * 將GridView改成單行橫向布局
     */
    private void changeGridView(Context context) {
        // item寬度
        int itemWidth = dip2px(context, 90);
        // item之間的間隔
        int itemPaddingH = dip2px(context, 1);
        //計(jì)算一共顯示多少行;
        int size = mAppinfoList.size();
        //int row=(size<=NUM) ? 1 :( (size%NUM>0) ? size/NUM+1 : size/NUM );
        //每行真正顯示多少個(gè)
        int rowitem = (size<NUM)?size:NUM;
        // 計(jì)算GridView寬度
        int gridviewWidth = rowitem * (itemWidth + itemPaddingH);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                gridviewWidth, LinearLayout.LayoutParams.MATCH_PARENT);
        mGridView.setLayoutParams(params);
        mGridView.setColumnWidth(itemWidth);
        mGridView.setHorizontalSpacing(itemPaddingH);
        mGridView.setStretchMode(GridView.NO_STRETCH);
        mGridView.setNumColumns(rowitem);
    }
 
    /**
     * 根據(jù)手機(jī)的分辨率從 dp 的單位 轉(zhuǎn)成為 px(像素)
     * @param context   上下文
     * @param dpValue   dp值
     * @return  px值
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
 
}

四、使用provider

1、在清單文件AndroidManifest.xml的<application>標(biāo)簽內(nèi)添加provider

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

注意:要與activity標(biāo)簽同級 

如何使用Android原生態(tài)實(shí)現(xiàn)分享轉(zhuǎn)發(fā)功能

 2、在res/xml目錄添加filepaths.xml,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!--
    1、name對應(yīng)的屬性值,開發(fā)者可以自由定義;
    2、path對應(yīng)的屬性值,當(dāng)前external-path標(biāo)簽下的相對路徑
    -->
    <!--1、對應(yīng)內(nèi)部內(nèi)存卡根目錄:Context.getFileDir()-->
    <files-path
        name="int_root"
        path="/" />
    <!--2、對應(yīng)應(yīng)用默認(rèn)緩存根目錄:Context.getCacheDir()-->
    <cache-path
        name="app_cache"
        path="/" />
    <!--3、對應(yīng)外部內(nèi)存卡根目錄:Environment.getExternalStorageDirectory()-->
    <external-path
        name="ext_root"
        path="Documents/" />
    <!--4、對應(yīng)外部內(nèi)存卡根目錄下的APP公共目錄:Context.getExternalFileDir(Environment.DIRECTORY_PICTURES)-->
    <external-files-path
        name="ext_pub"
        path="/" />
    <!--5、對應(yīng)外部內(nèi)存卡根目錄下的APP緩存目錄:Context.getExternalCacheDir()-->
    <external-cache-path
        name="ext_cache"
        path="/" />
</paths>

五、寫一個(gè)工具類 

ShareUtil.java

package net.zy13.skhelper.utils;
 
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
 
import net.zy13.skhelper.MainApplication;
import net.zy13.skhelper.entity.AppInfo;
 
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
public class ShareUtil {
    /**
     * 查詢手機(jī)內(nèi)所有的應(yīng)用列表
     * @param context
     * @return
     */
    public static List<AppInfo> getAllApps(Context context) {
        List<AppInfo> appList = new ArrayList<AppInfo>();
        PackageManager pm=context.getPackageManager();
        List<PackageInfo> packages = pm.getInstalledPackages(0);
        for (int i = 0;i< packages.size();i++) {
            PackageInfo packageInfo = packages.get(i);
            AppInfo tmpInfo = new AppInfo();
            tmpInfo.setAppName(packageInfo.applicationInfo.loadLabel(pm).toString());
            tmpInfo.setPackageName(packageInfo.packageName);
            tmpInfo.setVersionName(packageInfo.versionName);
            tmpInfo.setVersionCode(packageInfo.versionCode);
            tmpInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(pm));
            //如果非系統(tǒng)應(yīng)用,則添加至appList
            if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                //排除當(dāng)前應(yīng)用(替換成你的應(yīng)用包名即可)
                if(!packageInfo.packageName.equals("net.zy13.skhelper")) {
                    appList.add(tmpInfo);
                }
            }
        }
        return  appList;
    }
    /**
     * 保存圖片到緩存里
     * @param bitmap
     * @return
     */
    public static String SaveTitmapToCache(Bitmap bitmap){
        // 默認(rèn)保存在應(yīng)用緩存目錄里 Context.getCacheDir()
        File file=new File(MainApplication.getAppContext().getCacheDir(),System.currentTimeMillis()+".png");
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file.getPath();
    }
}

六、GridView的適配器 AppInfoAdapter.java

package net.zy13.skhelper.adapter;
 
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
import net.zy13.skhelper.R;
import net.zy13.skhelper.entity.AppInfo;
 
import java.util.List;
 
public class AppInfoAdapter extends BaseAdapter {
 
    private Context context;
    private List<AppInfo> mAppinfoList;
    private OnItemClickListener mOnItemClickLitener;
 
    public AppInfoAdapter(Context context, List<AppInfo> mAppinfoList) {
        super();
        this.context = context;
        this.mAppinfoList = mAppinfoList;
    }
 
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return mAppinfoList.size();
    }
 
    @Override
    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }
 
    @SuppressLint("NewApi")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        AppInfo appInfo = mAppinfoList.get(position);
        // 加載布局
        View view;
        ViewHolder viewHolder;
        if (convertView == null) {
            view = LayoutInflater.from(context).inflate(R.layout.appinfo_item, null);
            viewHolder = new ViewHolder(view);
            // 將ViewHolder存儲在View中
            view.setTag(viewHolder);
        } else {
            view = convertView;
            // 重新獲取ViewHolder
            viewHolder = (ViewHolder) view.getTag();
 
        }
        //設(shè)置控件的值
        viewHolder.imageViewIcon.setImageDrawable(appInfo.getAppIcon());
        String name=appInfo.getAppName();
        viewHolder.textViewName.setText(name);
        return view;
    }
 
    class ViewHolder {
        ImageView imageViewIcon;
        TextView textViewName;
 
        public ViewHolder(View view) {
            this.imageViewIcon = (ImageView) view.findViewById(R.id.appinfo_item_icon);
            this.textViewName = (TextView) view.findViewById(R.id.appinfo_item_name);
        }
    }
 
}

七、自定義分享窗口SharePopupWindow的調(diào)用 

 private LinearLayout mLayoutRoot;
 private ImageView mImageView;
 
//獲取根布局
mLayoutRoot=(LinearLayout)view.findViewById(R.id.LayoutRoot);
//獲取圖片控件
mImageView=(ImageView)view.findViewById(R.id.image_qrcode);
 
 
// 獲取ImageView圖片
mImageView.setDrawingCacheEnabled(true);
Bitmap bitmap =Bitmap.createBitmap(mImageViewQrcode.getDrawingCache());
mImageView.setDrawingCacheEnabled(false);
String imgpath=ShareUtil.SaveTitmapToCache(bitmap);
//實(shí)例化分享窗口
SharePopupWindow spw = new SharePopupWindow(mContext);
spw.setImgpath(imgpath);
// 顯示窗口
spw.showAtLocation(mLayoutRoot, Gravity.BOTTOM, 0, 0);

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“如何使用Android原生態(tài)實(shí)現(xiàn)分享轉(zhuǎn)發(fā)功能”這篇文章對大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI