Android16底部导航栏添加音量加减虚拟按键

芯片原厂发布给我们的Android16系统源码编译后,导航栏没有音量加减键,客户有反馈这个问题,之前在Android13系统也加过,但是移植过去需要稍微改动一下,否则编译都会报错,所以特意记录下,修改记录如下:frameworks/base目录下

java 复制代码
commit bf018b023d0cf281044ada362624b9be4513e56c
Author: incar <chs@incartech.cn>
Date:   Thu Nov 13 15:09:21 2025 +0800

    底部导航栏中添加音量加减键
    
    Change-Id: Id1a0fe55b5f05cfcaf4608f2abf5b49b52c79dfd

diff --git a/packages/SystemUI/res/drawable/ic_sysbar_volume_add_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_volume_add_button.xml
new file mode 100755
index 000000000000..76a145eff0cb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_volume_add_button.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="?attr/singleToneColor"
+        android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_volume_sub_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_volume_sub_button.xml
new file mode 100755
index 000000000000..69d86071ce10
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_volume_sub_button.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="28dp"
+        android:height="28dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="?attr/singleToneColor"
+        android:pathData="M18.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM5,9v6h4l5,5V4L9,9H5z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/volume_add.xml b/packages/SystemUI/res/layout/volume_add.xml
new file mode 100755
index 000000000000..6be528f2899b
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_add.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/volume_add"
+    android:layout_width="@dimen/navigation_key_width"
+    android:layout_height="match_parent"
+    android:layout_weight="0"
+    systemui:keyCode="24"
+    android:scaleType="center"
+    android:paddingStart="@dimen/navigation_key_padding"
+    android:paddingEnd="@dimen/navigation_key_padding"
+    />
+
diff --git a/packages/SystemUI/res/layout/volume_sub.xml b/packages/SystemUI/res/layout/volume_sub.xml
new file mode 100755
index 000000000000..29f88c18d9c0
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_sub.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/volume_sub"
+    android:layout_width="@dimen/navigation_key_width"
+    android:layout_height="match_parent"
+    android:layout_weight="0"
+    systemui:keyCode="25"
+    android:scaleType="center"
+    android:paddingStart="@dimen/navigation_key_padding"
+    android:paddingEnd="@dimen/navigation_key_padding"
+    />
+
diff --git a/packages/SystemUI/res/values-sw400dp/config.xml b/packages/SystemUI/res/values-sw400dp/config.xml
new file mode 100755
index 000000000000..5c37bfb34f68
--- /dev/null
+++ b/packages/SystemUI/res/values-sw400dp/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+
+    <!-- Nav bar button default ordering/layout -->
+    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add;right</string>
+
+</resources>
diff --git a/packages/SystemUI/res/values-sw400dp/dimens.xml b/packages/SystemUI/res/values-sw400dp/dimens.xml
old mode 100644
new mode 100755
index f19335bc6285..340697a37fcb
--- a/packages/SystemUI/res/values-sw400dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw400dp/dimens.xml
@@ -17,7 +17,8 @@
 <resources>
 
     <!-- The width of the view containing navigation buttons -->
-    <dimen name="navigation_key_width">80dip</dimen>
+    <dimen name="navigation_key_width">50dp</dimen>
+    <dimen name="navigation_key_padding">30dp</dimen>
 
     <!-- The padding on the side of the navigation bar. Must be greater than or equal to
          navigation_extra_key_width -->
diff --git a/packages/SystemUI/res/values-sw410dp/dimens.xml b/packages/SystemUI/res/values-sw410dp/dimens.xml
old mode 100644
new mode 100755
index ff6e005a94c7..285a637a0c57
--- a/packages/SystemUI/res/values-sw410dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw410dp/dimens.xml
@@ -26,6 +26,9 @@
 
     <dimen name="global_actions_grid_item_side_margin">12dp</dimen>
     <dimen name="global_actions_grid_item_height">72dp</dimen>
+	
+	<dimen name="navigation_key_width">55dp</dimen>
+    <dimen name="navigation_key_padding">33dp</dimen>
 
     <!-- Biometric Auth pattern view size, better to align keyguard_security_width -->
     <dimen name="biometric_auth_pattern_view_size">348dp</dimen>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
old mode 100644
new mode 100755
index 055c3a641d1b..8bba3bf4ebed
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -73,4 +73,7 @@
     <dimen name="lockscreen_shade_keyguard_transition_vertical_offset">83dp</dimen>
 
     <dimen name="notification_panel_margin_horizontal">24dp</dimen>
+	
+	<dimen name="navigation_key_width">120dp</dimen>
+    <dimen name="navigation_key_padding">50dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
old mode 100644
new mode 100755
index b4383156dc71..946ddbd45a12
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -27,7 +27,7 @@
     <bool name="config_quickSettingsMediaLandscapeCollapsed">false</bool>
 
     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">left;back,home,recent;right</string>
