煎饼

煎饼为你分享Android有关的技术文章
不断分享,点滴积累,共同提高

关注微信公众号[developers]
更快的了解新的技术动态

Pushbullet QuickReply的实现解析

Pushbullet QuickReply功能就是手机端App将Whatsapp、Houngouts、Line等应用的消息通知推送到PC端并可以通过PC端的弹窗直接回复内容。

点击上图的Reply选项就可以在PC端输入内容直接回复了,这个功能的确有用,为经常在电脑前工作的用户带来很大方便。

那么它是如何实现的呢?

首先来思考两个问题:

一、目前仅支持7种应用使用QuickReply功能的Pushbullet是如何判断哪些应用可以支持的或者说应用满足何种条件才能拥有此项功能?
二、回复消息时是如何能够回复给指定的联系人的?

注:要是能够回答了这两个问题,那么此文下边的内容就不用看了,quick reply的功能也就能实现了,换句话说,本文就是基于这两个问题来作分析的。

通过这个帖子,可以看出他们讨论的是反编译Pushbullet之后对相关代码对一些简单分析,虽然没有直接给出想要的结果,但不能否认反编译是一种不错的方法。本人反编译之后对相关代码分析之后得到相关代码的重要部分如下:

 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
static Mirroring.WearReplyAction a(NotificationSpec notificationspec)
{
        Mirroring.WearReplyAction wearreplyaction;
label0:
        {
            Bundle bundle;
            if (AndroidVersion.a(19) && NotificationMirroringService.a)
            {
                bundle = notificationspec.d.extras;
                break MISSING_BLOCK_LABEL_22;
            }
            Bundle bundle1;
            do
            {
                do
                {
                    return null;
                } while (bundle == null || bundle.containsKey("android.wearable.EXTENSIONS"));
                bundle1 = bundle.getBundle("android.wearable.EXTENSIONS");
            } while (!bundle1.containsKey("actions"));
            if (AndroidVersion.a(21))
            {
                Iterator iterator1 = ((ArrayList)bundle1.get("actions")).iterator();
                android.app.Notification.Action action;
                do
                {
                    if (!iterator1.hasNext())
                    {
                        break label0;
                    }
                    action = (android.app.Notification.Action)iterator1.next();
                } while (action.getRemoteInputs() == null || action.getRemoteInputs().length <= 0);
                wearreplyaction = new Mirroring.WearReplyAction(action, action.actionIntent);
            } else
            {
                Iterator iterator = ((ArrayList)bundle1.get("actions")).iterator();
                Bundle bundle2;
                do
                {
                    if (!iterator.hasNext())
                    {
                        break label0;
                    }
                    bundle2 = (Bundle)iterator.next();
                } while (bundle2.get("remoteInputs") == null);
                android.os.Parcelable aparcelable[] = bundle2.getParcelableArray("remoteInputs");
                ArrayList arraylist = new ArrayList(aparcelable.length);
                int i = aparcelable.length;
                for (int j = 0; j < i; j++)
                {
                    String s = ((Bundle)aparcelable[j]).getString("resultKey");
                    if (!Strings.b(s))
                    {
                        arraylist.add(s);
                    }
                }

                wearreplyaction = new Mirroring.WearReplyAction(arraylist, (PendingIntent)bundle2.get("actionIntent"));
            }
        }
_L1:
        if (ReplyToAllApps.a(notificationspec.a))
        {
            return wearreplyaction;
        } else
        {
            Analytics.h("wear_action_filtered").a("package", notificationspec.a).a();
            return null;
        }
        wearreplyaction = null;
          goto _L1
    }

分析之后发现原来是利用的Android Wear的一些特性,如果对Wear还不熟悉,这里有些参数却是值得你先注意一下:

android.wearable.EXTENSIONS
actions
remoteInputs
resultKey
actionIntent

看了一些Android Wear相关的API之后发现,Notification中可以加入一些Wear的特性(相关API)来支持在Wear上的显示。如何在通知中加入这些特性等内容与解决quick reply问题无关,暂时不作讲解,还请自行参考相关API。不过,Receiving Voice Input in a Notification 这部分与此文到有点关系,从这部分内容我们可以了解到remoteInputs及resultKey在回复消息时的一些重要作用,所以这部分可以重点关注一下。

相关的内容已经讲完,如果你自己分析之后,相信你可以回答上面两个问题了。

另外,此项功能也已在传输文件神器 AirDroid 上实现了,相较与Pushbullet使用GCM回复消息在国内几乎不能正常使用,你可以去体验一下 AirDroid

115

分享本文:

Elevation和Ripple共用的简单例子