Android システムでは、ステータス バー (StatusBar)、ナビゲーション バー (NavigationBar)、およびドロップダウン メニュー (ExPlan) が 3 つの一般的なユーザー インターフェイス要素であり、それぞれいくつかの基本的な情報表示と対話型機能を提供します。たとえば、ステータス バーには時間、電源、信号などの情報が表示され、ナビゲーション バーには戻る、ホームページ、マルチタスクなどのボタンが表示され、ドロップダウン メニューにはクイック設定や通知などのオプションが表示されます。 。すべての顧客の Android デバイスがこれらを必要またはサポートしているわけではないため、顧客がこれらの表示と非表示を自由に制御したい場合もあります。
この記事では、Android システムのステータス バー、ナビゲーション バー、ドロップダウン メニューのコントロール機能をカスタマイズして追加し、お客様のニーズに合わせて使用できるようにする方法を紹介します。
実装手順
ステータス バー、ナビゲーション バー、ドロップダウン メニューの制御機能を実装するには、次の部分を変更する必要があります。
- SystemUI モジュール: これは、ステータス バー、ナビゲーション バー、ドロップダウン メニューなどのインターフェイス要素の表示と管理を担当するシステム アプリケーションです。
- 設定モジュール: これは、ディスプレイ設定を含むさまざまなシステム設定オプションを提供するシステム アプリケーションです。
- システム プロパティ: これは、コマンド ラインまたはコードから読み書きできるシステム構成情報を保存および渡すためのメカニズムです。
- ブロードキャスト: これは、異なるコンポーネント間でメッセージを受け渡すために使用されるメカニズムであり、コマンド ラインまたはコードから送受信できます。
次の手順を完了する必要があります。
- SystemUI モジュールにブロードキャスト レシーバーを追加して、ステータス バー、ナビゲーション バー、ドロップダウン メニューの表示と非表示を制御するブロードキャストを受信し、対応する操作を実行します。
- SystemUI モジュールにシステム プロパティの読み取りを追加して、ステータス バー、ナビゲーション バー、ドロップダウン メニューの初期状態を取得し、対応するインターフェイス要素を作成または削除します。
- 設定モジュールにスイッチ設定項目を追加して、ステータス バー、ナビゲーション バー、ドロップダウン メニューの開閉を制御し、対応するブロードキャストを送信し、対応するシステム プロパティを書き込みます。
- 変更したシステムをコンパイルして実行し、セットアップで制御機能をテストします。
変更例
システムUIモジュール
フレームワーク/ベース/パッケージ/SystemUI/AndroidManifest.xml
受信するブロードキャストを宣言するには、次のコード行を SystemUI モジュールの AndroidManifest.xml ファイルに追加する必要があります。
<protected-broadcast android:name="sys.explan.show" />
<protected-broadcast android:name="sys.explan.hide" />
<protected-broadcast android:name="sys.statusbar.show" />
<protected-broadcast android:name="sys.statusbar.hide" />
<protected-broadcast android:name="sys.navigationbar.show" />
<protected-broadcast android:name="sys.navigationbar.hide" />
Frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
すべてのナビゲーション バーを削除するには、SystemUI モジュールの NavigationBarController.java ファイルに関数を追加する必要があります。
public void removeNavigationBars() {
Display[] displays = mDisplayManager.getDisplays();
for (Display display : displays) {
removeNavigationBar(display.getDisplayId());
}
}
Frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
SystemUI モジュールの PhoneStatusBarView.java ファイルを変更して、システム プロパティに基づいてドロップダウン メニューのタッチ イベントに応答するかどうかを決定する必要があります: (
このファイルが動的制御に使用されており、これ以外にバグがある場合は、ファイルに保存されている場合、他のすべては通常どおり変更されます)
- return barConsumedEvent || super.onTouchEvent(event);
+ /* String value = SystemProperties.get("persist.sys.explan.enable", "false");
+ if(value.equals("true")){
+ return barConsumedEvent || super.onTouchEvent(event);
+ }else{
+ return true;
+ }*/
+ //
+ return barConsumedEvent || super.onTouchEvent(event);
フレームワーク/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
SystemUI モジュールの StatusBar.java ファイルに、次のコード行を追加して、いくつかの変数とメソッドを宣言および初期化する必要があります。
+ private static final String ACTION_HIDE_EXPLAN = "sys.explan.hide";
+ private static final String ACTION_SHOW_EXPLAN = "sys.explan.show";
+ private static final String ACTION_HIDE_STATUS_BAR = "sys.statusbar.hide";
+ private static final String ACTION_SHOW_STATUS_BAR = "sys.statusbar.show";
+ private static final String ACTION_HIDE_NAVIGATION_BAR = "sys.navigationbar.hide";
+ private static final String ACTION_SHOW_NAVIGATION_BAR = "sys.navigationbar.show";
+ private static final String SYS_PROPERTY_STATUS_BAR = "persist.sys.statusbar.enable";
+ private static final String SYS_PROPERTY_NAVIGATION_BAR = "persist.sys.navigationbar.enable";
+ private static final String SYS_PROPERTY_EXPLAN = "persist.sys.explan.enable";
+ protected StatusBarManager mStatusBarManager;
+
public StatusBar(Context context) {
super(context);
...
+ mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
...
}
+
+ public void explan_show() {
+ mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
+ }
+ public void explan_hide() {
+ mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
+ }
SystemUI モジュールの StatusBar.java ファイルで、次のコード行を変更して、システム プロパティに基づいて初期化中にステータス バー、ナビゲーション バー、およびドロップダウン メニューを作成するか非表示にするかを決定する必要もあります。
- createAndAddWindows(result);
-
+ //ln28_add_start
+ if (!SystemProperties.getBoolean(SYS_PROPERTY_STATUS_BAR, false)) {
+ mStatusBarWindowController.setBarVisibility(View.GONE);
+ }
+ //ln28_add_end
if (mWallpaperSupported) {
...
}
-
- createNavigationBar(result);
-
+ //ln28_add_start
+ if (SystemProperties.getBoolean(SYS_PROPERTY_NAVIGATION_BAR, false)) {
+ createNavigationBar(result);
+ }
+ if (SystemProperties.getBoolean(SYS_PROPERTY_EXPLAN, false)) {
+ explan_show();
+ }
+ //ln28_add_end
if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
...
}
SystemUI モジュールの StatusBar.java ファイルに、論理的な動的制御を実現するために受信するブロードキャストを登録および処理する次のコード行を追加する必要もあります。
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_BAR);
+ filter.addAction(ACTION_SHOW_NAVIGATION_BAR);
+ filter.addAction(ACTION_HIDE_STATUS_BAR);
+ filter.addAction(ACTION_SHOW_STATUS_BAR);
+ filter.addAction(ACTION_HIDE_EXPLAN);
+ filter.addAction(ACTION_SHOW_EXPLAN);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
...
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
...
} else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
mQSPanel.showDeviceMonitoringDialog();
+ } else if (ACTION_HIDE_NAVIGATION_BAR.equals(action)) {
+ mNavigationBarController.removeNavigationBars();
+ SystemProperties.set(SYS_PROPERTY_NAVIGATION_BAR, "false");
+ } else if (ACTION_SHOW_NAVIGATION_BAR.equals(action)) {
+ createNavigationBar(null);
+ SystemProperties.set(SYS_PROPERTY_NAVIGATION_BAR, "true");
+ } else if (ACTION_HIDE_STATUS_BAR.equals(action)) {
+ mStatusBarWindowController.setBarVisibility(View.GONE);
+ SystemProperties.set(SYS_PROPERTY_STATUS_BAR, "false");
+ } else if (ACTION_SHOW_STATUS_BAR.equals(action)) {
+ mStatusBarWindowController.setBarVisibility(View.VISIBLE);
+ SystemProperties.set(SYS_PROPERTY_STATUS_BAR, "true");
+ } else if (ACTION_HIDE_EXPLAN.equals(action)) {
+ explan_hide();
+ SystemProperties.set(SYS_PROPERTY_EXPLAN, "false");
+ } else if (ACTION_SHOW_EXPLAN.equals(action)) {
+ explan_show();
+ SystemProperties.set(SYS_PROPERTY_EXPLAN, "true");
}
}
};
OK この時点で、SystemUI モジュールの変更は完了しました。とても簡単ですか? 次に、Settings モジュールを変更する必要があります。
設定モジュール
パッケージ/アプリ/設定/res/values/strings.xml
設定モジュールの strings.xml ファイルに、次のコード行を追加して、表示するスイッチ設定項目のタイトルを定義する必要があります。
<string name="ctrl_statusbar">状态栏</string>
<string name="ctrl_explan">下拉菜单</string>
<string name="ctrl_navigationbar">导航栏</string>
パッケージ/アプリ/設定/res/xml/display_settings.xml
設定モジュールの display_settings.xml ファイルに、次のコード行を追加して、表示するスイッチ設定を作成し、そのキー値とタイトルを指定する必要があります。
<SwitchPreference
android:key="ctrl_statusbar"
android:title="@string/ctrl_statusbar"/>
<SwitchPreference
android:key="ctrl_navigationbar"
android:title="@string/ctrl_navigationbar"/>
<SwitchPreference
android:key="ctrl_explan"
android:title="@string/ctrl_explan"/>
パッケージ/apps/Settings/src/com/android/settings/DisplaySettings.java
設定モジュールの DisplaySettings.java ファイルに、次のコード行を追加して、制御するスイッチ設定項目のコントローラーを登録する必要があります。
controllers.add(new ThemePreferenceController(context));
controllers.add(new BrightnessLevelPreferenceController(context, lifecycle));
controllers.add(new HdmiSettingsPreferenceController(context, KET_HDMI_SETTINGS));
+ controllers.add(new StatusBarPreferenceController(context));
+ controllers.add(new NavigationBarPreferenceController(context));
+ controllers.add(new ExPlanPreferenceController(context));
パッケージ/apps/Settings/src/com/android/settings/display/StatusBarPreferenceController.java
設定モジュールの StatusBarPreferenceController.java ファイルに、ステータス バー スイッチ設定項目のコントローラを実装するには、次のコード行を追加する必要があります。これは主に、システム プロパティの読み取りと書き込み、およびコントロール ブロードキャストの送信を担当します。
package com.android.settings.display;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import android.os.SystemProperties;
public class StatusBarPreferenceController extends AbstractPreferenceController implements
Preference.OnPreferenceChangeListener {
private static final String TAG = "StatusBarCtrl";
private static final boolean DEBUG = true;
private static final String KEY_STATUS_BAR = "ctrl_statusbar";
private static final String SYS_PROP_STATUS_BAR_ENABLE = "persist.sys.statusbar.enable";
public static final String ACTION_HIDE_STATUS_BAR = "sys.statusbar.hide";
public static final String ACTION_SHOW_STATUS_BAR = "sys.statusbar.show";
public StatusBarPreferenceController(Context context) {
super(context);
}
@Override
public String getPreferenceKey() {
return KEY_STATUS_BAR;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void displayPreference(PreferenceScreen screen) {
if (!isAvailable()) {
setVisible(screen, KEY_STATUS_BAR, false);
return;
}
final SwitchPreference mStatusBarPreference = screen.findPreference(KEY_STATUS_BAR);
if (mStatusBarPreference != null) {
String value = SystemProperties.get(SYS_PROP_STATUS_BAR_ENABLE, "false");
mStatusBarPreference.setChecked(value.equals("true"));
mStatusBarPreference.setOnPreferenceChangeListener(this);
}
}
@Override
public void updateState(Preference preference) {
String value = SystemProperties.get(SYS_PROP_STATUS_BAR_ENABLE, "false");
((SwitchPreference) preference).setChecked(value.equals("true"));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (DEBUG) {
Log.d(TAG, "key value " + value);
}
Intent intent = new Intent();
if (value) {
intent.setAction(ACTION_SHOW_STATUS_BAR);
} else {
intent.setAction(ACTION_HIDE_STATUS_BAR);
}
mContext.sendBroadcast(intent);
return true;
}
}
パッケージ/apps/Settings/src/com/android/settings/display/NavigationBarPreferenceController.java
設定モジュールの NavigationBarPreferenceController.java ファイルに、ナビゲーション バー スイッチ設定項目のコントローラーを実装するには、次のコード行を追加する必要があります。これは主に、システム プロパティの読み取りと書き込み、およびコントロール ブロードキャストの送信を担当します。
package com.android.settings.display;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import android.os.SystemProperties;
public class NavigationBarPreferenceController extends AbstractPreferenceController
implements Preference.OnPreferenceChangeListener {
private static final String TAG = "NavigationBarCtrl";
private static final boolean DEBUG = true;
private static final String KEY_NAVIGATION_BAR = "ctrl_navigationbar";
private static final String SYS_PROP_NAVIGATION_BAR_ENABLE = "persist.sys.navigationbar.enable";
public static final String ACTION_HIDE_NAVIGATION_BAR = "sys.navigationbar.hide";
public static final String ACTION_SHOW_NAVIGATION_BAR = "sys.navigationbar.show";
public NavigationBarPreferenceController(Context context) {
super(context);
}
@Override
public String getPreferenceKey() {
return KEY_NAVIGATION_BAR;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void displayPreference(PreferenceScreen screen) {
if (!isAvailable()) {
setVisible(screen, KEY_NAVIGATION_BAR, false);
return;
}
final SwitchPreference mNavigationBarPreference = screen.findPreference(KEY_NAVIGATION_BAR);
if (mNavigationBarPreference != null) {
String value = SystemProperties.get(SYS_PROP_NAVIGATION_BAR_ENABLE, "false");
mNavigationBarPreference.setChecked(value.equals("true"));
mNavigationBarPreference.setOnPreferenceChangeListener(this);
}
}
@Override
public void updateState(Preference preference) {
String value = SystemProperties.get(SYS_PROP_NAVIGATION_BAR_ENABLE, "false");
((SwitchPreference) preference).setChecked(value.equals("true"));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (DEBUG) {
Log.d(TAG, "key value " + value);
}
Intent intent = new Intent();
if (value) {
intent.setAction(ACTION_SHOW_NAVIGATION_BAR);
} else {
intent.setAction(ACTION_HIDE_NAVIGATION_BAR);
}
mContext.sendBroadcast(intent);
return true;
}
}
パッケージ/apps/Settings/src/com/android/settings/display/ExPlanPreferenceController.java
設定モジュールの ExPlanPreferenceController.java ファイルに、ドロップダウン メニューのスイッチ基本設定項目のコントローラーを実装するには、次のコード行を追加する必要があります。これは主に、システム プロパティの読み取りと書き込み、およびコントロール ブロードキャストの送信を担当します。
package com.android.settings.display;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import android.os.SystemProperties;
public class ExPlanPreferenceController extends AbstractPreferenceController implements
Preference.OnPreferenceChangeListener {
private static final String TAG = "ExPlanCtrl";
private static final boolean DEBUG = true;
private static final String KEY_EXPLAN = "ctrl_explan";
private static final String SYS_PROP_EXPLAN_ENABLE = "persist.sys.explan.enable";
private static final String ACTION_HIDE_EXPLAN = "sys.explan.hide";
private static final String ACTION_SHOW_EXPLAN = "sys.explan.show";
public ExPlanPreferenceController(Context context) {
super(context);
}
@Override
public String getPreferenceKey() {
return KEY_EXPLAN;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void displayPreference(PreferenceScreen screen) {
if (!isAvailable()) {
setVisible(screen, KEY_EXPLAN, false);
return;
}
final SwitchPreference mExPlanPreference = screen.findPreference(KEY_EXPLAN);
if (mExPlanPreference != null) {
String value = SystemProperties.get(SYS_PROP_EXPLAN_ENABLE, "false");
mExPlanPreference.setChecked(value.equals("true"));
mExPlanPreference.setOnPreferenceChangeListener(this);
}
}
@Override
public void updateState(Preference preference) {
String value = SystemProperties.get(SYS_PROP_EXPLAN_ENABLE, "false");
((SwitchPreference) preference).setChecked(value.equals("true"));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (DEBUG) {
Log.d(TAG, "key value " + value);
}
Intent intent = new Intent();
if (value) {
intent.setAction(ACTION_SHOW_EXPLAN);
} else {
intent.setAction(ACTION_HIDE_EXPLAN);
}
mContext.sendBroadcast(intent);
return true;
}
}
これで設定モジュールの変更は完了です。次に、変更したシステムを直接コンパイルして実行し、設定で制御機能をテストします。
試験結果
以下は、シミュレーターでのテストの結果です。ステータス バー、ナビゲーション バー、ドロップダウン メニューの表示と非表示の効果を確認できます。
これはすべてをオフにした場合の効果です
これはすべてをオンにした場合の効果です
再起動後、ここに設定が保存され、要件が完了していることがわかります。
属性のデフォルト値を設定したい場合は、場所を見つけて自分で追加できることを忘れていました。
+PRODUCT_PROPERTY_OVERRIDES += persist.sys.statusbar.enable=true
+PRODUCT_PROPERTY_OVERRIDES += persist.sys.navigationbar.enable=true
+PRODUCT_PROPERTY_OVERRIDES += persist.sys.explan.enable=true
結論
この記事では、Android システムにステータス バー、ナビゲーション バー、ドロップダウン メニューの制御機能を追加する方法を紹介します (主に SystemUI モジュールと設定モジュールの変更、システム プロパティとブロードキャストの使用)。これらの関数を使用すると、ユーザーはディスプレイ xx を有効にするかどうかの決定を制御し、呼び出すことができます。
この記事がお役に立てば幸いです。ご質問やご提案がございましたら、プライベート メッセージを送信してメッセージを残してください。