用代码打开通知中心(statusbar、通知栏、消息中心)
我想用代码来打开android的消息中心,也叫做statusbar、通知栏。通知栏其实就是一个常驻的服务,至于原理这里就不多说了,简单说下思路和问题。
思路:API中没有实现的方法,那么就利用反射机制
问题:4.2系统中的方法变更
解决办法:分系统实现不同的方法
源码路径:……\sdk\sources\android-18\android\app\StatusBarManager
我们先来看android 4.4(API 19)中的方法,android 4.3(API 18),android 4.2.2(API 17)中都是下列方法
/** * Expand the notifications panel. */ public void expandNotificationsPanel() { try { final IStatusBarService svc = getService(); if (svc != null) { svc.expandNotificationsPanel(); } } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); } } /** * Collapse the notifications and settings panels. */ public void collapsePanels() { try { final IStatusBarService svc = getService(); if (svc != null) { svc.collapsePanels(); } } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); } }
我们再来看android 4.1.2(API 16)中的方法,终于发现了方法名的不同了。
/** * Expand the status bar. */ public void expand() { try { final IStatusBarService svc = getService(); if (svc != null) { svc.expand(); } } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); } } /** * Collapse the status bar. */ public void collapse() { try { final IStatusBarService svc = getService(); if (svc != null) { svc.collapse(); } } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); } }
最后发现API 16自己包括之前的方法都是叫做expand(),collapse(),之后的方法就改名了。至于改名的原因也很清楚,就是4.2后状态栏中多了一个设置界面。所以要所写一个方法,由于expand(展开)这个方法名太笼统,所以就把拉开通知栏的方法叫做了expandNotificationsPanel,把拉开设置界面的方法叫做expandSettingsPanel。
下面是折叠/拉开设置界面的方法:
/** * Collapse the notifications and settings panels. */ public void collapsePanels() { try { final IStatusBarService svc = getService(); if (svc != null) { svc.collapsePanels(); } } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); } } /** * Expand the settings panel. */ public void expandSettingsPanel() { try { final IStatusBarService svc = getService(); if (svc != null) { svc.expandSettingsPanel(); } } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); } }
好啦,找到问题后我们就需要用反射机制和判断系统版本的方式来写代码了。
/** * 显示消息中心 */ public static void openStatusBar(Context mContext){ try { Object service = mContext.getSystemService ("statusbar"); System.out.println("SDK INT= "+VERSION.SDK_INT +" BUILD.VERSION.SDK"+Build.VERSION.SDK_INT); Class <?> statusBarManager = Class.forName("android.app.StatusBarManager"); // 判断系统版本号 String methodName = (VERSION.SDK_INT<=16)?"expand":"expandNotificationsPanel"; Method expand = statusBarManager.getMethod (methodName); expand.invoke (service); } catch (Exception e) { e.printStackTrace(); } } /** * 关闭消息中心 */ public static void closeStatusBar(Context mContext){ try { Object service = mContext.getSystemService ("statusbar"); Class <?> statusBarManager = Class.forName("android.app.StatusBarManager"); // 判断系统版本号 String methodName = (VERSION.SDK_INT<=16)?"collapse":"collapsePanels"; Method expand = statusBarManager.getMethod(methodName); expand.invoke(service); } catch (Exception e) { e.printStackTrace(); } }
整理后得到如下代码,方便大家调用(android 2.2及以上测试正常):
private static void doInStatusBar(Context mContext, String methodName) { try { Object service = mContext.getSystemService("statusbar"); Class<?> statusBarManager = Class.forName("android.app.StatusBarManager"); Method expand = statusBarManager.getMethod(methodName); expand.invoke(service); } catch (Exception e) { e.printStackTrace(); } } /** * 显示消息中心 */ public static void openStatusBar(Context mContext) { // 判断系统版本号 String methodName = (VERSION.SDK_INT <= 16) ? "expand" : "expandNotificationsPanel"; doInStatusBar(mContext, methodName); } /** * 关闭消息中心 */ public static void closeStatusBar(Context mContext) { // 判断系统版本号 String methodName = (VERSION.SDK_INT <= 16) ? "collapse" : "collapsePanels"; doInStatusBar(mContext, methodName); }
分类:
Other Skills
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?