兼容微信v6.7.3|v7.0.x等版本的朋友圈多图分享方案

Github 查看源码

本库经过几个版本的升级,当前的分享逻辑和本文中略有不同,但整体思想是一致的,实际方案请阅读源码

无法分享到微信

前些日子微信更新到了 v6.7.3 版本,传统的多图分享方式已经无效了。

微信 v6.7.3 版本以前的方案

微信在 v6.7.3 以前的版本提供了从系统相册分享多图到朋友圈的接口,具体使用如下:

val intent = Intent()
intent.action = Intent.ACTION_SEND_MULTIPLE
intent.component = ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareToTimeLineUI")
intent.type = "image/*"
intent.putStringArrayListExtra(Intent.EXTRA_TEXT, arrayListOf(text))
intent.putExtra("Kdescription", text)
// 传递多张图片的 Uri 。
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList)
startActivity(intent)

使用以上代码,在微信 v6.7.3 以前可以正常分享,但是如果用户把微信更新到 v6.7.3 版本,再使用该分案分享多图就只能看到上面那张图了。

跳转微信 v6.7.3 图文分享界面

虽然 v6.7.3 不能直接分享多图了,但是接口其实还是保留了的,只要在传递参数 Intent.EXTRA_STREAM 时 urilList 中只携带 1 张图片,还是可以跳转到朋友圈图文分享界面的。如下:

微信图文分享界面

微信 v7.0.x 不能使用 Intent.ACTION_SEND_MULTIPLE 分享了,只能使用 Intent.ACTION_SEND,具体解决方案请阅读源码

此界面和从朋友圈中通过选择图片后跳转的界面是一模一样的,不仅可以分享图片,还可以发送文字、定位、同步到QQ空间。
但是,仅仅打开图文分享界面是不行的,因为我们要的是多图分享,而这里只传入了 1 张图片。为了解决这个问题,需要用到 AccessibilityService

使用无障碍服务

AccessibilityService 官方文档

无障碍服务是一个为残疾人或可能暂时无法与设备完全互动的人提供用户界面扩展功能的服务。
从Android4.0(API级别14)开始,无障碍服务可以代表用户操作,包含改变输入焦点和选择(激活)用户界面元素。在Android4.1(API级别16),操作的范围被扩展至包含滚动列表和与文本域交互。无障碍服务也可采取全局操作,如导航到主界面、按返回按钮、打开屏幕通知和最近应用列表。Android4.1也包含新焦点类型,无障碍焦点,该焦点类型可让所有视觉元素能够被无障碍服务所选择。
这些新的能力让开发者能够开发替代导航模式,如手势导航,提高残障用户对Android设备的控制。

通过使用无障碍服务,可以监听用户手机界面和事件,并在特定事件产生时代替用户执行一些操作。因此我们只要知道分析朋友圈图文分享界面的事件,找到合适的事件帮助用户自动填写文字、自动选择图片即可。
注意:由于无障碍服务功能强大,因此 Android 系统对其进行了限制,必须用户手动打开 APP 开发的无障碍服务,才能产生作用。

事件分析

class WXShareMultiImageService : AccessibilityService() {

    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // 当窗口发生的事件是我们配置监听的事件时,会回调此方法.会被调用多次
    }

    override fun onInterrupt() {
        //当服务要被中断时调用.会被调用多次
    }
}

每次产生的事件都会发送到 onAccessibilityEvent 函数,通过打印 AccessibilityEvent 的内容分析事件,发现以下事件:

  • 打开图文分享界面时产生的事件:
{
    eventType : AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
    className : com.tencent.mm.plugin.sns.ui.SnsUploadUI
    ...
}
  • 点击添加图片的 + 号产生的事件:
{
    eventType : AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
    className : android.widget.ListView
    ...
}
  • 打开图片选择界面的事件:
{
    eventType : AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
    className : com.tencent.mm.plugin.gallery.ui.AlbumPreviewUI
    ...
}

分析图文分享界面的 UI

使用 Android SDK 的 uiautomatorviewer 工具分析 UI,找到如下视图:

  • 文字编辑框(EditText)。
  • 已选图片列表(GridView),最后一个 Item 是【添加图片按钮】。
  • 添加图片方式列表(ListView),最后一个 Item 是【从相册选择】。
  • 待选图片列表(GridView)。
  • 复选框(CheckBox),其实点击的不是 CheckBox,而是另一个不可见的 View。
  • 【完成】选择按钮。

AccessibilityService 中获取视图节点的 3 种方式:

// 通过 id  获取节点。
rootNodeInfo.findAccessibilityNodeInfosByViewId(idString)

// 通过文本获取节点。
rootNodeInfo.findAccessibilityNodeInfosByText(text)

// 遍历子节点获取指定节点。
fun findNodeInfo(rootNodeInfo: AccessibilityNodeInfo?, className: String): AccessibilityNodeInfo? {
    // 遍历,具体内容请查看源码。
}

微信每个版本的视图 id 都不一样,为了版本兼容,不能使用 id 获取节点。
通过 text 文本获取节点只对有 text 属性且有值的节点有效。
因此大多数节点通过遍历子节点的形式获取。

自动粘贴

将待分享的文字复制到系统剪切板,如果用户打开了无障碍服务,服务将自动粘贴文字到输入框,否则用户也可以手动长按输入框粘贴。

val editText = findNodeInfo(rootInActiveWindow, EditText::class.java.name)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
    // 粘贴剪切板内容
    editText?.performAction(AccessibilityNodeInfo.ACTION_FOCUS)
    editText?.performAction(AccessibilityNodeInfo.ACTION_PASTE)
} else {
    editText?.text = ClipboardUtil.getPrimaryClip(this)
}

自动选图

用户点击分享时下载并记录图片,如果用户打开了无障碍服务,服务将代替用户自动选择图片,否则用户也可以进入相册手动选择图片。

// 以下几个步骤是异步的,这里只是为了方便才写在了一起。

// 第一步: 自动点击添加图片的 + 号按钮。
val gridView = findNodeInfo(rootInActiveWindow, GridView::class.java.name)
gridView?.getChild(gridView.childCount - 1)?.performAction(AccessibilityNodeInfo.ACTION_CLICK)

// 第二步:点击【从相册选择】按钮。
listView.findAccessibilityNodeInfosByText("从相册选择")
        ?.get(0)
        ?.parent
        ?.performAction(AccessibilityNodeInfo.ACTION_CLICK)

// 第三步:选择图片。
val gridView = findNodeInfo(rootInActiveWindow, GridView::class.java.name)
for (i in ShareInfo.getSelectedImageCount()..ShareInfo.getWaitingImageCount()) {
    findNodeInfo(gridView.getChild(i), View::class.java.name)
            ?.performAction(AccessibilityNodeInfo.ACTION_CLICK)
}

// 第四步:点击【完成】按钮。
rootInActiveWindow.findAccessibilityNodeInfosByText("完成")
        ?.get(0)
        ?.performAction(AccessibilityNodeInfo.ACTION_CLICK)

详细内容请 查看源码

为了方便大家使用新的分享方案,我这里已经封装成组件 ,并发布源码到 Github。
https://github.com/shichaohui/WXShareMultiImage

完整的多图分享流程

流程图

下载 Demo

Github 查看源码

优缺点

优点

  1. 可自动粘贴分享文字。
  2. 可自动选择指定的多张图片。
  3. 服务不可用时会自动降级,由用户手动选择图片。

缺点

  1. 无法获取分享结果。
  2. 需用户手动打开服务。
  3. 部分机型在关闭APP时会自动关闭服务。
  4. 微信更新朋友圈图文分享界面可能导致方案失效。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容