如何实现App消息的未读已知、撤回已存

1,513 阅读6分钟

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!


本文有很多字,阅读需要一段时间,读完本文,您将有以下收获:

1. 嗯……了解……关于……
2. 掌握……这个……
读完了就知道了……

一、背景

大家好,我是产业园软件研发中心总监,我部门只有2个工位,另一个是实习生小李,老板说要扩到300人。

小李最近闷闷不乐,他说:

你让我学这么多知识有什么用?百度它不香吗?!

你看,就拿这个NotificationListenerService……这玩意——怎么读?学完了,能换钱吗?

很明显,小李太浮躁了。浮躁的不只是小李,还有老板,他也来了:

客户发钉钉问我问题,我问你,你还没回我,都已读20多分钟了,人家问为啥故意不回复?

你也在客户群里,他发了个消息又撤回了,到底说个啥?我忙,你多关注啊,整天瞎忙!

我打算同时解决小李和老板的焦虑,就用Android里面的NotificationListenerService(都别拦我)!!

二、通知监听服务?

NotificationListenerService(通知监听服务)看名字就知道啊,这是一个监听通知的服务,也就是说通知有变化,会通知你。

那么通知指的是什么?在哪里有体现呢?

微信里提到过通知通知1 拷贝.png

钉钉里也有提到通知通知2 拷贝.png

安卓用户,从屏幕顶部摁着往下拉,会拽出来一个叫通知栏的页面。 通知3 拷贝.png

这里面我们看到,微信会发通知,QQ会发通知,支付宝会发通知,收到短信会发通知,接到电话会发通知,甚至你插上充电线的时候它也会发出通知(声音逐渐亢奋,“也……”字拉长音)。

到这里,你突然明白了:噢!通知就是手机突然来了一声:不冷冷冷~。

是的,通知就是那一声提示音,同时带来文字消息。

NotificationListenerService就是管理这些通知的,有了它,上面展示的数据你都能拿到。

三、使用方法

自己写一个类,继承NotificationListenerService,然后重写里面的onNotificationPosted就可以了。

import android.app.Notification;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;

public class NotificationService extends NotificationListenerService {
    ……
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        Notification nc = sbn.getNotification(); // 通知栏对象
        String packageName = ""+sbn.getPackageName(); // 应用的包名
        String tickerText = ""+nc.tickerText;  // 通知栏摘要
        String extrasTitle = ""+nc.extras.get("android.title"); // 通知栏标题
        String extrasText = ""+nc.extras.get("android.text"); // 通知栏内容
	// todo  你想做的事情
    }
}

后面你的手机再收到任何通知,都会再额外地通知onNotificationPosted一次,此时你就能获取到信息了。

系统向你发送的内容包括:包名packageName,通知栏的标题extrasTitle,内容extrasText

下面是常见的App和对应的包名:

常见App包名 packageName
微信com.tencent.mm
QQcom.tencent.mobileqq
微博com.sina.weibo
钉钉com.alibaba.android.rimet
支付宝com.eg.android.AlipayGphone
抖音com.ss.android.ugc.aweme
淘宝com.taobao.taobao

至于标题extrasTitle和内容extrasText,其实也很好理解: 讲解 拷贝.png

既然我们拿到了这些数据,那就可以发挥想象力了:

  1. 一旦收到微信消息就存储,当发送的人撤回了,但是我们早就存完了,这就是防撤回功能。
  2. 收到钉钉消息,不点开钉钉,在这里也能看到,你既知道了内容,钉钉也依然是未读状态。
  3. ……

[☹] 就这么简单吗?

你还想怎么样,简单不好吗? [😯]

[☹] 这不科学,这么伟大的功能……

那我就再多说一点 [😯]

3.1 注册服务

你自己写的NotificationService类,目前只有你自己知道,需要告诉系统一声,这就需要在AndroidManifest.xml中进行注册。

<!-- AndroidManifest.xml -->
<application>
    <activity></activity>
    <service
        android:name=".NotificationService"
        android:exported="true"
        android:label="我的服务"
        android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
        <intent-filter>
            <action android:name="android.service.notification.NotificationListenerService" />
        </intent-filter>
    </service>
    ……
</application>

这样,你就在手机系统中注册了一个需要监听通知的服务,相当于交了保护费,上了江湖册子,以后系统收到什么风吹草动,它也会通知你一声。

3.2 开启权限和启动

上面的一系列操作,又是继承系统类,又是注册系统服务的,你以为万事俱备了吗?

你监听用户通知栏这事儿,问过用户吗?

问用户这事儿,最好放在ActivityonResume方法中执行。因为申请权限发出后,会跳到设置页面。设置完成回来后,正好又经过onResume方法,这样就又能判断是否获取到权限了,咱得启动服务啊。

// 判断是否允许获取通知
private boolean isNotificationServiceEnable() {
    return NotificationManagerCompat.getEnabledListenerPackages(this).contains(getPackageName());
}

@Override
protected void onResume() {
    super.onResume();
    boolean notificationIsOpen = isNotificationServiceEnable();
    if (!notificationIsOpen){ // 如果不允许通知,提醒去开启
        startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
    }else { // 如果已经允许,启动服务
        startService(new Intent(this, NotificationService.class));
    }
}

用户会收到这么一个通知使用权的申请。 img_set.png

如果用户点击了允许,那么就证明他授权这个软件读取自己通知栏的所有信息。

后面的一切,就都可以跑通了。

四、应用场景

为了解决小李和老板的问题,我用NotificationListenerService这一个知识点,指导小李开发了一个App,它有很多功能。

4.1 重要信息提醒

我关注了「老婆」发来的所有消息、「老板」发来的包含[开会]的消息。当我收到这类消息时,就会发出设定的提示音,重点提示。我在打游戏时,手机放在一边,任他微信、QQ噼啪乱响,只要没有播放我的爆炸提示音,那说明都不重要。

img_msg.png

4.2 手机黑匣子

手机解锁屏、充电连接数据线、断网联网、收到短信、未接电话,以及所有的通知栏收到的推送信息,都会记录下来。别人动过我的手机,看一眼就知道。 img_box.png

五、实习生还是离开了

我把这款App告诉了老板,说是实习生小李开发的。老板很震惊,说要给小李涨200块钱工资。

我不知道该不该告诉小李,最后还是小李找到了我,他说他要辞职了。

这种场面我见多了,以前还有一个《实习生小王离职:用代码生成了OCR训练集》的故事。

罢了,罢了,走吧,走吧,用技术解决生活中的问题一直是我的追求,这次也算是交差了。

同时,提醒各位掘友,注意手机权限的管理,看看你是否允许了这类权限,否则你的短信、电话、微信记录,他们都能知道。其中,一些手环类App是肯定需要的,因为你的手环之所以能收到微信消息,也是通过这个通知栏监听权限实现的,这是唯一方法,只能这样。如果,其他App也要通知栏权限,那你就需要注意了。