[Android]导航栏中插入电源菜单

  1. 新增 frameworks/base/packages/SystemUI/res/layout/power.xml
XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.navigationbar.buttons.KeyButtonView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res-auto"
    android:id="@+id/power"
    android:layout_width="@dimen/navigation_key_width"
    android:layout_height="match_parent"
    android:layout_weight="0"
    android:contentDescription="@string/accessibility_power"
    android:paddingStart="@dimen/navigation_key_padding"
    android:paddingEnd="@dimen/navigation_key_padding"
    android:scaleType="center"
    systemui:keyCode="0" />
  1. frameworks/base/packages/SystemUI/res/values/config.xml

默认状态下不显示新增的"Power"选项,在对应的overlay目录下可以将config_power_menu_show_enable设置成true.

XML 复制代码
 <!-- Insert power menu in navigation bar default if value is false-->
 <bool name="config_power_menu_show_enable">false</bool>

3.frameworks/base/packages/SystemUI/res/values/strings.xml

XML 复制代码
<!-- Content description of the power button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_power">Power</string>

4.frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java

java 复制代码
private void prepareNavigationBarView() {
        mView.reorient();

        ButtonDispatcher recentsButton = mView.getRecentsButton();
        recentsButton.setOnClickListener(this::onRecentsClick);
        recentsButton.setOnTouchListener(this::onRecentsTouch);

        ButtonDispatcher homeButton = mView.getHomeButton();
        homeButton.setOnTouchListener(this::onHomeTouch);
        homeButton.setNavBarButtonClickLogger(mNavBarButtonClickLogger);

        ButtonDispatcher backButton = mView.getBackButton();
        backButton.setNavBarButtonClickLogger(mNavBarButtonClickLogger);

        reconfigureHomeLongClick();

        ButtonDispatcher accessibilityButton = mView.getAccessibilityButton();
        accessibilityButton.setOnClickListener(this::onAccessibilityClick);
        accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
        updateAccessibilityStateFlags();

        ButtonDispatcher imeSwitcherButton = mView.getImeSwitchButton();
        imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);

        // Insert a Power menu to the navigation bar 20250411 add start
        ButtonDispatcher powerButton = mView.getPowerButton();
        powerButton.setOnClickListener(mPowerClickListener);
        // Insert a Power menu to the navigation bar 20250411 add end

        updateScreenPinningGestures();
}

// Insert a Power menu to the navigation bar 20250411 add start
private View.OnClickListener mPowerClickListener = new View.OnClickListener() {
        public void onClick(View v) {
            Intent intent = new Intent("android.intent.action.POWER_MENU");
            mContext.sendBroadcast(intent);
        }
};
//Insert a Power menu to the navigation bar 20250411 add end

5.frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java

java 复制代码
// Insert a Power menu to the navigation bar 20250411 add
public static final String POWER = "power";
private Context mContext;
private boolean mPowerMenuShowEnable = false;
public static final int SOHO_NAVIGATION_BAR_SIZE = 4;
// Insert a Power menu to the navigation bar 20250411 end


