我是靠谱客的博主 野性啤酒,这篇文章主要介绍Android原生态实现分享转发功能实例,现在分享给大家,希望可以做个参考。

导读:

之前刚学安卓时,写过一篇“Android调用系统shareAPI实现分享转发功能”的文章,随着安卓版本的迭代更新以及其他APP的优化,安卓的这个shareAPI好像失效了,不怎么好使,已经获取不到有分享功能的APP列表,点击分享也会直接崩溃。并不是说我之前那篇文章的代码有错,只能说是时代有了变化,旧的方法已经不能满足新的需求

 最近开发一个收款APP,想把分享功能加入进去,然后发现旧的方法已经不行,这就难过了,网上一些大佬建议用第三方APP自带的分享SDK,但是我觉得用第三方的SDK太麻烦了,每个 APP都要申请接口账号和接口密钥,即便是使用其他人封装好的分享框架,也是需要去申请账号密钥的,一点也不方便,还是喜欢安卓原生态写法,简单便捷、一劳永逸。

经过我几番研究,最终完美实现了,效果图如下:

 一、xml布局文件

1、res/layout目录下创建share_dialog.xml

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?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目录下创建appinfo_item.xml

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?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 中,添加以下代码,用来实现弹出窗背景效果:

复制代码
1
2
3
4
5
6
7
8
<style name="circleDialog" parent="android:style/Theme.Dialog"> <!-- 背景透明,设置圆角对话框必须设置背景透明,否则四角会有背景色小块--> <item name="android:windowBackground">@android:color/transparent</item> <!-- 没有标题 --> <item name="android:windowNoTitle">true</item> <!-- 背景模糊 --> <item name="android:backgroundDimEnabled">true</item> </style>

二、创建一个实体类 AppInfo.java,用来保存应用信息

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package net.zy13.skhelper.entity; import android.graphics.drawable.Drawable; /** * APP信息实体类 */ 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,自定义分享的弹窗

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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 { //每行显示多少个 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; } /** * 构造函数 * @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); //获取所有的非系统应用 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); //我这里分享的是图片,如果你要分享链接和文本,可以在这里自行发挥 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(); } }); //设置SelectPicPopupWindow的View this.setContentView(mMenuView); //设置SelectPicPopupWindow弹出窗体的宽 this.setWidth(LayoutParams.FILL_PARENT); //设置SelectPicPopupWindow弹出窗体的高 this.setHeight(LayoutParams.WRAP_CONTENT); //设置SelectPicPopupWindow弹出窗体可点击 this.setFocusable(true); //设置窗口外也能点击(点击外面时,窗口可以关闭) this.setOutsideTouchable(true); //设置SelectPicPopupWindow弹出窗体动画效果 this.setAnimationStyle(R.style.circleDialog); //实例化一个ColorDrawable颜色为半透明 ColorDrawable dw = new ColorDrawable(0x00000000); //设置SelectPicPopupWindow弹出窗体的背景 this.setBackgroundDrawable(dw); } /** * 将GridView改成单行横向布局 */ private void changeGridView(Context context) { // item宽度 int itemWidth = dip2px(context, 90); // item之间的间隔 int itemPaddingH = dip2px(context, 1); //计算一共显示多少行; int size = mAppinfoList.size(); //int row=(size<=NUM) ? 1 :( (size%NUM>0) ? size/NUM+1 : size/NUM ); //每行真正显示多少个 int rowitem = (size<NUM)?size:NUM; // 计算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); } /** * 根据手机的分辨率从 dp 的单位 转成为 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>标签内添加provider

复制代码
1
2
3
4
5
6
7
8
9
<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标签同级 

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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 1、name对应的属性值,开发者可以自由定义; 2、path对应的属性值,当前external-path标签下的相对路径 --> <!--1、对应内部内存卡根目录:Context.getFileDir()--> <files-path name="int_root" path="/" /> <!--2、对应应用默认缓存根目录:Context.getCacheDir()--> <cache-path name="app_cache" path="/" /> <!--3、对应外部内存卡根目录:Environment.getExternalStorageDirectory()--> <external-path name="ext_root" path="Documents/" /> <!--4、对应外部内存卡根目录下的APP公共目录:Context.getExternalFileDir(Environment.DIRECTORY_PICTURES)--> <external-files-path name="ext_pub" path="/" /> <!--5、对应外部内存卡根目录下的APP缓存目录:Context.getExternalCacheDir()--> <external-cache-path name="ext_cache" path="/" /> </paths>

五、写一个工具类 

ShareUtil.java

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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 { /** * 查询手机内所有的应用列表 * @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)); //如果非系统应用,则添加至appList if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { //排除当前应用(替换成你的应用包名即可) if(!packageInfo.packageName.equals("net.zy13.skhelper")) { appList.add(tmpInfo); } } } return appList; } /** * 保存图片到缓存里 * @param bitmap * @return */ public static String SaveTitmapToCache(Bitmap bitmap){ // 默认保存在应用缓存目录里 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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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(); } //设置控件的值 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的调用 

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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); //实例化分享窗口 SharePopupWindow spw = new SharePopupWindow(mContext); spw.setImgpath(imgpath); // 显示窗口 spw.showAtLocation(mLayoutRoot, Gravity.BOTTOM, 0, 0);

到此这篇关于Android原生态实现分享转发功能实例的文章就介绍到这了,更多相关Android分享转发功能内容请搜索靠谱客以前的文章或继续浏览下面的相关文章希望大家以后多多支持靠谱客!

最后

以上就是野性啤酒最近收集整理的关于Android原生态实现分享转发功能实例的全部内容,更多相关Android原生态实现分享转发功能实例内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(103)

评论列表共有 0 条评论

立即
投稿
返回
顶部