• Android11在导航栏中添加软关机按钮 M


    一、配置文件准备:

    1.准备一张power按钮的图片:

      Android11和以往又有不同,不再是用png格式的图片,用的是矢量图。可以阿里巴巴矢量图库里面招图片,再用as转成xml文件,内容如下:

      packages/SystemUI/res/drawable/ic_sysbar_power.xml

    <?xml version="1.0" encoding="utf-8"?>
    <!--
         Copyright (C) 2018 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.
    -->
    <vector android:height="24dp" android:viewportHeight="1024"
        android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
        <path android:fillColor="#FFFFFF" android:pathData="M705.6,124.9c-5.3,-2.7 -11.6,1.2 -11.6,7.2v64.2c0,5.5 2.9,10.6 7.5,13.6 22.4,14.1 43.2,30.7 62.2,49.8 32.7,32.8 58.4,70.9 76.3,113.3 18.5,43.9 27.9,90.5 27.9,138.7 0,48.1 -9.4,94.8 -27.9,138.7 -17.9,42.4 -43.6,80.5 -76.3,113.3 -32.7,32.8 -70.8,58.5 -113.2,76.4 -43.8,18.6 -90.5,28 -138.5,28s-94.7,-9.4 -138.5,-28c-42.4,-17.9 -80.5,-43.6 -113.2,-76.4 -32.7,-32.8 -58.4,-70.9 -76.3,-113.3 -18.5,-43.9 -27.9,-90.5 -27.9,-138.7 0,-48.1 9.4,-94.8 27.9,-138.7 17.9,-42.4 43.6,-80.5 76.3,-113.3 19,-19 39.8,-35.6 62.2,-49.8 4.7,-2.9 7.5,-8.1 7.5,-13.6V132c0,-6 -6.3,-9.8 -11.6,-7.2C178.5,195.2 82,339.3 80,506.3 77.2,745.1 272.5,943.5 511.2,944c239,0.5 432.8,-193.3 432.8,-432.4 0,-169.2 -97,-315.7 -238.4,-386.7z"/>
        <path android:fillColor="#FFFFFF" android:pathData="M480,560h64c4.4,0 8,-3.6 8,-8V88c0,-4.4 -3.6,-8 -8,-8h-64c-4.4,0 -8,3.6 -8,8v464c0,4.4 3.6,8 8,8z"/>
    </vector>

    2.添加按键布局:

    diff --git a/packages/SystemUI/res/layout/power.xml b/packages/SystemUI/res/layout/power.xml
    new file mode 100755
    index 0000000..013577f
    --- /dev/null
    +++ b/packages/SystemUI/res/layout/power.xml
    @@ -0,0 +1,29 @@
    +<?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.statusbar.policy.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"
    +    systemui:keyCode="0"
    +    android:scaleType="center"
    +    android:contentDescription="@string/accessibility_power"
    +    android:paddingStart="@dimen/navigation_key_padding"
    +    android:paddingEnd="@dimen/navigation_key_padding"
    +    />
    +
    diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
    old mode 100644
    new mode 100755
    index 174f5c7..34c65af
    --- a/packages/SystemUI/res/values/strings.xml
    +++ b/packages/SystemUI/res/values/strings.xml
    @@ -302,6 +302,8 @@
         <string name="accessibility_back">Back</string>
         <!-- Content description of the home button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
         <string name="accessibility_home">Home</string>
    +    <!-- Content description of the power button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
    +    <string name="accessibility_power">Power</string>
         <!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
         <string name="accessibility_menu">Menu</string>
         <!-- Content description of the accessibility button in the navigation bar (not shown on the screen). [CHAR LIMIT=NONE] -->

    3.修改config文件:

    diff --git a/packages/SystemUI/res/values-sw400dp/config.xml b/packages/SystemUI/res/values-sw400dp/config.xml
    old mode 100644
    new mode 100755
    index de33fb5..1a70147
    --- a/packages/SystemUI/res/values-sw400dp/config.xml
    +++ b/packages/SystemUI/res/values-sw400dp/config.xml
    @@ -22,6 +22,6 @@
     <resources>
     
         <!-- Nav bar button default ordering/layout -->
    -    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add,screenshot;right</string>
    +    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add,screenshot,power;right</string>
     
     </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 3c0ee9f..a434084
    --- a/packages/SystemUI/res/values-sw600dp/config.xml
    +++ b/packages/SystemUI/res/values-sw600dp/config.xml
    @@ -27,7 +27,7 @@
         <integer name="quick_settings_user_time_settings_tile_span">1</integer>
     
         <!-- Nav bar button default ordering/layout -->
    -    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add,screenshot;right</string>
    +    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add,screenshot,power;right</string>
     
         <!-- Animation duration when using long press on recents to dock -->
         <integer name="long_press_dock_anim_duration">290</integer>
    diff --git a/packages/SystemUI/res/values-sw720dp/config.xml b/packages/SystemUI/res/values-sw720dp/config.xml
    old mode 100644
    new mode 100755
    index b850aef..b28e749
    --- a/packages/SystemUI/res/values-sw720dp/config.xml
    +++ b/packages/SystemUI/res/values-sw720dp/config.xml
    @@ -27,6 +27,6 @@
         <integer name="keyguard_max_notification_count">5</integer>
     
         <!-- Nav bar button default ordering/layout -->
    -    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add,screenshot;right</string>
    +    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add,screenshot,power;right</string>
     </resources>
     
    diff --git a/packages/SystemUI/res/values-sw900dp/config.xml b/packages/SystemUI/res/values-sw900dp/config.xml
    old mode 100644
    new mode 100755
    index f957d6e..1adb097
    --- a/packages/SystemUI/res/values-sw900dp/config.xml
    +++ b/packages/SystemUI/res/values-sw900dp/config.xml
    @@ -19,6 +19,6 @@
     <resources>
     
         <!-- Nav bar button default ordering/layout -->
    -    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add,screenshot;right</string>
    +    <string name="config_navBarLayout" translatable="false">left;volume_sub,back,home,recent,volume_add,screenshot,power;right</string>
     
     </resources>
    diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
    old mode 100644
    new mode 100755
    index eedfe31..9c659ae
    --- a/packages/SystemUI/res/values/config.xml
    +++ b/packages/SystemUI/res/values/config.xml
    @@ -341,7 +341,7 @@
         </string-array>
     
         <!-- Nav bar button default ordering/layout -->
    -    <string name="config_navBarLayout" translatable="false">left[.5W];volume_sub,back,home,recent,volume_add,screenshot;right[.5W]</string>
    +    <string name="config_navBarLayout" translatable="false">left[.5W];volume_sub,back,home,recent,volume_add,screenshot,power;right[.5W]</string>
         <string name="config_navBarLayoutQuickstep" translatable="false">back[1.7WC];home;contextual[1.7WC]</string>
         <string name="config_navBarLayoutHandle" translatable="false">back[40AC];home_handle;ime_switcher[40AC]</string>

    二、java代码实现

      1.添加按钮:

    diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
    old mode 100644
    new mode 100755
    index 7014673..94dd1c1
    --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
    +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
    @@ -67,6 +67,7 @@ public class NavigationBarInflaterView extends FrameLayout
         public static final String SCREENSHOT = "screenshot";
         public static final String VOLUME_ADD = "volume_add";
         public static final String VOLUME_SUB = "volume_sub";
    +    public static final String POWER = "power";
     
         public static final String GRAVITY_SEPARATOR = ";";
         public static final String BUTTON_SEPARATOR = ",";
    @@ -405,6 +406,8 @@ public class NavigationBarInflaterView extends FrameLayout
                 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 (POWER.equals(button)) {
    +            v = inflater.inflate(R.layout.power, parent, false);
             } else if (button.startsWith(KEY)) {
                 String uri = extractImage(button);
                 int code = extractKeycode(button);
    diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
    old mode 100644
    new mode 100755
    index 6b4a157..1679e89
    --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
    +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
    @@ -125,6 +125,7 @@ public class NavigationBarView extends FrameLayout implements
         private KeyButtonDrawable mVolumeAddIcon;
         private KeyButtonDrawable mVolumeSubIcon;
         private KeyButtonDrawable mScreenshotIcon;
    +    private KeyButtonDrawable mPowerIcon;
     
         private EdgeBackGestureHandler mEdgeBackGestureHandler;
         private final DeadZone mDeadZone;
    @@ -335,6 +336,7 @@ public class NavigationBarView extends FrameLayout implements
             mButtonDispatchers.put(R.id.screenshot, new ButtonDispatcher(R.id.screenshot));
             mButtonDispatchers.put(R.id.volume_add, new ButtonDispatcher(R.id.volume_add));
             mButtonDispatchers.put(R.id.volume_sub, new ButtonDispatcher(R.id.volume_sub));
    +        mButtonDispatchers.put(R.id.power, new ButtonDispatcher(R.id.power));
             mDeadZone = new DeadZone(this);
     
             mNavColorSampleMargin = getResources()
    @@ -491,6 +493,10 @@ public class NavigationBarView extends FrameLayout implements
             return mButtonDispatchers.get(R.id.volume_sub);
         }
     
    +    public ButtonDispatcher getPowerButton() {
    +        return mButtonDispatchers.get(R.id.power);
    +    }
    +
         public RotationContextButton getRotateSuggestionButton() {
             return (RotationContextButton) mButtonDispatchers.get(R.id.rotate_suggestion);
         }
    @@ -539,6 +545,7 @@ public class NavigationBarView extends FrameLayout implements
             mVolumeAddIcon = getDrawable(R.drawable.ic_sysbar_volume_add_button);
             mVolumeSubIcon = getDrawable(R.drawable.ic_sysbar_volume_sub_button);
             mScreenshotIcon = getDrawable(R.drawable.ic_sysbar_capture_button);
    +        mPowerIcon = getDrawable(R.drawable.ic_sysbar_power);
         }
     
         public KeyButtonDrawable getBackDrawable() {
    @@ -695,6 +702,7 @@ public class NavigationBarView extends FrameLayout implements
             getVolumeAddButton().setImageDrawable(mVolumeAddIcon);
             getVolumeSubButton().setImageDrawable(mVolumeSubIcon);
             getScreenshotButton().setImageDrawable(mScreenshotIcon);
    +        getPowerButton().setImageDrawable(mPowerIcon);
     
             updateRecentsIcon();

    2.点击按键时动作处理:

    diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/
    android/systemui/statusbar/phone/NavigationBarFragment.java
    old mode 100644
    new mode 100755
    index 95a9eda..3ef4c3a
    --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
    +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
    @@ -1049,6 +1049,24 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
                 volumeAddButton.setVisibility(View.GONE);
                 volumeSubButton.setVisibility(View.GONE);
             }
    +
    +        ButtonDispatcher powerButton = mNavigationBarView.getPowerButton();
    +        powerButton.setOnClickListener(this:: powerClick);
    +        powerButton.setOnTouchListener(this:: powerTouch);
    +
    +    }
    +
    +    private boolean powerTouch(View v, MotionEvent event) {
    +        if (event.getAction() == MotionEvent.ACTION_UP) {
    +            Intent intent=new Intent("com.xzy.systemui.poweroff");
    +            getContext().sendBroadcast(intent);
    +        }
    +        return false;
    +    }
    +
    +    private void powerClick(View v) {
    +            Intent intent=new Intent("com.xzy.systemui.poweroff");
    +            getContext().sendBroadcast(intent);
         }
     
         private boolean onHomeTouch(View v, MotionEvent event) {

    点击按钮,发出关机消息的广播。

    3.关机弹框的实现:

      注册广播,接受到广播后弹出关机重启选择的弹框

    diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
    index d966f36..4671c2f 100755
    --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
    +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
    @@ -2020,6 +2020,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
             filter = new IntentFilter();
             filter.addAction(Intent.ACTION_DREAMING_STARTED);
             filter.addAction(Intent.ACTION_DREAMING_STOPPED);
    +        filter.addAction("com.xzy.systemui.poweroff"); 
             context.registerReceiver(mDreamReceiver, filter);
     
             // register for multiuser-relevant broadcasts
    @@ -4494,6 +4495,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                     if (mKeyguardDelegate != null) {
                         mKeyguardDelegate.onDreamingStopped();
                     }
    +            } else if("com.xzy.systemui.poweroff".equals(intent.getAction())) {
    +                               
    +                Slog.v(TAG, "wmc...Receive a soft poweroff broadcast.");
    +                showGlobalActionsInternal();                 
                 }
             }
         };
    showGlobalActionsInternal这个方法是调出关机弹框的。
    但此时发现弹框是这样的:

    经过了解,发现Android 原生的关机界面有两种,一种是LegacyGlobalActions(以上图片)中的dialog,另一种是SystemUI中的GlobalActionsDialog。

    继续看弹框的代码流程:

    void showGlobalActionsInternal() {
            if (mGlobalActions == null) {
                mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
            }
            final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
            mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
            // since it took two seconds of long press to bring this up,
            // poke the wake lock so they have some time to see the dialog.
            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
        }
    showGlobalActionsInternal->mGlobalActions.showDialog
    services/core/java/com/android/server/policy/GlobalActions.java
    public void showDialog(boolean keyguardShowing, boolean deviceProvisioned) {
            if (DEBUG) Slog.d(TAG, "showDialog " + keyguardShowing + " " + deviceProvisioned);
            if (mGlobalActionsProvider != null && mGlobalActionsProvider.isGlobalActionsDisabled()) {
                return;
            }
            mKeyguardShowing = keyguardShowing;
            mDeviceProvisioned = deviceProvisioned;
            mShowing = true;
            if (mGlobalActionsAvailable && !"box".equals(SystemProperties.get("ro.target.product","unkonw"))) {
                mHandler.postDelayed(mShowTimeout, 5000);
                mGlobalActionsProvider.showGlobalActions();
            } else {
                // SysUI isn't alive, show legacy menu.
                ensureLegacyCreated();
                mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned);
            }
        }

    在这里就能找到原因了,编译的系统ro.target.product不是box的,所以流程走的是mLegacyGlobalActions.showDialog,即前面调出的图片。

    这样修改一下即可:

    index ecd1eab..31250a9 100755
    --- a/services/core/java/com/android/server/policy/GlobalActions.java
    +++ b/services/core/java/com/android/server/policy/GlobalActions.java
    @@ -65,7 +65,7 @@ class GlobalActions implements GlobalActionsProvider.GlobalActionsListener {
             mKeyguardShowing = keyguardShowing;
             mDeviceProvisioned = deviceProvisioned;
             mShowing = true;
    -        if (mGlobalActionsAvailable && !"box".equals(SystemProperties.get("ro.target.product","unkonw"))) {
    +        if (mGlobalActionsAvailable && !"tablet".equals(SystemProperties.get("ro.target.product","unkonw"))) {
                 mHandler.postDelayed(mShowTimeout, 5000);
                 mGlobalActionsProvider.showGlobalActions();
             } else {

    此时弹框图片:

     

     参考:https://blog.csdn.net/An_Times/article/details/122043152

  • 相关阅读:
    java调用restful webservice(转)
    精心挑选的12款优秀 jQuery Ajax 分页插件和教程
    android shape的使用
    android 获取资源文件 r.drawable中的图片转换为drawable、bitmap
    jquery+ajax分页
    ImageButton自定义按钮的按下效果的高效实现方法(非一般)
    ActionBarSherlock SlidingMenu整合,解决SlidingMenu example的getSupportActionBar()方法不能用问题
    sdk manager更新失败,显示Download interrupted: read timed out,应该如何解决?
    Android SDK 下载速度慢解决方法
    android 让图片充满整个屏幕
  • 原文地址:https://www.cnblogs.com/wmc245376374/p/16374130.html
Copyright © 2020-2023  润新知