手机可以使用微信、QQ、蓝牙等应用对文字、图片等资源进行分享。安卓系统本身可以很简便的实现分享功能,因为我们只需向startActivity传递一个 ACTION_SEND 的Intent,系统就为我们弹出一个应用程序列表,如果我们再指定intent为chooser的方式,那么这个列表就能每次都出现而且都是相同的操作。
使用ACTION_SEND弹出的应用程序列表展示的是系统中所有可以进行分享的应用,本文分享的是过滤掉指定的应用不展示在应用程序列表中。
使用ACTION_SEND弹出应用程序列表进行文件分享
//new一个intent
Intent intent = new Intent();
//ACTION_SEND:该action表明该intent用于从一个activity发送数据到另外一个activity的,甚至可以是跨进程的数据发送
intent.setAction(Intent.ACTION_SEND);
//放入分享内容
intent.putExtra(Intent.EXTRA_TEXT,"文字分享");
//设置分享的类型
intent.setType("text/plain");
//最后通过createChooser展示符合分享条件的应用列表
startActivity(Intent.createChooser(intent,"选择分享应用"));
如果想要去掉蓝牙的分享方式
可以通过获取可分享列表然后再添加内容
//获取匹配的应用列表信息
List<ResolveInfo> resolveInfos = this.getPackageManager().queryIntentActivities(intent,0);
//设置一个集合存放过滤指定应用后的应用集合
List<Intent> targetedShareIntents = new ArrayList<Intent>();
//遍历这个集合,过滤掉我们不想要分享的应用
for (ResolveInfo info : resolveInfos) {
Intent targeted = new Intent();
targeted.setType("text/plain");
//获取应用info
ActivityInfo activityInfo = info.activityInfo;
//过滤掉蓝牙分享
if (activityInfo.packageName.contains("bluetooth") || activityInfo.name.contains("bluetooth")) {
continue;
}
//将过滤后的应用方法targeted中
targeted.setPackage(activityInfo.packageName);
//将targeted放到预先new好的targetedShareIntents集合中
targetedShareIntents.add(targeted);
}
//显示一个供用户选择的应用列表
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
//最终展示符合createChooser第一个参数的应用以及由EXTRA_INTENT_INTENTS指定的应用
chooserIntent.putExtra(Intent.EXTRA_INTENT,targetedShareIntents.remove(0));
if (chooserIntent == null) {
return;
}
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[] {}));
startActivity(Intent.createChooser(chooserIntent,"选择分享应用"));
但是这样写会存在很大的问题。
在Android 7.0及以上系统,限制了file域的访问,导致进行intent分享的时候,会报错甚至崩溃。
我们需要在App启动的时候在Application的onCreate方法中添加如下代码,解除对file域访问的限制:
if(Build.VERSION.SDK_INT >= 24) {
Builder builder = new Builder();
StrictMode.setVmPolicy(builder.build());
}
Google表示,在“N”版本之后您可以使用黑名单的方式来代替白名单。
我们可以使用以下方法进行过滤(代码中有太多地方进行了ACTION_SEND调用,所以我将方法写进工具类中)
public static Intent FilterBluetooth(Intent intent, String intentType, PackageManager pm){
Intent chooser = Intent.createChooser(intent, "Complete action using");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ArrayList<ComponentName> targets = new ArrayList<>();
//Remove bluetooth which has a broken share intent
for (ResolveInfo candidate : pm.queryIntentActivities(intent, 0)) {
String packageName = candidate.activityInfo.packageName;
String AppName = candidate.activityInfo.name;
if (packageName.toLowerCase().contains("bluetooth")) {
targets.add(new ComponentName(packageName, AppName));
}
}
chooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, targets.toArray(new ComponentName[0]));
}
return chooser;
}