+    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add;right</string>
 
     <!-- orientation of the dead zone when touches have recently occurred elsewhere on screen -->
     <integer name="navigation_bar_deadzone_orientation">0</integer>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index ceb8c171fd83..7021b41d3ab6 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -362,7 +362,7 @@
     </string-array>
 
     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
+    <string name="config_navBarLayout" translatable="false">left[.5W];volume_sub,back,home,recent,volume_add;right[.5W]</string>
     <string name="config_navBarLayoutQuickstep" translatable="false">back[1.7WC];home;contextual[1.7WC]</string>
     <string name="config_navBarLayoutHandle" translatable="false">back[70AC];home_handle;ime_switcher[70AC]</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index 8bc3203ea51e..5cd4a79c7857 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -1379,6 +1379,21 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
         accessibilityButton.setOnClickListener(this::onAccessibilityClick);
         accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
         updateAccessibilityStateFlags();
+        ButtonDispatcher volumeAddButton=mView.getVolumeAddButton();
+        ButtonDispatcher volumeSubButton=mView.getVolumeSubButton();
+        //boolean isShowVolumeButton = "true".equals(SystemProperties.get("ro.rk.systembar.voiceicon","true"));
+        boolean isShowVolumeButton = true;
+        if(isShowVolumeButton){
+            volumeAddButton.setVisibility(View.VISIBLE);
+            volumeSubButton.setVisibility(View.VISIBLE);
+        }else{
+            volumeAddButton.setVisibility(View.GONE);
+            volumeSubButton.setVisibility(View.GONE);
+        }
+        if (mContext.getResources().getConfiguration().smallestScreenWidthDp < 400) {
+            volumeAddButton.setVisibility(View.GONE);
+            volumeSubButton.setVisibility(View.GONE);
+        }
 
         ButtonDispatcher imeSwitcherButton = mView.getImeSwitchButton();
         imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
@@ -1982,6 +1997,10 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
         updateButtonLocation(
                 region, touchRegionCache, mView.getAccessibilityButton(), inScreenSpace,
                 useNearestRegion);
