RK3288安卓7.1系统定制屏幕上面从底部往上滑显示状态栏,并且添加一个虚拟按键再次显示状态栏

实现功能:安卓系统屏幕上任意位置连续点击5次后系统自动隐藏导航栏
现场环境:导航栏+状态栏隐藏,谷歌浏览器作为launcher启动并且进入
难点:任意位置点击5下这个事件如何捕捉

参考apk捕捉点击5下事件代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    final static int COUNTS = 5;// 点击次数
    final static long DURATION = 1000;// 规定有效时间
    long[] mHits = new long[COUNTS];
    Button bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        continuousClick(COUNTS, DURATION);
    }

    private void continuousClick(int count, long time) {
        //每次点击时,数组向前移动一位
        System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
        //为数组最后一位赋值
        mHits[mHits.length - 1] = SystemClock.uptimeMillis();
        if (mHits[0] >= (SystemClock.uptimeMillis() - DURATION)) {
            mHits = new long[COUNTS];//重新初始化数组
            Toast.makeText(this, "连续点击了5次", Toast.LENGTH_LONG).show();
        }
    }


}

可以参考安卓原生实现,连续点击系统版本5次,进入开发者模式,这个点击事件和系统版本这个按键进行了绑定,所有比较好处理,但是我们这边谷歌浏览器源代码改不了,只能从framework系统层面想办法,看framework是如何捕捉点击事件的。

更新时间:20230629
更改需求:从屏幕地下向上滑动,显示状态栏,并且添加一个虚拟按键用于再次隐藏状态栏
思路:用PhoneWindowManager提供的onSwipeFromBottom()接口就能捕捉从底部向上滑动这个事件,然后调用一个函数用于隐藏状态栏。
代码如下:

--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1906,8 +1906,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                     }
                     @Override
                     public void onSwipeFromBottom() {
+                        Log.i(TAG,"onSwipeFromBottom ...AAA");
                         if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
                             requestTransientBars(mNavigationBar);
+                            Log.i(TAG, "mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM");
+                        }else{
+                            Log.i(TAG,"onSwipeFromBottom ...");
+                            showNavigationBar();
                         }
                     }
                     @Override
@@ -2000,6 +2005,24 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                 mStatusBarController.getAppTransitionListener());
     }

+
+
+    private void showNavigationBar(){
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    IStatusBarService statusbar = getStatusBarService();
+                    if (statusbar != null) {
+                        statusbar.showNavigationBar();
+                    }
+                } catch (RemoteException e) {
+                    mStatusBarService = null;
+                }
+            }
+        });
+    }

从底部向上滑动触发PhoneWindowManager的onSwipeFromBottom()函数,我们在这个函数里面调用showNavigationBar()用handler将消息发送出去。消息里面new了一个新的工作线程,并且调用了statusbar.showNavigationBar()。

--- a/frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -632,6 +632,24 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
         }
     }

+    @Override
+    public void showNavigationBar() {
+        enforceStatusBar();
+        android.util.Log.d(TAG , " showNavigationBar...");
+        synchronized(mLock) {
+            mHandler.post(new Runnable() {
+                    public void run() {
+                        if (mBar != null) {
+                            try {
+                                mBar.showNavigationBar();
+                            } catch (RemoteException ex) {
+                            }
+                        }
+                    }
+                });
+        }
+    }

然后StatusBarManagerService的showNavigationBar()函数被调用。这个函数做的事情和上一个一样,通过handler创建一个新线程,线程里面调用 mBar.showNavigationBar()。

