Android编程实现禁止状态栏下拉的方法详解

本文实例讲述了Android编程实现禁止状态栏下拉的方法。分享给大家供大家参考,具体如下:

简介

项目需求APP全屏时,要禁止状态栏的下拉,这个应该是一个普遍的需求了吧,但Android系统没有直接提供给普通APP直接调用的接口。那么我们只能自己想办法增加接口去实现该功能了。

具体实现方法

1. 修改SystemUI

路径:==/frameworks/base/packages/SystemUI//src/com/android/systemui/statusbar/phone/PhoneStatusBar.Java==

通过在PhoneStatusBar.java类中注册一个广播的方式来实现状态栏的禁用和解除,其核心方法就是调用了disable()方法。disable()是SystemUI自定义的方法,感兴趣的同学可以去看其具体实现。

下面来看下我们在SystemUI中的具体实现代码:

@@ -494,6 +494,31 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { } + //add steven zhang by 20160701 + private BroadcastReceiver mStatusShowHide = new BroadcastReceiver() { + + @Override + public void onReceive(final Context context, Intent intent) { + // TODO Auto-generated method stub + String action = intent.getAction(); + + if ("com.aura.statusbar.SHOW_OR_HIDE".equals(action)) { + // StatusBarManager.DISABLE_NONE + // StatusBarManager.DISABLE_EXPAND + final int mode = intent.getIntExtra("mode", StatusBarManager.DISABLE_NONE); + if (mNavigationBarView != null) { + mHandler.post(new Runnable() { + + @Override + public void run() { + + disable(mode); + } + }); + } + } + } + }; //micheal add the Broadcast interface for Control the wifi sleep mode change begin 20150514 private BroadcastReceiver wifiSleepModeChangeReceiver = new BroadcastReceiver(){ @Override @@ -519,6 +544,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { // ================================================================================ protected PhoneStatusBarView makeStatusBarView() { final Context context = mContext; + // add steven zhang by 20160701 + IntentFilter statusFilter = new IntentFilter(); + statusFilter.addAction("com.aura.statusbar.SHOW_OR_HIDE"); + context.registerReceiver(mStatusShowHide, statusFilter);

既然显示隐藏的广播我们已经注册好了,那么看下我们在APP中的具体调用吧。

@Override protected void onResume() { super.onResume(); Intent i = new Intent("com.aura.statusbar.SHOW_OR_HIDE"); i.putExtra("mode", StatusBarManager.DISABLE_EXPAND); sendBroadcast(i); } @Override protected void onPause() { super.onPause(); Intent i = new Intent("com.aura.statusbar.SHOW_OR_HIDE"); i.putExtra("mode", StatusBarManager.DISABLE_NONE); sendBroadcast(i); }

在Activity中重写onResume和onPause方法实现状态栏的禁用和解除禁用。另:StatusBarManager是一个隐藏类,所以调用的时候可能导入不了包会报错,最简单的方法就是之间用数值替换,下面列出对应关系。

public static final int DISABLE_EXPAND = 0x00010000; public static final int DISABLE_NOTIFICATION_ICONS = 0x00020000; public static final int DISABLE_NOTIFICATION_ALERTS = 0x00040000; public static final int DISABLE_NOTIFICATION_TICKER = 0x00080000; public static final int DISABLE_SYSTEM_INFO = 0x00100000; public static final int DISABLE_HOME = 0x00200000; public static final int DISABLE_RECENT = 0x01000000; public static final int DISABLE_BACK = 0x00400000; public static final int DISABLE_CLOCK = 0x00800000; public static final int DISABLE_SEARCH = 0x02000000; public static final int DISABLE_NONE = 0x00000000; public static final int DISABLE_NAVIGATION = View.STATUS_BAR_DISABLE_HOME | View.STATUS_BAR_DISABLE_RECENT; public static final int DISABLE_MASK = DISABLE_EXPAND | DISABLE_NOTIFICATION_ICONS | DISABLE_NOTIFICATION_ALERTS | DISABLE_NOTIFICATION_TICKER | DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK | DISABLE_SEARCH;

所以不能引用StatusBarManager的同学之间使用其数值是一样的。如果有源码的朋友,可以使用系统编译的后framework jar包作为APP的lib就可以直接使用StatusBarManager方法了。其路径为/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar。将classes.jar改为framework.jar导入工程就OK了。

通过上面的步骤我们知道最关键的就是调用PhoneStatusBar中disable()方法,我们这里是以广播的方式实现的,任何有新方法的同学可以脑洞大开,只要能实现调用到disable()就可以禁用状态栏。

2.修改PhoneWindowManager

路径:==/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java==

