Android --- ACTION_SEND调用系统分享过滤指定app(解决file域的访问限制)

       手机可以使用微信、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;
}

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值