--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -77,6 +77,7 @@ public class CommandQueue extends IStatusBar.Stub {
     private static final int MSG_APP_TRANSITION_FINISHED       = 31 << MSG_SHIFT;
     private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS    = 32 << MSG_SHIFT;
     private static final int MSG_HANDLE_SYSNAV_KEY             = 33 << MSG_SHIFT;
+    private static final int MSG_SHOW_NAVIGATIONBAR            = 34 << MSG_SHIFT;

     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -103,6 +104,7 @@ public class CommandQueue extends IStatusBar.Stub {
         void animateExpandSettingsPanel(String obj);
         void setSystemUiVisibility(int vis, int fullscreenStackVis,
                 int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds);
+        void showNavigationBar();
         void topAppWindowChanged(boolean visible);
         void setImeWindowStatus(IBinder token, int vis, int backDisposition,
                 boolean showImeSwitcher);
@@ -198,6 +200,13 @@ public class CommandQueue extends IStatusBar.Stub {
         }
     }

+    public void showNavigationBar() {
+        synchronized (mLock) {
+            mHandler.removeMessages(MSG_SHOW_NAVIGATIONBAR);
+            mHandler.sendEmptyMessage(MSG_SHOW_NAVIGATIONBAR);
+        }
+    }
+
     public void topAppWindowChanged(boolean menuVisible) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_TOP_APP_WINDOW_CHANGED);
@@ -471,6 +480,9 @@ public class CommandQueue extends IStatusBar.Stub {
                 case MSG_NOTIFICATION_LIGHT_OFF:
                     mCallbacks.notificationLightOff();
                     break;
+                case MSG_SHOW_NAVIGATIONBAR:
+                   mCallbacks.showNavigationBar();
+                   break;
                 case MSG_NOTIFICATION_LIGHT_PULSE:
                     mCallbacks.notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
                     break;

mBar.showNavigationBar()会将消息传递到CommandQueue,然后执行CommandQueue里面的showNavigationBar,handlerMessage就调用回调函数的mCallbacks.showNavigationBar()。

--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -212,6 +212,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;

+import javax.security.auth.callback.Callback;
+
 public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
         DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
         OnHeadsUpChangedListener, VisualStabilityManager.Callback {
@@ -1111,6 +1113,26 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
             mKeyguardUserSwitcher.onDensityOrFontScaleChanged();
         }
     }
+    @Override // CommandQueue
+    public void showNavigationBar() {
+       Log.i("way", TAG + " addNavigationBar...");
+        forceAddNavigationBar();
+    }
+
+
+    private void forceAddNavigationBar() {
+        // If we have no Navbar view and we should have one, create it
+        if (mNavigationBarView != null) {
+            return;
+        }
+
+        mNavigationBarView =
+                (NavigationBarView) View.inflate(mContext, R.layout.navigation_bar, null);
+
+        mNavigationBarView.setDisabledFlags(mDisabled);
+        addNavigationBar(); // dynamically adding nav bar, reset System UI visibility!
+    }
+

然后在回调函数PhoneStatusBar.PhoneStatusBar()将状态栏再次展现出来即可。
aidl需要添加接口:

--- a/frameworks/base/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/frameworks/base/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -113,4 +113,5 @@ oneway interface IStatusBar
     void remQsTile(in ComponentName tile);
     void clickQsTile(in ComponentName tile);
     void handleSystemNavigationKey(in int key);
+    void showNavigationBar();
 }
diff --git a/frameworks/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/frameworks/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 698e387175..6893ce3c1b 100644
--- a/frameworks/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/frameworks/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -67,4 +67,5 @@ interface IStatusBarService
     void remTile(in ComponentName tile);
     void clickTile(in ComponentName tile);
     void handleSystemNavigationKey(in int key);
+    void showNavigationBar();
 }

然后再添加一个虚拟按键,用来隐藏状态栏。

