国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android編程實現禁止狀態欄下拉的方法詳解

2019-10-22 18:29:15
字體:
來源:轉載
供稿:網友

本文實例講述了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中的具體調用吧。

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

在Activity中重寫onResumeonPause方法實現狀態欄的禁用和解除禁用。另: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了。

通過上面的步驟我們知道最關鍵的就是調用PhoneStatusBardisable()方法,我們這里是以廣播的方式實現的,任何有新方法的同學可以腦洞大開,只要能實現調用到disable()就可以禁用狀態欄。

2.修改PhoneWindowManager

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

// monitor for system gesturesmSystemGestures = 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中的具體調用

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

在AndroidManifest.xml中聲明相應的權限

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

網上還有修改PhoneWindowManager中的adjustSystemUiVisibilityLw方法的,如:

@Overridepublic 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中的引用

@Overrideprotected void onResume() {    super.onResume();    StatusBarManager statusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);    statusBarManager.disable(StatusBarManager.DISABLE_EXPAND);}@Overrideprotected 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開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黔西县| 广昌县| 新化县| 台南市| 淳安县| 色达县| 娱乐| 县级市| 耒阳市| 西乌珠穆沁旗| 远安县| 呼伦贝尔市| 屏东市| 宝清县| 光泽县| 唐河县| 潼南县| 海口市| 旌德县| 东乌珠穆沁旗| 明光市| 敖汉旗| 白玉县| 怀安县| 政和县| 合山市| 同江市| 株洲县| 宜阳县| 芒康县| 横峰县| 建瓯市| 新巴尔虎右旗| 阳山县| 论坛| 柳州市| 石景山区| 元阳县| 临夏市| 石台县| 綦江县|