// monitor for system gestures mSystemGestures = new SystemGesturesPointerEventListener(context, new SystemGesturesPointerEventListener.Callbacks() { @Override public void onSwipeFromTop() { if (isGestureIsolated()) return; if (mStatusBar != null) { requestTransientBars(mStatusBar); } } @Override public void onSwipeFromBottom() { if (isGestureIsolated()) return; if (mNavigationBar != null && mNavigationBarOnBottom) { requestTransientBars(mNavigationBar); } } @Override public void onSwipeFromRight() { if (isGestureIsolated()) return; if (mNavigationBar != null && !mNavigationBarOnBottom) { requestTransientBars(mNavigationBar); } } @Override public void onDebug() { // no-op } private boolean isGestureIsolated() { boolean ret = false; ret = Settings.System.getInt(mContext.getContentResolver(),"status_bar_disabled", 0) == 1; return ret; } });

在SystemGesturesPointerEventListener.Callbacks的方法中增加一个判断函数isGestureIsolated()用于判断是否支持其对应的手势操作。在这里特别说明一下,在网上找到方法用

private boolean isGestureIsolated() { boolean ret = false; WindowState win = mFocusedWindow != null ? mFocusedWindow:mTopFullscreenOpaqueWindowState; if (win != null && (win.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_IMMERSIVE_GESTURE_ISOLATED) != 0) ret = true; else ret = false; return ret; }

getSystemUiVisibility()这种方式做判断的时候,获取到的win不一定是当前activity的,有时候是statusbar的,所以这样的效果不是很好,经常会下拉出状态栏,于是就有了

Settings.System.getInt(mContext.getContentResolver(),"status_bar_disabled", 0) == 1;

做判断的方法,用这种方式有一个好处就是非常直接,需要它禁止下拉的时候,就调用

Settings.System.putInt(getContentResolver(), "status_bar_disabled", 1);

就OK了,解除禁止的时候调用

Settings.System.putInt(getContentResolver(), "status_bar_disabled", 0);

看下Activity中的具体调用

@Override protected void onResume() { super.onResume(); //禁止下拉 Settings.System.putInt(getContentResolver(), "status_bar_disabled", 1); } @Override protected void onPause() { super.onPause(); //解除禁止 Settings.System.putInt(getContentResolver(), "status_bar_disabled", 0); }

在AndroidManifest.xml中声明相应的权限

<uses-permission android:name="android.permission.WRITE_SETTINGS" />

网上还有修改PhoneWindowManager中的adjustSystemUiVisibilityLw方法的,如:

@Override public int adjustSystemUiVisibilityLw(int visibility){ if (Settings.System.getInt(mContext.getContentResolver(),"status_bar_disabled", 0) == 0) { mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); } mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); // Reset any bits in mForceClearingStatusBarVisibility that // are now clear. mResettingSystemUiFlags &= visibility; // Clear any bits in the new visibility that are currently being // force cleared, before reporting it. return visibility & ~mResettingSystemUiFlags & ~mForceClearedSystemUiFlags; }

在adjustSystemUiVisibilityLw增加一个标志的判断,但这种实现的效果也不是很好,还是会出现下拉能拉下来的情况。

综上所叙,修改PhoneWindowManager实现禁止下拉的方法还是在SystemGesturesPointerEventListener.Callbacks中增加一个内部方法,这个内部方法使用标志位的形式来判断是否支持状态栏下拉。

3. 使用StatusBarManager中方法

因为StatusBarManager是隐藏方法,所以要在IDE中直接使用的话要导入framework jar包,怎么找到framework jar在1. 修改SystemUI中有说过,这里就不重复了。直接上代码:

1.在AndroidManifest.xml中声明相应的权限

<uses-permission android:name="android.permission.STATUS_BAR"/> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>

网上有文章说要声明

android : sharedUserId="android.uid.system"

亲自测试没有加上面这行代码,也是可以使用的。

2. 在Activity中的引用

@Override protected void onResume() { super.onResume(); StatusBarManager statusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE); statusBarManager.disable(StatusBarManager.DISABLE_EXPAND); } @Override protected void onPause() { super.onPause(); StatusBarManager statusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE); statusBarManager.disable(StatusBarManager.DISABLE_NONE); }

1.是使用系统签名,编译为系统app

java -jar signapk.jar platform.x509.pem platform.pk8 TestDemo.apk TestDemoNew.apk

TestDemoNew.apk就是系统签名后的apk,然后push到/system/app/目录下就ok了。关于签名的知识就不多说了,可自行找到相关资料。

下面看下原生系统中电话处理禁止下拉的做法,代码如下:

路径:==/packages/apps/Phone/src/com/android/phone/NotificationMgr.java==

