概述
在系统服务中增加显示/隐藏导航栏方法,在上层app动态调用显示/隐藏导航栏方法,设备关机和重启后也能继续生效。
创建全局变量
1.定义全局变量
在frameworks/base/core/java/android/provider/Settings.java中添加
/**
* hide navigation
* @hide
*/
public static final String SYSTEM_HIDE_NAVIGATION = "hide_navigation_bar";
2.定义全局变量默认值
在frameworks/base/packages/SettingsProvider/res/values/defaults.xml添加
<bool name="def_hide_navigation_bar">false</bool>
3.初始化默认值
在frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java添加
loadBooleanSetting(stmt, Settings.System.SYSTEM_HIDE_NAVIGATION,
R.bool.def_hide_navigation_bar);
在系统服务中添加显示和隐藏方法
1.在AIDL中添加方法
frameworks/base/core/java/com/custom/ICustomService.aidl
package com.custom;
/**
* @hide
*/
interface ICustomService {
/* 显示导航栏*/
void showNavigationBar();
/* 隐藏导航栏*/
void hideNavigationBar();
}
2.在Manager中添加方法
frameworks/base/core/java/com/custom/CustomManager.java
package com.custom;
import com.custom.ICustomService;
import android.content.Context;
import android.os.IBinder;
import android.util.Log;
import android.annotation.NonNull;
import android.os.RemoteException;
/**
* CustomManager 类是客户端访问 CustomService 的入口类。
*/
public class CustomManager {
private static final String TAG = "CustomManager";
/**
* 服务接口实例。
*/
private ICustomService mService;
/**
* @param context 应用程序上下文。
* @param service
* @hide
*/
public CustomManager(@NonNull Context context, @NonNull ICustomService service) {
mService = service;
}
/**
* 显示导航栏
* @hide
*/
public void showNavigationBar() {
try {
if (mService != null) {
mService.showNavigationBar();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* 隐藏导航栏
* @hide
*/
public void hideNavigationBar() {
try {
if (mService != null) {
mService.hideNavigationBar();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
3.在Service中添加显示隐藏导航栏实现
package com.custom;
import com.custom.ICustomService;
import android.util.Log;
import android.content.Context;
import android.provider.Settings;
import android.content.Intent;
/**
* 该类继承自ICustomService.Stub
*/
public class CustomService extends ICustomService.Stub {
private static final String TAG = "CustomService";
/**
* 上下文
*/
private Context mContext;
public CustomService(Context context) {
mContext = context;
android.util.Log.d(TAG, "CustomService run ...");
}
/**
* 显示导航栏。
*/
public void showNavigationBar() {
Settings.System.putInt(
mContext.getContentResolver(), Settings.System.SYSTEM_HIDE_NAVIGATION, 0);
Intent intent = new Intent("action.ACTION_HIDE_NAVIGATION");
mContext.sendBroadcast(intent);
}
/**
* 隐藏导航栏。
*/
public void hideNavigationBar() {
Settings.System.putInt(
mContext.getContentResolver(), Settings.System.SYSTEM_HIDE_NAVIGATION, 1);
Intent intent = new Intent("action.ACTION_HIDE_NAVIGATION");
mContext.sendBroadcast(intent);
}
}
在SystemUI中监听广播控制导航栏的显示和隐藏
1.在StatusBar.java中添加
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
+ public static final String ACTION_HIDE_NAVIGATION = "action.ACTION_HIDE_NAVIGATION"; //广播
+ private boolean mHideNavStatus = true;
+ private static final int MSG_HIDE_NAVIGATION_STATUS = 10001;
+
private static final String BANNER_ACTION_CANCEL =
"com.android.systemui.statusbar.banner_action_cancel";
private static final String BANNER_ACTION_SETUP =
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
mNotificationLogger.setHeadsUpManager(mHeadsUpManager);
- createNavigationBar(result);
+ //createNavigationBar(result);
+
+ try {
+ boolean hideNavStatus = Settings.System.getInt(mContext.getContentResolver(),Settings.System.SYSTEM_HIDE_NAVIGATION,0) != 0;
+ if (!hideNavStatus) {
+ createNavigationBar(result);
+ }
+ } catch (Exception e) {
+ Log.d(TAG, "--------------Navigation------------- " + e);
+ }
+
+ setNavigationStatus();
if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
+ filter.addAction(ACTION_HIDE_NAVIGATION);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}
}
}
+
+ private void setNavigationStatus() {
+ boolean hideNavStatus = Settings.System.getInt(mContext.getContentResolver(),Settings.System.SYSTEM_HIDE_NAVIGATION,0) != 0;
+ if(hideNavStatus)
+ hideNavigation();
+ else{
+ showNavigation();
+ }
+ }
+
+ private void showNavigation() {
+ boolean hideNavStatus = Settings.System.getInt(mContext.getContentResolver(),Settings.System.SYSTEM_HIDE_NAVIGATION,0) != 0;
+ if (!mHideNavStatus && !hideNavStatus){
+ NavigationBarView mNavigationBarView = mNavigationBarController.getDefaultNavigationBarView();
+
+ if (mNavigationBarView == null)
+ mNavigationBarController.createNavigationBars(true,null);
+
+ mHideNavStatus = true;
+ }
+ }
+
+ private void hideNavigation() {
+ if (mHideNavStatus){
+ NavigationBarView mNavigationBarView = mNavigationBarController.getDefaultNavigationBarView();
+
+ if (mNavigationBarView != null)
+ mNavigationBarController.hideNavigationBar();
+
+ mHideNavStatus = false;
+ }
+ }
+
// TODO(b/117478341): This was left such that CarStatusBar can override this method.
// Try to remove this.
protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
case MSG_LAUNCH_TRANSITION_TIMEOUT:
onLaunchTransitionTimeout();
break;
+ case MSG_HIDE_NAVIGATION_STATUS:
+ setNavigationStatus();
+ break;
}
}
}
}
else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
mQSPanel.showDeviceMonitoringDialog();
+ }
+ else if(ACTION_HIDE_NAVIGATION.equals(action)) { //接收广播
+ mHandler.removeMessages(MSG_HIDE_NAVIGATION_STATUS);
+ mHandler.sendEmptyMessageDelayed(MSG_HIDE_NAVIGATION_STATUS, 300);
}
}
};
2.在NavigationBarController.java中添加
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
@@ -178,6 +178,16 @@ public class NavigationBarController implements Callbacks {
}
}
+ /**
+ * 隐藏导航栏
+ */
+ public void hideNavigationBar() {
+ Display[] displays = mDisplayManager.getDisplays();
+ for (Display display : displays) {
+ removeNavigationBar(display.getDisplayId());
+ }
+ }
+
/** @see NavigationBarFragment#checkNavBarModes() */
public void checkNavBarModes(int displayId) {
NavigationBarFragment navBar = mNavigationBars.get(displayId);
编译
./build.sh -Au
编译完成后烧录update.img
在上层app中调用
1.复制out\soong\.intermediates\frameworks\base\framework-minus-apex\android_common\jarjar\framework-minus-apex.jar 到AndroidStudio 项目的libs中
在build.gradle --- dependencies中添加依赖
compileOnly files('libs\\framework.jar')
2.在代码中调用
CustomManager customManager = (CustomManager) getSystemService("custom_service");
//显示导航栏
customManager.showNavigationBar();
//隐藏导航栏
customManager.hideNavigationBar();