android系统分享的自定义功能

作者: LeoYe168 | 来源:发表于2017-08-09 16:04 被阅读411次

分享功能是app中特别常见的功能,国内的app基本都支持分享到微信 QQ等主流的社交应用。至于分享功能的实现大多是使用第三方的share sdk一步到位,或者分享的app比较少比如就一个微信 那通常使用微信sdk的分享模块即可。但其实android系统就给我们提供过一种分享的实现方式,代码也比较简单如下

        Intent share = new Intent(Intent.ACTION_SEND);
        share.setType("text/plain");
        share.putExtra(Intent.EXTRA_TEXT, shareText);
        share.putExtra(Intent.EXTRA_SUBJECT, shareSubject);

        if (uri != null) {
            share.setType("image/*");
            share.putExtra(Intent.EXTRA_STREAM, uri);
        }
        context.startActivity(Intent.createChooser(share, title));
IMG_20170406_160025.jpg

系统提供的短短不到十行代码,将分享列表 数据 展示 点击 跳转 跳转后分享内容的分享等一系列动作都集合完成了。这样确实给人干净利索的感觉,但随之问题也来了比如我分享列表中只有特定几个app,甚至把某个app放在第一个,还有点击Facebook的分享后分享方式我想用facebooksdk自带的,等等一些列自定义功能完成就比较麻烦。

对个别app的分享特别处理

从以上的代码可以看出,google官方定义出分享的key value一一对应规则。比如Intent.EXTRA_STREAM对应为分享图片的uri,Intent.EXTRA_TEXT对应为分享的text文本。从道理上讲如果分享到的app都遵循google定义的这规则我们就能通过官方这代码实现分享到所有app的功能。然而理想很丰满现实很骨感,比如我们项目中要求分享到的facebook就压根不遵守这规则,我们想实现分享到Facebook就必须用其sdk实现。于是我们就需要在分享列表中点击Facebook是单独走Facebook的分享逻辑。

  • 常规思维这是一个列表,我们监听列表item的点击事件即可,然而从实现该分享列表的代码 可以看出没有类似listview recyclerview控件,也没有adapter,扒了下源码和google找不到item的点击事件的监听,故该方案放弃了
  • 所以只能采用了自己实现分享列表,然后监听分享列表item点击事件单独处理的方式,也是符合常规思路

第一步:获取分享列表的数据

        private static List<List<ResolveInfo>> getShareActivities() {
        Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
        sharingIntent.setType("text/plain");
        PackageManager pm = App.getInstance().getPackageManager();
        List<List<ResolveInfo>> listArrayList = new ArrayList<>();
        List<ResolveInfo> activityList = pm.queryIntentActivities(sharingIntent, 0);
        List<ResolveInfo> newActivityList = new ArrayList<>();

        for (Iterator<ResolveInfo> it = activityList.iterator(); it.hasNext(); ) {
            ResolveInfo info = it.next();
            //过滤出facebook google+  whatapp  twitter 分享app单独处理
            LogUtils.e("+++", info.activityInfo.packageName);
            if (info.activityInfo.packageName.equals("com.android.bluetooth") || info.activityInfo.packageName.equals("com.android.nfc") || info.activityInfo.packageName.equals("com.facebook.katana") || info.activityInfo.packageName.equals("com.google.android.apps.plus") || info.activityInfo.packageName.equals("com.facebook.orca") || info.activityInfo.packageName.contains("whatsapp") || info.activityInfo.packageName.equals("com.twitter.android")) {
                if (info.activityInfo.packageName.equals("com.android.bluetooth") || info.activityInfo.packageName.equals("com.android.nfc")) {
                    it.remove();
                } else {
                    newActivityList.add(info);
                    it.remove();
                }
            }
        }
        //增加一条other数据
        newActivityList.add(null);
        listArrayList.add(newActivityList);
        listArrayList.add(activityList);
        return listArrayList;
    }

第二步:构建分享的列表,且定义点击事件等

public static void systemShareDialog(List<ResolveInfo> packages, Context context, String title, String shareText) {
        List<Intent> targetIntents = new ArrayList<Intent>();
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.setType("text/plain");
        SPM spm = new SPM();

        for (ResolveInfo candidate : packages) {
            String packageName = candidate.activityInfo.packageName;
            Intent target = new Intent(android.content.Intent.ACTION_SEND);
            target.setType("text/plain");
            target.putExtra(Intent.EXTRA_TEXT, shareText);
            //target.setPackage(packageName);
            //t will be able to handle the case of multiple activities within the same app that can handle this intent. Otherwise, a weird item of "Android System" will be shown
            target.setComponent(new ComponentName(packageName, candidate.activityInfo.name));

            targetIntents.add(target);
        }
//        createchooser时使用targetIntents.remove(0)即传入targetIntents的第一个intent,并将其移除,
//
//        否则执行chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {}));添加后启动时会出现两个相同的应用
        Intent chooserIntent = Intent.createChooser(targetIntents.remove(0), title);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[]{}));
        context.startActivity(chooserIntent);

    }

总结

至此完成了基于android系统提供的分享方式上的扩展改造,自定义分享列表数据展示 自定义点击后的分享形式等等都可以实现。。其实此功能中Intent.createChooser所做工作还是蛮多的,有兴趣童鞋可以再去扒下起源码,看具体实现和到底做了哪些工作。本人已扒过然后 恍然大悟,欢迎交流。

项目demo链接

相关文章

  • Android开发之分享功能(一)

    1.实现系统自带的分享功能 使用android系统提供的分享功能:点击分享按钮,系统会自动获取手机内提供分享功能的...

  • android系统分享的自定义功能

    分享功能是app中特别常见的功能,国内的app基本都支持分享到微信 QQ等主流的社交应用。至于分享功能的实现大多是...

  • ITelephony.endCall 混淆后挂断电话失败

    android开发中定制系统app,自定义拨号打电话功能,在混淆后发现ITelephony.endCall返回的是...

  • App开启QQ微信传文件

    Android利用系统系统自带文件分享功能[https://blog.csdn.net/joedan0104/ar...

  • Android系统分享功能

    Android系统是自带分享功能的,不过也有一定的局限性,可以分享图片,文字,视频,音频等,也可以分享多图,但是不...

  • Android自定义相机

    CustomCamera android自定义相机 功能描述: 主要可自定义相机的各类按钮布局 相机拍照缩放功能 ...

  • 自定义MediaPlayer控制组件

    一款自定义的MediaControl组件,替换Android系统自带的控制组件,控制视频播放、快进、暂停等功能 A...

  • 自定义MediaPlayer控制组件

    一款自定义的MediaControl组件,替换Android系统自带的控制组件,控制视频播放、快进、暂停等功能 A...

  • 2019-08-12

    利用 Android 系统原生 API 实现分享功能 石先 关注 3.4 2017.04.17 11:23* 字数...

  • 自定义分享功能

    目前大部分Android App中都具有分享功能,用户可以将自己喜欢的文章分享到朋友圈或微博。Android系统本...

网友评论

  • 57f9d9d03c02:非得申请开发者才能接微信的分享么,这也太复杂了,有没有比较简单的可以分享txt文件出去的方法
    LeoYe168:@凌_86db 国内强大的share sdk应该可以

本文标题:android系统分享的自定义功能

本文链接:https://www.haomeiwen.com/subject/orjqattx.html