Android关闭通知消息权限无法弹出Toast的解决方案
背景
在之前一段时间里经常有用户反馈无法看到薄荷app弹出的消息提示,导致用户对一些使用场景感到很困惑。猜测可能是由于用户关闭了薄荷app的通知消息的权限导致的问题,测试后发现果真如此。
原因
跟踪Toast的源代码,make
方法省略,做了一些初始化的工作,show
方法
|
|
熟悉binder
通讯的同学应该都知道,其实调用了NotificationManagerService.service.enqueueToast
方法进入toast队列,进行相应的逻辑处理后回调给Toast中的TN
,TN
其实就是一个aidl
的stub
实现,相当于Client
端,用来接收Service
端发来的消息。看下TN
中的show方法
|
|
通过WinwodManager
添加一个view
显示提示消息。
总结来说就是toast的显示过程通过IPC通讯由NotificationManagerService
维护一个toast队列,然后通知给Toast中的客户端TN
调用WindowManager
添加view。
那么,如果关闭通知栏消息权限,会影响NotificationManagerService
队列的逻辑处理过程,导致不能通知TN
显示出视图。
解决
通过上面的分析,我们可以绕过NotificationManagerService
,我们自己维护一个toast队列,处理相关的逻辑,进行显示,定时取消。关键代码
|
|
mQueue
维护了Toast
的队列,队列采用FIFO
调度,每次调用show()
方法触发activeQueue()
方法,从队列中取出toast进行显示,然后定时取消。
总结
Google把Toast视为系统级别的消息通知,其实是不合理的,在app前台可见的情况下,有些关键信息需要提供给用户,如果关闭了消息通知权限,那么用户就会看不到这些关键的提示就会很困惑,直接影响用户体验,并且在Android5.0之后在设置中就可以关闭app的消息权限,Toast作为一个系统级别的消息提示设计者真的挺缺心眼的。虽然MD中有SnackBar作为消息提示,其原理就是在当前界面找到根视图,在根视图addView()
,达到弹出提示的目的,但是请原谅我的审美不够高,SnackBar真的很丑,并且最近Google又支持BottomSheet,两个叠加到一起,我的天,画面太美,我不敢看。还有就是必须要拿到当前的content,对于用Application的context弹出toast的方案来说适配起来修改比较麻烦。很明显,Toast就应该是app级的消息提示,我们的解决方案也正是这么做的。
参考
- 《Android开发艺术探索》第八章 理解Window和WindowManager
- 解决小米MIUI系统上后台应用没法弹Toast的问题
- Toast
- NotificationManagerService
本文链接: http://w4lle.com/2016/03/27/Android关闭通知消息权限无法弹出Toast的问题解决方案/
版权声明:本文为 w4lle 原创文章,可以随意转载,但必须在明确位置注明出处!
本文链接: http://w4lle.com/2016/03/27/Android关闭通知消息权限无法弹出Toast的问题解决方案/