RK:系统手势监听
一.
1.1.需求:从屏幕的左上角为起点,双指触控滑动至屏幕正中央,启动Launcher
1.2.GestureDetector
package com.gatsby.mygesturelistener;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
public class MainActivity extends Activity {
private MyGestureListener mgListener;
private GestureDetector mDetector;
private final static String TAG = "gatsby";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mgListener = new MyGestureListener();
mDetector = new GestureDetector(this, mgListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}
// 实现GestureListener接口
private class MyGestureListener implements GestureDetector.OnGestureListener {
@Override
public boolean onDown(MotionEvent motionEvent) {
Log.d(TAG, "onDown");
return false;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
// Log.d(TAG, "onShowPress:手指按下一段时间,不过还没到长按");
Log.d(TAG, "onShowPress");
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
// Log.d(TAG, "onSingleTapUp:手指离开屏幕的一瞬间");
Log.d(TAG, "onSingleTapUp");
return false;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
// Log.d(TAG, "onScroll:在触摸屏上滑动");
Log.d(TAG, "onScroll");
return false;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
// Log.d(TAG, "onLongPress:长按并且没有松开");
Log.d(TAG, "onLongPress");
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
// Log.d(TAG, "onFling:迅速滑动,并松开");
Log.d(TAG, "onFling");
Log.d(TAG, "motionEvent->" + motionEvent.getX() + " motionEvent1->" + motionEvent1.getX());
// 从左往右 滑动<50
if (motionEvent.getX() - motionEvent1.getX() < 50) {
}
return false;
}
}
}
2.1.MotionEvent、GestureDetector、OnGestureListener
首先,在Android系统中,每一次手势交互都会依照以下顺序执行。
a. 接触接触屏一刹那,触发一个MotionEvent事件。
b. 该事件被OnTouchListener监听,在其onTouch()方法里获得该MotionEvent对象。、
c. 通过GestureDetector(手势识别器)转发次MotionEvent对象至OnGestureListener。·
d. OnGestureListener获得该对象,听根据该对象封装的的信息,做出合适的反馈
MotionEvent: 这个类用于封装手势、触摸笔、轨迹球等等的动作事件。其内部封装了两个重要的属性X和Y,这两个属性分别用于记录横轴和纵轴的坐标。
GestureDetector: 识别各种手势。
OnGestureListener: 这是一个手势交互的监听接口,其中提供了多个抽象方法,并根据GestureDetector的手势识别结果调用相对应的方法。
.系统监听触摸事件
主要就是在SystemGesturesPointerEventListener中加了一个回调方法onMorePointerSwipe,当getPointerCount==2的时候调用,然后在PhoneWindowManager中实现onMorePointerSwipe.
底部、右边滑动,接鼠标时从顶部、底部按住滑动,我们在 Callbacks 中增加一个 void onMorePointerSwipe();
用来回调三指同时滑动的情况,通过 event.getPointerCount() 获取当前屏幕手指按下个数,也可打开调试模式里的指针和触点显示
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) {
requestTransientBars(mStatusBar);
}
if(SystemProperties.get("persist.sys.gesshownavibar","0").equals("1"))
{
if(SystemProperties.get("persist.sys.hidenavibar","0").equals("1"))
{
addBar();
}
}
}
@Override
public void onSwipeFromBottom() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
requestTransientBars(mNavigationBar);
}
if(SystemProperties.get("persist.sys.gesshownavibar","0").equals("1"))
{
if(SystemProperties.get("persist.sys.hidenavibar","0").equals("1"))
{
addBar();
}
}
}
@Override
public void onSwipeFromRight() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onSwipeFromLeft() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onFling(int duration) {
if (mPowerManagerInternal != null) {
mPowerManagerInternal.powerHint(
PowerManagerInternal.POWER_HINT_INTERACTION, duration);
}
}
二.Android7.1 左上两下 ,右一下 进allapp
2.1.自定义手势
--- a/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
+++ b/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
@@ -59,6 +59,7 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
int screenHeight;
int screenWidth;
+ private int count_point;
private int mDownPointers;
private boolean mSwipeFireable;
private boolean mDebugFireable;
@@ -72,7 +73,7 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
mSwipeDistanceThreshold = mSwipeStartThreshold;
if (DEBUG) Slog.d(TAG, "mSwipeStartThreshold=" + mSwipeStartThreshold
- + " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold);
+ + " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold);
}
private static <T> T checkNull(String name, T arg) {
@@ -86,6 +87,8 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
Handler h = new Handler(Looper.myLooper());
mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), h);
mOverscroller = new OverScroller(mContext);
+
+ Slog.d(TAG,"222 screenHeight = "+screenHeight+" screenWidth = "+screenWidth);
}
@Override
@@ -102,8 +105,26 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
if (mMouseHoveringAtEdge) {
mMouseHoveringAtEdge = false;
mCallbacks.onMouseLeaveFromEdge();
- }
+ }
mCallbacks.onDown();
+ float xhgetX = event.getRawX();
+ float xhgetY = event.getRawY();
+ Slog.d(TAG,"333 xhgetX = "+xhgetX+" xhgetY = "+xhgetY);
+ if (xhgetX <= 100.00 && xhgetY <= 100.00 ){
+ if(count_point<2)
+ count_point ++;
+ }else if( (xhgetX <= (screenWidth/2 + 50) && xhgetX >= (screenWidth/2 - 50) && xhgetY <= (screenHeight/2 + 50) && xhgetY >= (screenHeight/2 - 50))
+ || (xhgetX >= (screenWidth -100 ) && xhgetY >= (screenHeight - 100)) ){
+ if(count_point==2)
+ count_point ++;
+ }else{
+ count_point = 0;
+ }
+ if(count_point == 3){
+ count_point=0;
+ mCallbacks.onBootAllApps();
+ }
+ Slog.d(TAG,"333 count_point = "+count_point);
break;
case MotionEvent.ACTION_POINTER_DOWN:
captureDown(event, event.getActionIndex());
@@ -282,5 +303,6 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
void onMouseHoverAtBottom();
void onMouseLeaveFromEdge();
void onDebug();
+ void onBootAllApps();
}
}
2.2.注册系统全局广播
使用自定义的广播,然后用命令行测试的时候出现如下warning:
原因:系统对自定义广播做了保护限制 对广播做了保护限定之后只有一定权限的用户才可以使用 否则用一次就会打印一次warning 并且保存异常信息到文件中 所以要在清单文件中注册广播
--- a/frameworks/base/core/res/AndroidManifest.xml
+++ b/frameworks/base/core/res/AndroidManifest.xml
@@ -509,6 +509,8 @@
<protected-broadcast android:name="android.intent.action.HDMI_PLUG" />
<protected-broadcast android:name="android.intent.action.USB_CAMERA" />
+ <protected-broadcast android:name="com.xinhua.bootAllApps" />
+
<!--for cec-->
<protected-broadcast android:name="com.rockchip.hdmicec.power_status_changed" />
2.3.这里回调
--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1963,6 +1963,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void onMouseLeaveFromEdge() {
mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
}
+
+ @Override
+ public void onBootAllApps() {
+ //
+ Slog.d("SystemGestures","onBootAllApps");
+ Intent i = new Intent("com.xinhua.bootAllApps");
+ mContext.sendBroadcastAsUser(i,UserHandle.CURRENT);
+ }
});
mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext);
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
2.4.接收广播
--- a/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
+++ b/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
@@ -223,6 +223,23 @@ public class Launcher extends Activity
}
};
+ private final BroadcastReceiver allAppReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if ("com.xinhua.bootAllApps".equals(intent.getAction())) {
+ if (!isAppsViewVisible()) {
+ getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.TAP,
+ LauncherLogProto.ALL_APPS_BUTTON);
+ showAppsView(true /* animated */, true /* updatePredictedApps */,
+ false /* focusSearchBar */);
+ }
+ }
+ }
+ };
+
@Thunk Workspace mWorkspace;
private View mLauncherView;
@Thunk DragLayer mDragLayer;
@@ -456,6 +473,10 @@ public class Launcher extends Activity
IntentFilter filter = new IntentFilter(ACTION_APPWIDGET_HOST_RESET);
registerReceiver(mUiBroadcastReceiver, filter);
+
+ IntentFilter allAppfilter = new IntentFilter();
+ allAppfilter.addAction("com.xinhua.bootAllApps");
+ registerReceiver(allAppReceiver, allAppfilter);
mRotationEnabled = getResources().getBoolean(R.bool.allow_rotation);
// In case we are on a device with locked rotation, we should look at preferences to check
三. 系统手势 发出back键值
diff --git a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ecfe39b..0a639a2 100755
--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1927,6 +1927,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
@Override
+ public void onMorePointerSwipe() {
+ try{
+ Runtime. getRuntime().exec("input keyevent 4");
+ }catch(IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
public void onFling(int duration) {
if (mPowerManagerInternal != null) {
mPowerManagerInternal.powerHint(
diff --git a/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java b/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
index 598c58e..9d131ff 100755
--- a/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
+++ b/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
@@ -44,7 +44,9 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
private static final int SWIPE_FROM_BOTTOM = 2;
private static final int SWIPE_FROM_RIGHT = 3;
private static final int SWIPE_FROM_LEFT = 4;
-
+ private static boolean XhDown = false;
+ private static boolean Success = false;
+
private final Context mContext;
private final int mSwipeStartThreshold;
private final int mSwipeDistanceThreshold;
@@ -103,7 +105,14 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
mMouseHoveringAtEdge = false;
mCallbacks.onMouseLeaveFromEdge();
}
+ mCallbacks.onDown();
mCallbacks.onDown();
+ Success = true;
+ float xhgetX = event.getRawX();
+ float xhgetY = event.getRawY();
+ if (xhgetX < 300.00 && xhgetY < 300.00 ){
+ XhDown = true;
+ }
break;
case MotionEvent.ACTION_POINTER_DOWN:
captureDown(event, event.getActionIndex());
@@ -131,8 +140,14 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
} else if (swipe == SWIPE_FROM_LEFT) {
if (DEBUG) Slog.d(TAG, "Firing onSwipeFromLeft");
mCallbacks.onSwipeFromLeft();
- }
- }
+ }
+ }
+ float XhgetX = event.getRawX();
+ float XhgetY = event.getRawY();
+ if (Success && XhDown && XhgetX > 560.00 && XhgetX < 1360.00 && XhgetY > 400.00 && XhgetY < 740.00){
+ Success = false;
+ mCallbacks.onMorePointerSwipe();
+ }
break;
case MotionEvent.ACTION_HOVER_MOVE:
if (event.isFromSource(InputDevice.SOURCE_MOUSE)) {
@@ -150,6 +165,8 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
}
break;
case MotionEvent.ACTION_UP:
+ Success = true;
+ XhDown = false;
case MotionEvent.ACTION_CANCEL:
mSwipeFireable = false;
mDebugFireable = false;
@@ -282,5 +299,6 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
void onMouseHoverAtBottom();
void onMouseLeaveFromEdge();
void onDebug();
+ void onMorePointerSwipe();
}
}

浙公网安备 33010602011771号