摘要 安卓系统本身可以很简便的实现分享功能,因为我们只需向startActivity传递一个 ACTION_SEND 的Intent,系统就为我们弹出一个应用程序列表,如果我们再指定intent为chooser的方式,那么这个列表就能每次都出现而且都是相同的操作。 利用系统的api实现分享的代
安卓系统本身可以很简便的实现分享功能,因为我们只需向startActivity传递一个ACTION_SEND
的Intent,系统就为我们弹出一个应用程序列表,如果我们再指定intent为chooser的方式,那么这个列表就就会有个指定的标题,如下:
这就是分享界面。
其实凡是以隐式intent调用activity,如果能处理该intent的应用有多个的话,都会出现一个选择应用的对话框,这种对话框除了列出应用列表,还为你提供是永久选择,还是只是这次选择。比如我们发送了这样一个浏览网页的intent:
1
2
3
4
|
Intent i =
new
Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
|
那么系统会为我们列出能接收这个intent的应用(一般浏览器都会实现,相当于一种约定),界面如下:
注意上面的对话框只是单纯列出了应用,而且比分享对话框还多了两个选择方式的按钮,所以仅仅这样还不符合分享功能的需求。
分享的需求有两点:
每次都列出所有应用;
不再提示只是一次选择还是永久选择;
为此,我们需要通过Intent来创建chooser:
1
|
Intent chooserIntent = Intent.createChooser(intent,
"Select app to share"
);
|
intent的createChooser
方法调用后,上面提到的两个不符合需求的问题就不存在了,其实这就是分享功能的本质,他只不过是利用了Intent的机制而已。
利用系统的api实现分享的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Intent intent =
new
Intent(Intent.ACTION_SEND);
intent.setType(
"text/plain"
);
intent.putExtra(Intent.EXTRA_TITLE, title);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, content);
Intent chooserIntent = Intent.createChooser(intent,
"Select app to share"
);
if
(chooserIntent ==
null
) {
return
;
}
try
{
startActivity(chooserIntent);
}
catch
(android.content.ActivityNotFoundException ex) {
Toast.makeText(
this
,
"Can't find share component to share"
, Toast.LENGTH_SHORT).show();
}
|
一般,通过上面的代码,提供的分享方式有各种应用:邮件,信息,蓝牙,微博,Twitter,二维码扫描器等。
-
但是,第一:我想过滤掉蓝牙,
-
其次:我想对邮件分享详细的内容,对信息和微博等分享较简短的内容,对二维码扫描器只分享URL。
解决的办法是得到所有能处理ACTION_SEND
的应用程序包名,然后根据名字来过滤或者特殊处理。主要用到getPackageManager().queryIntentActivities
方法。
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
|
String contentDetails =
""
;
String contentBrief =
""
;
String shareUrl =
""
;
Intent it =
new
Intent(Intent.ACTION_SEND);
it.setType(
"text/plain"
);
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(it, 0);
if
(!resInfo.isEmpty()) {
List<Intent> targetedShareIntents =
new
ArrayList<Intent>();
for
(ResolveInfo info : resInfo) {
Intent targeted =
new
Intent(Intent.ACTION_SEND);
targeted.setType(
"text/plain"
);
ActivityInfo activityInfo = info.activityInfo;
// judgments : activityInfo.packageName, activityInfo.name, etc.
if
(activityInfo.packageName.contains(
"bluetooth"
) || activityInfo.name.contains(
"bluetooth"
)) {
continue
;
}
if
(activityInfo.packageName.contains(
"gm"
) || activityInfo.name.contains(
"mail"
)) {
targeted.putExtra(Intent.EXTRA_TEXT, contentDetails);
}
else
if
(activityInfo.packageName.contains(
"zxing"
)) {
targeted.putExtra(Intent.EXTRA_TEXT, shareUrl);
}
else
{
targeted.putExtra(Intent.EXTRA_TEXT, contentBrief);
}
targeted.setPackage(activityInfo.packageName);
targetedShareIntents.add(targeted);
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0),
"Select app to share"
);
if
(chooserIntent ==
null
) {
return
;
}
// A Parcelable[] of Intent or LabeledIntent objects as set with
// putExtra(String, Parcelable[]) of additional activities to place
// a the front of the list of choices, when shown to the user with a
// ACTION_CHOOSER.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(
new
Parcelable[] {}));
try
{
startActivity(chooserIntent);
}
catch
(android.content.ActivityNotFoundException ex) {
Toast.makeText(
this
,
"Can't find share component to share"
, Toast.LENGTH_SHORT).show();
}
}
|
如果我们想指定一个应用来分享,那么可以将上面的代码做些修改:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
private void initShareIntent(String type) {
boolean found =
false
;
Intent share =
new
Intent(android.content.Intent.ACTION_SEND);
share.setType(
"image/jpeg"
);
// gets the list of intents that can be loaded.
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0);
if
(!resInfo.isEmpty()){
for
(ResolveInfo info : resInfo) {
if
(info.activityInfo.packageName.toLowerCase().contains(type) ||
info.activityInfo.name.toLowerCase().contains(type) ) {
share.putExtra(Intent.EXTRA_SUBJECT,
"subject"
);
share.putExtra(Intent.EXTRA_TEXT,
"your text"
);
share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(
new
File(myPath)) );
// Optional, just if you wanna share an image.
share.setPackage(info.activityInfo.packageName);
found =
true
;
break
;
}
}
if
(!found)
return
;
startActivity(Intent.createChooser(share,
"Select"
));
}
}
|
然后在需要分享的地方加上:
1
|
initShareIntent(
"twi"
);
|
其实这种方法的前提是你必须知道某个应用的包名大致是什么样,比如qq的微信和微博的包名其实没有qq
initShareIntent(
"qq"
);是没有用的,你可以先将他们打印出来看长什么样子,然后在调用。以下是我总结的一些常用应用包名:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
case
ID_QQWEIBO:
initShareIntent(
"com.tencent.wblog"
);
break
;
case
ID_WEIXIN:
initShareIntent(
"com.tencent.mm"
);
break
;
case
ID_EVERNOTE:
initShareIntent(
"evernote"
);
break
;
case
ID_SINAWEIBO:
initShareIntent(
"com.sina.weibo"
);
break
;
case
ID_RENREN:
initShareIntent(
"renren"
);
break
;
case
ID_QQ:
initShareIntent(
"tencent.mobileqq"
);
break
;
|