public NavigationBarInflaterView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // Insert a Power menu to the navigation bar 20250411 add
        mContext = context;
        if (mContext != null) {
            mPowerMenuShowEnable = mContext.getResources().getBoolean(
                    R.bool.config_power_menu_show_enable);
        }
        // Insert a Power menu to the navigation bar 20250411 end
        createInflaters();
        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
        mListener = new Listener(this);
        mNavBarMode = Dependency.get(NavigationModeController.class).addListener(mListener);
}

    protected void inflateLayout(String newLayout) {
        mCurrentLayout = newLayout;
        if (newLayout == null) {
            newLayout = getDefaultLayout();
        }
        // Insert a Power menu to the navigation bar 20250411 modify start
        if (mPowerMenuShowEnable) {
            String[] sets = newLayout.split(GRAVITY_SEPARATOR, SOHO_NAVIGATION_BAR_SIZE);
            if (sets.length != SOHO_NAVIGATION_BAR_SIZE) {
                Log.d(TAG, "Invalid layout.");
                newLayout = getDefaultLayout();
                sets = newLayout.split(GRAVITY_SEPARATOR, SOHO_NAVIGATION_BAR_SIZE);
            }
            String[] start = sets[0].split(BUTTON_SEPARATOR);
            String[] center = sets[1].split(BUTTON_SEPARATOR);
            String[] end = sets[2].split(BUTTON_SEPARATOR);
            String[] add = sets[3].split(BUTTON_SEPARATOR);
            inflateButtons(start, mHorizontal.findViewById(R.id.ends_group),
                    false /* landscape */, true /* start */);
            inflateButtons(start, mVertical.findViewById(R.id.ends_group),
                    true /* landscape */, true /* start */);
            inflateButtons(center, mHorizontal.findViewById(R.id.ends_group),
                    false /* landscape */, false /* start */);
            inflateButtons(center, mVertical.findViewById(R.id.ends_group),
                    true /* landscape */, false /* start */);
            inflateButtons(end, mHorizontal.findViewById(R.id.ends_group),
                    false /* landscape */, false /* start */);
            inflateButtons(end, mVertical.findViewById(R.id.ends_group),
                    true /* landscape */, false /* start */);
            inflateButtons(add, mHorizontal.findViewById(R.id.ends_group),
                    false /* landscape */, false /* start */);
            inflateButtons(add, mVertical.findViewById(R.id.ends_group),
                    true /* landscape */, false /* start */);
        } else {
            String[] sets = newLayout.split(GRAVITY_SEPARATOR, 3);
            if (sets.length != 3) {
                Log.d(TAG, "Invalid layout.");
                newLayout = getDefaultLayout();
                sets = newLayout.split(GRAVITY_SEPARATOR, 3);
            }
            String[] start = sets[0].split(BUTTON_SEPARATOR);
            String[] center = sets[1].split(BUTTON_SEPARATOR);
            String[] end = sets[2].split(BUTTON_SEPARATOR);
            // Inflate these in start to end order or accessibility traversal will be messed up.
            inflateButtons(start, mHorizontal.findViewById(R.id.ends_group),
                    false /* landscape */, true /* start */);
            inflateButtons(start, mVertical.findViewById(R.id.ends_group),
                    true /* landscape */, true /* start */);

            inflateButtons(center, mHorizontal.findViewById(R.id.center_group),
                    false /* landscape */, false /* start */);
            inflateButtons(center, mVertical.findViewById(R.id.center_group),
                    true /* landscape */, false /* start */);

            addGravitySpacer(mHorizontal.findViewById(R.id.ends_group));
            addGravitySpacer(mVertical.findViewById(R.id.ends_group));

            inflateButtons(end, mHorizontal.findViewById(R.id.ends_group),
                    false /* landscape */, false /* start */);
            inflateButtons(end, mVertical.findViewById(R.id.ends_group),
                    true /* landscape */, false /* start */);
        }
        // Insert a Power menu to the navigation bar 20250411 modify end
        updateButtonDispatchersCurrentView();
    }

View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
        View v = null;
        String button = extractButton(buttonSpec);
        if (LEFT.equals(button)) {
            button = extractButton(NAVSPACE);
        } else if (RIGHT.equals(button)) {
            button = extractButton(MENU_IME_ROTATE);
        }
        if (HOME.equals(button)) {
            v = inflater.inflate(R.layout.home, parent, false);
        } else if (BACK.equals(button)) {
            v = inflater.inflate(R.layout.back, parent, false);
        } else if (RECENT.equals(button)) {
            v = inflater.inflate(R.layout.recent_apps, parent, false);
        } else if (MENU_IME_ROTATE.equals(button)) {
            v = inflater.inflate(R.layout.menu_ime, parent, false);
        } else if (NAVSPACE.equals(button)) {
            v = inflater.inflate(R.layout.nav_key_space, parent, false);
        } else if (CLIPBOARD.equals(button)) {
            v = inflater.inflate(R.layout.clipboard, parent, false);
        } else if (CONTEXTUAL.equals(button)) {
            v = inflater.inflate(R.layout.contextual, parent, false);
        } else if (HOME_HANDLE.equals(button)) {
            v = inflater.inflate(R.layout.home_handle, parent, false);
        } else if (IME_SWITCHER.equals(button)) {
            v = inflater.inflate(R.layout.ime_switcher, parent, false);
        // Insert a Power menu to the navigation bar 20250411 add start
        } else if (POWER.equals(button)) {
            v = inflater.inflate(R.layout.power, parent, false);
        // Insert a Power menu to the navigation bar 20250411 add end
        } else if (button.startsWith(KEY)) {
            String uri = extractImage(button);
            int code = extractKeycode(button);
            v = inflater.inflate(R.layout.custom_key, parent, false);
            ((KeyButtonView) v).setCode(code);
            if (uri != null) {
                if (uri.contains(":")) {
                    ((KeyButtonView) v).loadAsync(Icon.createWithContentUri(uri));
                } else if (uri.contains("/")) {
                    int index = uri.indexOf('/');
                    String pkg = uri.substring(0, index);
                    int id = Integer.parseInt(uri.substring(index + 1));
                    ((KeyButtonView) v).loadAsync(Icon.createWithResource(pkg, id));
                }
            }
        }
        return v;
    }