+        updateButtonLocation(region, touchRegionCache, mView.getVolumeAddButton(), inScreenSpace,
+                useNearestRegion);
+        updateButtonLocation(region, touchRegionCache, mView.getVolumeSubButton(), inScreenSpace,
+                useNearestRegion);
         if (mView.getFloatingRotationButton().isVisible()) {
             // Note: this button is floating so the nearest region doesn't apply
             updateButtonLocation(
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
index 2c5a9c84645b..71b13f5d7784 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
@@ -68,6 +68,8 @@ public class NavigationBarInflaterView extends FrameLayout {
     public static final String RIGHT = "right";
     public static final String CONTEXTUAL = "contextual";
     public static final String IME_SWITCHER = "ime_switcher";
+    public static final String VOLUME_ADD = "volume_add";
+    public static final String VOLUME_SUB = "volume_sub";
 
     public static final String GRAVITY_SEPARATOR = ";";
     public static final String BUTTON_SEPARATOR = ",";
@@ -117,11 +119,13 @@ public class NavigationBarInflaterView extends FrameLayout {
     private boolean mIsVertical;
     private boolean mAlternativeOrder;
 
+    private int mDensity;
     private LauncherProxyService mLauncherProxyService;
     private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
 
     public NavigationBarInflaterView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mDensity = context.getResources().getConfiguration().densityDpi;
         createInflaters();
         mLauncherProxyService = Dependency.get(LauncherProxyService.class);
         mListener = new Listener(this);
@@ -137,6 +141,16 @@ public class NavigationBarInflaterView extends FrameLayout {
         mLandscapeInflater = LayoutInflater.from(mContext.createConfigurationContext(landscape));
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if(mDensity != newConfig.densityDpi || mDensity < 600){
+            mDensity = newConfig.densityDpi;
+            clearViews();
+            inflateLayout(mCurrentLayout);
+        }
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -405,6 +419,10 @@ public class NavigationBarInflaterView extends FrameLayout {
             v = inflater.inflate(R.layout.home_handle, parent, false);
         } else if (IME_SWITCHER.equals(button)) {
             v = inflater.inflate(R.layout.ime_switcher, parent, false);
+        } else if (VOLUME_ADD.equals(button)) {
+            v = inflater.inflate(R.layout.volume_add, parent, false);
+        } else if (VOLUME_SUB.equals(button)) {
+            v = inflater.inflate(R.layout.volume_sub, parent, false);
         } else if (button.startsWith(KEY)) {
             String uri = extractImage(button);
             int code = extractKeycode(button);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
index d2974e9f90bd..380e982dc57c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
@@ -47,6 +47,7 @@ import android.util.Log;
 import android.util.SparseArray;
 import android.view.ContextThemeWrapper;
 import android.view.Display;
+import android.view.Display.Mode;
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.View;
@@ -126,6 +127,8 @@ public class NavigationBarView extends FrameLayout {
     private KeyButtonDrawable mHomeDefaultIcon;
     private KeyButtonDrawable mRecentIcon;
     private KeyButtonDrawable mDockedIcon;
+    private KeyButtonDrawable mVolumeAddIcon;
+    private KeyButtonDrawable mVolumeSubIcon;
     private Context mLightContext;
     private int mLightIconColor;
     private int mDarkIconColor;
@@ -168,6 +171,7 @@ public class NavigationBarView extends FrameLayout {
      * fully locked mode we only show that unlocking is blocked.
      */
     private ScreenPinningNotify mScreenPinningNotify;
+    private boolean mIsRot0Landscape = true;
     private boolean mScreenPinningActive = false;
 
     /**
@@ -327,6 +331,10 @@ public class NavigationBarView extends FrameLayout {
         mTmpLastConfiguration = new Configuration();
         mConfiguration.updateFrom(context.getResources().getConfiguration());
 
+        Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
+        Mode displayMode = display.getMode();
+        mIsRot0Landscape = displayMode.getPhysicalWidth() > displayMode.getPhysicalHeight();
+        //Log.v(TAG, "PW=" + displayMode.getPhysicalWidth() + ", PH=" + displayMode.getPhysicalHeight());
         mScreenPinningNotify = new ScreenPinningNotify(mContext);
 
         mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
@@ -336,6 +344,8 @@ public class NavigationBarView extends FrameLayout {
         mButtonDispatchers.put(R.id.ime_switcher, imeSwitcherButton);
         mButtonDispatchers.put(R.id.accessibility_button, accessibilityButton);
         mButtonDispatchers.put(R.id.menu_container, mContextualButtonGroup);
+        mButtonDispatchers.put(R.id.volume_add, new ButtonDispatcher(R.id.volume_add));
+        mButtonDispatchers.put(R.id.volume_sub, new ButtonDispatcher(R.id.volume_sub));
         mDeadZone = new DeadZone(this);
     }
 
@@ -443,6 +453,14 @@ public class NavigationBarView extends FrameLayout {
         return mButtonDispatchers.get(R.id.accessibility_button);
     }
 
+    public ButtonDispatcher getVolumeAddButton() {
+        return mButtonDispatchers.get(R.id.volume_add);
+    }
+
+    public ButtonDispatcher getVolumeSubButton() {
+        return mButtonDispatchers.get(R.id.volume_sub);
+    }
+
     public ButtonDispatcher getHomeHandle() {
         return mButtonDispatchers.get(R.id.home_handle);
     }
@@ -483,6 +501,8 @@ public class NavigationBarView extends FrameLayout {
         if (orientationChange || densityChange || dirChange) {
             mBackIcon = getBackDrawable();
         }
+        mVolumeAddIcon = getDrawable(R.drawable.ic_sysbar_volume_add_button);
+        mVolumeSubIcon = getDrawable(R.drawable.ic_sysbar_volume_sub_button);
     }
 
     /**
@@ -614,6 +634,8 @@ public class NavigationBarView extends FrameLayout {
         }
         getHomeButton().setImageDrawable(homeIcon);
         getBackButton().setImageDrawable(backIcon);
+        getVolumeAddButton().setImageDrawable(mVolumeAddIcon);
+        getVolumeSubButton().setImageDrawable(mVolumeSubIcon);
 
         updateRecentsIcon();
 
相关推荐
又是努力搬砖的一年6 小时前
elasticsearch修改字段类型
android·大数据·elasticsearch
高山上有一只小老虎6 小时前
小红背单词
java·算法
Cosmoshhhyyy6 小时前
《Effective Java》解读第26条:请不要使用原生态类型
java·开发语言
阿杆.6 小时前
如何在 Spring Boot 中接入 Amazon ElastiCache
java·spring boot·后端
别惹CC6 小时前
Spring AI 进阶之路04:集成 SearXNG 实现联网搜索
java·后端·spring
invicinble6 小时前
springboot的日志体系
java·spring boot·后端
走在路上的菜鸟6 小时前
Android学Dart学习笔记第十八节 类-继承
android·笔记·学习·flutter
czlczl200209257 小时前
拒绝 DTO 爆炸:详解 Spring Boot 参数校验中的“分组校验” (Validation Groups) 技巧
java·spring boot·后端
悟空码字7 小时前
SpringBoot动态脱敏实战,从注解到AOP的优雅打码术
java·后端