Android通知栏监听之NotificationListenerService

来源:互联网 发布:java无限循环代码 编辑:程序博客网 时间:2024/06/15 00:31

NotificationListenerService的基础使用就不说了,可以阅读官方文档或者自行百度。这里参考个性通知App的功能做一些难点探究。


以下主要是对通知栏通知的跳转做探究。
当有通知弹出在通知栏时,NotificationListenerService的onNotificationPosted会回调,返回参数是StatusBarNotification的对象。
能拿到StatusBarNotfication对象跳转的方式很简单方便,通过获取它的PendingIntent,调用PendingIntent的send方法即可模拟发送此条通知的意图。代码如下:

//获取PendingItentPendingIntent pendingIntent = sbn.getNotification().contentIntent;pendingIntent.send();

难点一:通知栏通知的保存。
跳转的难点就在于,我们的通知栏监听应用退出或者被杀死时,我们将失去StatusBarNotification这个对象,继而没法通过PendingIntent的send方法进行跳转。
然后我们会想到,当收到onNotificationPosted方法回调时,就把StatusBarNotification存起来,但是你会发现这个对象虽然实现了Parcelable接口,但是没法进行实体化保存(就是像字符串那样存起来)。Parcel定位就是轻量级的高效的对象序列化和反序列化机制,专为Binder实现的一种序列化机制。
那保存PendingIntent呢?同样,也是不行的。
再往细想,保存PendingIntent中的Intent呢?嘿嘿嘿,可行,Intent有个toUri方法,可以将Intent转化为String,String肯定是可以存的了。代码如下:

        Intent intent = getIntentByPendingIntent(pendingIntent);        //将Intent转换成String,可以存到数据库        String serializeIntent = intent.toUri(0);    /**     * 通过反射从PendingIntent中拿到Intent     *     * @param pendingIntent     * @return intent     */    public static Intent getIntentByPendingIntent(PendingIntent pendingIntent) {        Intent intent = null;        try {            intent = (Intent) PendingIntent.class.getDeclaredMethod("getIntent", new Class[0]).invoke(pendingIntent, new Object[0]);        } catch (Exception paramPendingIntent) {            LogUtil.d("PendingIntent getIntent failure!!!");        }        return intent;    }

难点二:通知栏Intent的跳转。
存了String的Intent,然后通过Intent的parseUri,可以将String后的Intent转化为Intent对象。然后我们知道,当初App建立Notification时,会通过getActivity、getService、getBroadcast方法传入Intent,从而点击通知栏时,系统会知道跳转到何种组件。而此时我们只有Intent,不知道应该是通过startActivity、startService、sendBroadcast进行跳转。故采用以下这种套路,每个试一下,哈哈哈:

        try {            context.startActivity(intent);            LogUtil.d("jumpAppByStartActivity");        } catch (Exception e) {            LogUtil.d("jumpAppByStartActivity Failure!!!");        }        try {            context.startService(intent);            LogUtil.d("jumpAppByStartService");        } catch (Exception e) {            LogUtil.d("jumpAppByStartService Failure!!!");        }        try {            context.sendBroadcast(intent);            LogUtil.d("jumpAppBySendBroadcast");        } catch (Exception e) {            LogUtil.d("jumpAppBySendBroadcast Failure!!!");        }

附上Github的Demo:
https://github.com/OptimusPrimeRen/NotificationListenerDemo

0 0
原创粉丝点击