diff --git a/frameworks/base/packages/SystemUI/res/drawable-nodpi/hide_bar_btn.png b/frameworks/base/packages/SystemUI/res/drawable-nodpi/hide_bar_btn.png
new file mode 100644
index 0000000000..cb6de860fc
Binary files /dev/null and b/frameworks/base/packages/SystemUI/res/drawable-nodpi/hide_bar_btn.png differ
diff --git a/frameworks/base/packages/SystemUI/res/layout/hide_bar_btn.xml b/frameworks/base/packages/SystemUI/res/layout/hide_bar_btn.xml
new file mode 100644
index 0000000000..3901f25971
--- /dev/null
+++ b/frameworks/base/packages/SystemUI/res/layout/hide_bar_btn.xml
@@ -0,0 +1,14 @@
+<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/hide_bar_btn"
+android:layout_width="@dimen/navigation_key_width"
+android:layout_height="match_parent"
+android:layout_weight="0"
+android:src="@drawable/hide_bar_btn"
+systemui:keyCode="0"
+android:scaleType="center"
+android:contentDescription="@string/hide_bar_btn"
+android:paddingStart="@dimen/navigation_key_padding"
+android:paddingEnd="@dimen/navigation_key_padding"
+/>
diff --git a/frameworks/base/packages/SystemUI/res/values-sw600dp/config.xml b/frameworks/base/packages/SystemUI/res/values-sw600dp/config.xml
index aa03ab2f28..8d437dc1b3 100644
--- a/frameworks/base/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/frameworks/base/packages/SystemUI/res/values-sw600dp/config.xml
@@ -34,7 +34,7 @@
     <bool name="config_keyguardUserSwitcher">true</bool>

     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">space;volume_sub,back,home,recent,volume_add,screenshot;menu_ime</string>
+    <string name="config_navBarLayout" translatable="false">space;hide_bar_btn;volume_sub,back,home,recent,volume_add,screenshot;menu_ime</string>

     <!-- Animation duration when using long press on recents to dock -->
     <integer name="long_press_dock_anim_duration">290</integer>
diff --git a/frameworks/base/packages/SystemUI/res/values-sw900dp/config.xml b/frameworks/base/packages/SystemUI/res/values-sw900dp/config.xml
index 016f7e582d..dfd6a95255 100644
--- a/frameworks/base/packages/SystemUI/res/values-sw900dp/config.xml
+++ b/frameworks/base/packages/SystemUI/res/values-sw900dp/config.xml
@@ -19,6 +19,6 @@
 <resources>

     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">space;volume_sub,back,home,recent,volume_add,screenshot;menu_ime</string>
+    <string name="config_navBarLayout" translatable="false">space;hide_bar_btn;volume_sub,back,home,recent,volume_add,screenshot;menu_ime</string>

 </resources>
diff --git a/frameworks/base/packages/SystemUI/res/values/config.xml b/frameworks/base/packages/SystemUI/res/values/config.xml
index da5f4bff48..f3b29fbc33 100644
--- a/frameworks/base/packages/SystemUI/res/values/config.xml
+++ b/frameworks/base/packages/SystemUI/res/values/config.xml
@@ -280,7 +280,7 @@
     <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>

     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">space;volume_sub,back,home,recent,volume_add,screenshot;menu_ime</string>
+    <string name="config_navBarLayout" translatable="false">space;hide_bar_btn;volume_sub,back,home,recent,volume_add,screenshot;menu_ime</string>

     <bool name="quick_settings_show_full_alarm">false</bool>

diff --git a/frameworks/base/packages/SystemUI/res/values/strings.xml b/frameworks/base/packages/SystemUI/res/values/strings.xml
index 4a51329215..0425791349 100644
--- a/frameworks/base/packages/SystemUI/res/values/strings.xml
+++ b/frameworks/base/packages/SystemUI/res/values/strings.xml
@@ -153,6 +153,8 @@
     <!-- Title of confirmation dialog for USB debugging -->
     <string name="usb_debugging_title">Allow USB debugging?</string>

+     <string name="hide_bar_btn" translatable="false">hide_bar</string>
+
     <!-- Message of confirmation dialog for USB debugging -->
     <string name="usb_debugging_message">The computer\'s RSA key fingerprint is:\n<xliff:g id="fingerprint">%1$s</xliff:g></string>

这部分比较简单就不讲解了,应该都能看懂。

--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -134,7 +134,6 @@ public class NavigationBarView extends LinearLayout {
                 mHomeAppearing = false;
             }
         }
