您好,登錄后才能下訂單哦!
Android中怎么禁止?fàn)顟B(tài)欄下拉,很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
1. 修改SystemUI
路徑:==/frameworks/base/packages/SystemUI//src/com/android/systemui/statusbar/phone/PhoneStatusBar.Java==
通過在PhoneStatusBar.java類中注冊一個(gè)廣播的方式來實(shí)現(xiàn)狀態(tài)欄的禁用和解除,其核心方法就是調(diào)用了disable()
方法。disable()是SystemUI自定義的方法,感興趣的同學(xué)可以去看其具體實(shí)現(xiàn)。
下面來看下我們在SystemUI中的具體實(shí)現(xiàn)代碼:
@@ -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);
既然顯示隱藏的廣播我們已經(jīng)注冊好了,那么看下我們在APP中的具體調(diào)用吧。
@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
方法實(shí)現(xiàn)狀態(tài)欄的禁用和解除禁用。另:StatusBarManager是一個(gè)隱藏類,所以調(diào)用的時(shí)候可能導(dǎo)入不了包會(huì)報(bào)錯(cuò),最簡單的方法就是之間用數(shù)值替換,下面列出對應(yīng)關(guān)系。
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的同學(xué)之間使用其數(shù)值是一樣的。如果有源碼的朋友,可以使用系統(tǒng)編譯的后framework jar包作為APP的lib就可以直接使用StatusBarManager方法了。其路徑為/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar。將classes.jar改為framework.jar導(dǎo)入工程就OK了。
通過上面的步驟我們知道最關(guān)鍵的就是調(diào)用PhoneStatusBar中disable()
方法,我們這里是以廣播的方式實(shí)現(xiàn)的,任何有新方法的同學(xué)可以腦洞大開,只要能實(shí)現(xiàn)調(diào)用到disable()就可以禁用狀態(tài)欄。
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
的方法中增加一個(gè)判斷函數(shù)isGestureIsolated()
用于判斷是否支持其對應(yīng)的手勢操作。在這里特別說明一下,在網(wǎng)上找到方法用
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()
這種方式做判斷的時(shí)候,獲取到的win不一定是當(dāng)前activity的,有時(shí)候是statusbar的,所以這樣的效果不是很好,經(jīng)常會(huì)下拉出狀態(tài)欄,于是就有了
Settings.System.getInt(mContext.getContentResolver(),"status_bar_disabled", 0) == 1;
做判斷的方法,用這種方式有一個(gè)好處就是非常直接,需要它禁止下拉的時(shí)候,就調(diào)用
Settings.System.putInt(getContentResolver(), "status_bar_disabled", 1);
就OK了,解除禁止的時(shí)候調(diào)用
Settings.System.putInt(getContentResolver(), "status_bar_disabled", 0);
看下Activity中的具體調(diào)用
@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中聲明相應(yīng)的權(quán)限
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
網(wǎng)上還有修改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增加一個(gè)標(biāo)志的判斷,但這種實(shí)現(xiàn)的效果也不是很好,還是會(huì)出現(xiàn)下拉能拉下來的情況。
綜上所敘,修改PhoneWindowManager實(shí)現(xiàn)禁止下拉的方法還是在SystemGesturesPointerEventListener.Callbacks中增加一個(gè)內(nèi)部方法,這個(gè)內(nèi)部方法使用標(biāo)志位的形式來判斷是否支持狀態(tài)欄下拉。
3. 使用StatusBarManager中方法
因?yàn)镾tatusBarManager是隱藏方法,所以要在IDE中直接使用的話要導(dǎo)入framework jar包,怎么找到framework jar在1. 修改SystemUI中有說過,這里就不重復(fù)了。直接上代碼:
1.在AndroidManifest.xml中聲明相應(yīng)的權(quán)限
<uses-permission android:name="android.permission.STATUS_BAR"/> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
網(wǎng)上有文章說要聲明
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.是使用系統(tǒng)簽名,編譯為系統(tǒng)app
java -jar signapk.jar platform.x509.pem platform.pk8 TestDemo.apk TestDemoNew.apk
TestDemoNew.apk就是系統(tǒng)簽名后的apk,然后push到/system/app/目錄下就ok了。關(guān)于簽名的知識(shí)就不多說了,可自行找到相關(guān)資料。
下面看下原生系統(tǒng)中電話處理禁止下拉的做法,代碼如下:
路徑:==/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); }
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。