这里有新鲜出炉的精品教程,程序狗速度看过来!
Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。
这篇文章主要介绍了Android编程实现禁止状态栏下拉的方法,结合实例形式详细分析了Android状态栏操作相关的函数、属性调用及权限控制设置技巧,需要的朋友可以参考下
本文实例讲述了Android编程实现禁止状态栏下拉的方法。分享给大家供大家参考,具体如下:
简介
项目需求APP全屏时,要禁止状态栏的下拉,这个应该是一个普遍的需求了吧,但Android系统没有直接提供给普通APP直接调用的接口。那么我们只能自己想办法增加接口去实现该功能了。
具体实现方法
1. 修改SystemUI
路径:==/frameworks/base/packages/SystemUI//src/com/android/systemui/statusbar/phone/PhoneStatusBar.Java==
通过在PhoneStatusBar.java类中注册一个广播的方式来实现状态栏的禁用和解除,其核心方法就是调用了
方法。disable()是SystemUI自定义的方法,感兴趣的同学可以去看其具体实现。
- disable()
下面来看下我们在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
方法实现状态栏的禁用和解除禁用。另:StatusBarManager是一个隐藏类,所以调用的时候可能导入不了包会报错,最简单的方法就是之间用数值替换,下面列出对应关系。
- onPause
- 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;
- }
这种方式做判断的时候,获取到的win不一定是当前activity的,有时候是statusbar的,所以这样的效果不是很好,经常会下拉出状态栏,于是就有了
- getSystemUiVisibility()
- 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程序设计有所帮助。
来源: http://www.phperz.com/article/17/0916/345692.html