目前公司在做新項目開發,項目目前是不讓有Back,Home,Menu實體按鍵,這就導致了一個問題,點開其它應用無法返回到桌面,
當然些問題對於做開發的我們肯定是難不到的,如果我們開發碰到這問題肯定是adb鏈接 終端輸入對應的key值 命令就搞定了
例如
$adb shell input keyevent 4
或者我們使用投屏神器 scrcpy 也能搞定.
問題是產品要面向客戶展示,總不能抱個電腦鏈接產品機器讓客戶看吧...這樣也太丟人了,使用的是Android 7.1 原生系統,又不支持邊緣滑動,問題總是要解決的,經過前期的調研發現了兩種方式可以完成.
第一種是系統層面增加
好處:系統自己維護,定製化強
缺點:需要有自己的ROM包
第二種是寫一個手勢APP
好處:不需要修改系統.
缺點:受系統限制比較大
第一種方式
經過查詢代碼發現其實Google 在7.1 上面已經寫好對應的藉口,只是空着沒實現.
那具體的實現方式就是 我在系統中屬性裏面增加屬性值來決定每個滑動事件對應的動作,這樣以來只需要改動配置文件就行,不需要每次修改framework代碼.
我開發的版本的系統屬性路徑如下,添加系統屬性,默認是配置是空(關閉狀態)想要使用該功能的時候直接打開即可.
device/qcom/msmXXX/system.prop
#Edge Gesture Function
persist.gesturekey.bottom= #HOME
persist.gesturekey.right= #MENU
persist.gesturekey.left= #BACK
然後在 PhoneWindowManager.java中添加滑動事件
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
// monitor for system gestures
mSystemGestures = new SystemGesturesPointerEventListener(context,
new SystemGesturesPointerEventListener.Callbacks() {
@Override
public void onSwipeFromTop() {
if (mStatusBar != null) {
// 下拉框 系統已經實現的 如 systemUI 通知欄等
requestTransientBars(mStatusBar);
}
}
@Override
public void onSwipeFromBottom() {
// 添加底部往上滑動事件
doPersitKey(SystemProperties.get("persist.gesturekey.bottom"));
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onSwipeFromRight() {
// 添加右滑動
doPersitKey(SystemProperties.get("persist.gesturekey.right"));
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onSwipeFromLeft() {
// 添加左滑動
doPersitKey(SystemProperties.get("persist.gesturekey.left"));
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
requestTransientBars(mNavigationBar);
}
}
...........省略代碼.........
});
可以看到我沒有在具體的事件中進行處理,這樣是爲了後期方便,我處理時間的時候去讀取配置文件對應的值,通過對應的值來決定做左滑動,上滑動以及右滑動的值
具體的處理滑動事件邏輯邏輯
private void doPersitKey(String persistkey) {
if ("BACK".equals(persistkey)) {
long now = SystemClock.uptimeMillis();
KeyEvent down = new KeyEvent(
now, now, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0);
InputManager.getInstance().injectInputEvent(
down, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
KeyEvent up = new KeyEvent(
now, now, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK, 0);
InputManager.getInstance().injectInputEvent(
up, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
} else if ("HOME".equals(persistkey)) {
launchHomeFromHotKey();
} else if ("MENU".equals(persistkey)) {
toggleRecentApps();
}
}
第二種APP方式無障礙功能
代碼已經寫好,直接用AndroidStudio打開運行即可
運行之後需要打開無障礙模式模式才能進行使用
如果不想每次使用都開啓無障礙服務就需要系統簽名 系統簽名詳解
1.AndroidManifest.xml 增加
添加 sharedUserId
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="com.xxx.gesture"
package="com.xxx.gesture">
添加開機啓動權限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
添加開機啓動廣播
<action android:name="android.intent.action.BOOT_COMPLETED" />
2.在靜態開機廣播中增加如下代碼,這樣的話開機就會啓動此服務,越過用戶手動開啓,就可以使用邊緣手勢滑動功能
public class SystemReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Settings.Secure.putString(context.getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "com.xxx.gesture/com.xxx.gesture.AccessibilityServiceGesture");
Settings.Secure.putString(context.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, "1");
}
}
}