/** * Updates the status bar to reflect the current desired state. */ private void updateStatusBar() { int state = StatusBarManager.DISABLE_NONE; if (!mIsExpandedViewEnabled) { state |= StatusBarManager.DISABLE_EXPAND; } if (!mIsNotificationEnabled) { state |= StatusBarManager.DISABLE_NOTIFICATION_ALERTS; } if (!mIsSystemBarNavigationEnabled) { // Disable *all* possible navigation via the system bar. state |= StatusBarManager.DISABLE_HOME; state |= StatusBarManager.DISABLE_RECENT; state |= StatusBarManager.DISABLE_BACK; } if (DBG) log("updateStatusBar: state = 0x" + Integer.toHexString(state)); mStatusBarManager.disable(state); }

从这个方法中我们知道系统禁用状态栏的方法就是调用StatusBarManager实现的。

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android多媒体操作技巧汇总(音频,视频,录音等)》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

时间: 2024-09-27 02:10:46

Android编程实现禁止状态栏下拉的方法详解的相关文章

Android编程实现禁止StatusBar下拉的方法

本文实例讲述了Android编程实现禁止StatusBar下拉的方法.分享给大家供大家参考,具体如下: Android中有许多隐藏的Service,StatusBarManager就是其中一个,在Context.java中可以看到: /** * Use with {@link #getSystemService} to retrieve a {@link * android.app.StatusBarManager} for interacting with the status bar. *

Android编程实现AIDL(跨进程通信)的方法详解_Android

本文实例讲述了Android编程实现AIDL(跨进程通信)的方法.分享给大家供大家参考,具体如下: 一. 概述: 跨进程通信(AIDL),主要实现进程(应用)间数据共享功能. 二. 实现流程: 1. 服务器端实现: (1)目录结构,如下图: (2)实现*.aidl文件: A. IAIDLService.aidl实现: package com.focus.aidl; import com.focus.aidl.Person; interface IAIDLService { String getN

Android编程使用sax解析xml数据的方法详解

本文实例讲述了Android编程使用sax解析xml数据的方法.分享给大家供大家参考,具体如下: 随着技术的发展,现在的web已经和以前不同了.web已经逐渐像移动的方向倾斜,作为程序员的确应该拓展一下自己的知识层面.学习各方面的知识,今天就接着前几天的弄一下Android的xml解析,这次就使用sax的方式解析xml.下面就一步一步的来做吧. 1. 编写一个简单的xml <?xml version="1.0" encoding="UTF-8"?> &l

Android编程实现AIDL(跨进程通信)的方法详解

本文实例讲述了Android编程实现AIDL(跨进程通信)的方法.分享给大家供大家参考,具体如下: 一. 概述: 跨进程通信(AIDL),主要实现进程(应用)间数据共享功能. 二. 实现流程: 1. 服务器端实现: (1)目录结构,如下图: (2)实现*.aidl文件: A. IAIDLService.aidl实现: package com.focus.aidl; import com.focus.aidl.Person; interface IAIDLService { String getN

yii2带搜索功能的下拉框实例详解_php实例

简单的小功能,但是用起来还是蛮爽的.分享出来让更多的人有更快的开发效率,开开心心快乐编程. 如果你还没有使用过composer,你可就out了,看我的教程分享,composer简直就是必备神奇有木有.都说到这个点上了,我们赶紧使用composer进行安装吧. 先给大家展示下效果图: 下面给大家说下具体实现思路: composer require kartik-v/yii2-widget-select2 "@dev" #特别说明,因为这里安装的dev版本,也就是开发版本,不稳定版本,如果

Android中gson、jsonobject解析JSON的方法详解_Android

JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换.JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为. JSON对象: JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, ke

Android中gson、jsonobject解析JSON的方法详解

JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换.JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为. JSON对象: JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, ke

Android编程之软键盘的隐藏显示实例详解_Android

本文实例分析了Android编程之软键盘的隐藏显示方法.分享给大家供大家参考,具体如下: Android是一个针对触摸屏专门设计的操作系统,当点击编辑框,系统自动为用户弹出软键盘,以便用户进行输入. 那么,弹出软键盘后必然会造成原有布局高度的减少,那么系统应该如何来处理布局的减少?我们能否在应用程序中进行自定义的控制?这些是本文要讨论的重点. 一.软键盘显示的原理 软件盘的本质是什么?软键盘其实是一个Dialog! InputMethodService为我们的输入法创建了一个Dialog,并且将

Android TextView使用SpannableString设置复合文本的方法详解_Android

本文实例讲述了Android TextView使用SpannableString设置复合文本的方法.分享给大家供大家参考,具体如下: TextView通常用来显示普通文本,但是有时候需要对其中某些文本进行样式.事件方面的设置.Android系统通过SpannableString类来对指定文本进行相关处理,具体有以下功能: 1.BackgroundColorSpan 背景色 2.ClickableSpan 文本可点击,有点击事件 3.ForegroundColorSpan 文本颜色(前景色) 4.