-
         public void onBackAltCleared() {
             ButtonDispatcher backButton = getBackButton();

@@ -207,6 +206,7 @@ public class NavigationBarView extends LinearLayout {
         mButtonDisatchers.put(R.id.screenshot, new ButtonDispatcher(R.id.screenshot));
         mButtonDisatchers.put(R.id.volume_add, new ButtonDispatcher(R.id.volume_add));
         mButtonDisatchers.put(R.id.volume_sub, new ButtonDispatcher(R.id.volume_sub));
+        mButtonDisatchers.put(R.id.hide_bar_btn, new ButtonDispatcher(R.id.hide_bar_btn));
     }

     public BarTransitions getBarTransitions() {
@@ -283,6 +283,9 @@ public class NavigationBarView extends LinearLayout {
     public ButtonDispatcher getImeSwitchButton() {
         return mButtonDisatchers.get(R.id.ime_switcher);
     }
+    public ButtonDispatcher get_hide_bar_btn() {
+        return mButtonDisatchers.get(R.id.hide_bar_btn);
+    }

     private void updateCarModeIcons(Context ctx) {
         mBackCarModeIcon = ctx.getDrawable(R.drawable.ic_sysbar_back_carmode);


a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -50,6 +50,7 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi
     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 HIDE_BAR_BTN = "hide_bar_btn";

     public static final String GRAVITY_SEPARATOR = ";";
     public static final String BUTTON_SEPARATOR = ",";
@@ -297,8 +298,13 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi
             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(HIDE_BAR_BTN.equals(button)){
+            v = inflater.inflate(R.layout.hide_bar_btn, parent, false);
+            if (landscape && isSw600Dp()) {
+                setupLandButton(v);
+            }
         } else if (button.startsWith(KEY)) {
-            String uri = extractImage(button);
+            String uri = extractImage(button);
             int code = extractKeycode(button);
             v = inflater.inflate(R.layout.custom_key, parent, false);
             ((KeyButtonView) v).setCode(code);
@@ -340,7 +346,6 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi
         String subStr = buttonSpec.substring(start + 1, buttonSpec.indexOf(KEY_CODE_END));
         return subStr;
     }
-
     public static int extractKeycode(String buttonSpec) {
         if (!buttonSpec.contains(KEY_CODE_START)) {
             return 1;

这里是加载我们引入的虚拟按键资源。

--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
     private void inflateSignalClusters() {
         SignalClusterView signalClusterView = reinflateSignalCluster(mStatusBarView);
@@ -1427,6 +1449,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
         }
     };

+    private View.OnClickListener mHideBarClickListener = new View.OnClickListener() {
+        public void onClick(View view) {
+           Log.i(TAG, "mHideBarClickListener  onClick...");
+           removeNavigationBar();
+        }
+    };
+
     private View.OnTouchListener mScreenshotTouchListener = new View.OnTouchListener() {

         @Override
@@ -1525,6 +1554,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
         }
     }

+    private void removeNavigationBar() {
+        if (DEBUG) Log.d(TAG, "removeNavigationBar: about to remove " + mNavigationBarView);
+        if (mNavigationBarView == null) return;
+
+        mWindowManager.removeView(mNavigationBarView);
+        mNavigationBarView = null;
+    }
+
     private void prepareNavigationBarView() {
         mNavigationBarView.reorient();

@@ -1541,7 +1578,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
         ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
         homeButton.setOnTouchListener(mHomeActionListener);
         homeButton.setOnLongClickListener(mLongPressHomeListener);
-
+
+        ButtonDispatcher btn = mNavigationBarView.get_hide_bar_btn();
+        btn.setOnClickListener(mHideBarClickListener);
+        btn.setVisibility(View.VISIBLE);
+
         ButtonDispatcher screenshotButton=mNavigationBarView.getScreenshotButton();
         screenshotButton.setOnClickListener(mScreenshotClickListener);
         screenshotButton.setOnTouchListener(mScreenshotTouchListener);

--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -39,6 +39,10 @@ public class TvStatusBar extends BaseStatusBar {
     public void setIcon(String slot, StatusBarIcon icon) {
     }

+   @Override // CommandQueue
+    public void showNavigationBar() {
+
+    }
     @Override
     public void removeIcon(String slot) {
     }

添加点击事件隐藏状态栏

参考资料:https://blog.csdn.net/ly0724ok/article/details/117324053
参考资料:https://blog.csdn.net/way_ping_li/article/details/45727335

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值