6.frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java

java 复制代码
// Insert a Power menu to the navigation bar 20250411 add
private KeyButtonDrawable mPowerIcon;

public NavigationBarView(Context context, AttributeSet attrs) {
        super(context, attrs);

      // Insert a Power menu to the navigation bar 20250411 add
      mButtonDispatchers.put(R.id.power, new ButtonDispatcher(R.id.power));
}

// Insert a Power menu to the navigation bar 20250411 add start
public ButtonDispatcher getPowerButton() {
    return mButtonDispatchers.get(R.id.power);
}
// Insert a Power menu to the navigation bar 20250411 add end


private void updateIcons(Configuration oldConfig) {
        final boolean orientationChange = oldConfig.orientation != mConfiguration.orientation;
        final boolean densityChange = oldConfig.densityDpi != mConfiguration.densityDpi;
        final boolean dirChange = oldConfig.getLayoutDirection() != mConfiguration.getLayoutDirection();

        if (orientationChange || densityChange) {
            mDockedIcon = getDrawable(R.drawable.ic_sysbar_docked);
            mHomeDefaultIcon = getHomeDrawable();
        }
        if (densityChange || dirChange) {
            mRecentIcon = getDrawable(R.drawable.ic_sysbar_recent);
            mContextualButtonGroup.updateIcons(mLightIconColor, mDarkIconColor);
        }
        if (orientationChange || densityChange || dirChange) {
            mBackIcon = getBackDrawable();
        }
        // Insert a Power menu to the navigation bar 20250411 add
        mPowerIcon = getDrawable(R.drawable.ic_settings_power);
}

public void updateNavButtonIcons() {
...
    //Insert a Power menu to the navigation bar 20250411 add
    getPowerButton().setImageDrawable(mPowerIcon);

}

7.frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

java 复制代码
void init(Injector injector) {
    mContext = injector.getContext();
    ...
    //Insert a Power menu to the navigation bar 20250411 add start
    IntentFilter mPower = new IntentFilter("android.intent.action.POWER_MENU");
    mContext.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //show global actions dialog
            showGlobalActionsInternal();
        }
    }, mPower);
    //Insert a Power menu to the navigation bar 20250411 add end

    // register for multiuser-relevant broadcasts
    filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
    mContext.registerReceiver(mMultiuserReceiver, filter);
    ...
}
相关推荐
百锦再1 小时前
Android Studio开发中Application和Activity生命周期详解
android·java·ide·app·gradle·android studio·studio
移动开发者1号2 小时前
Android现代进度条替代方案
android·app
万户猴2 小时前
【Android蓝牙开发实战-11】蓝牙BLE多连接机制全解析1
android·蓝牙
RichardLai882 小时前
[Flutter 基础] - Flutter基础组件 - Icon
android·flutter
前行的小黑炭2 小时前
Android LiveData源码分析:为什么他刷新数据比Handler好,能更节省资源,解决内存泄漏的隐患;
android·kotlin·android jetpack
清霜之辰3 小时前
安卓 Compose 相对传统 View 的优势
android·内存·性能·compose
_祝你今天愉快3 小时前
再看!NDK交叉编译动态库并在Android中调用
android
一杯凉白开3 小时前
Android View 事件的分发机制 四句口诀 先问拦截再派送,子不处理父兜底, 一旦消费无后续, 滑动冲突靠逻辑。
android
星途码客3 小时前
SQLyog中DELIMITER执行存储过程时出现的前置缩进问题
android