一.
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() 获取当前屏幕手指按下个数,也可打开调试模式里的指针和触点显示
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 ce46afc0..105d27c 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 @@ -1926,6 +1926,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } @Override + public void onMorePointerSwipe() { + if (mNavigationBar != null) { + Log.d("gatsby","1111111111111111 onMorePointerSwipe"); + + } + } + + @Override public void onFling(int duration) { if (mPowerManagerInternal != null) { mPowerManagerInternal.powerHint( @@ -2002,6 +2010,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { mWindowManagerInternal.registerAppTransitionListener( mStatusBarController.getAppTransitionListener()); } + + + /** * Read values from config.xml that may be overridden depending on 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 old mode 100644 new mode 100755 index 598c58e..da3b8d9 --- a/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java +++ b/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java @@ -33,7 +33,7 @@ import android.widget.OverScroller; */ public class SystemGesturesPointerEventListener implements PointerEventListener { private static final String TAG = "SystemGestures"; - private static final boolean DEBUG = false; + private static final boolean DEBUG = true; private static final long SWIPE_TIMEOUT_MS = 500; private static final int MAX_TRACKED_POINTERS = 32; // max per input system private static final int UNTRACKED_POINTER = -1; @@ -44,6 +44,7 @@ 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 final Context mContext; private final int mSwipeStartThreshold; @@ -64,6 +65,7 @@ public class SystemGesturesPointerEventListener implements PointerEventListener private boolean mDebugFireable; private boolean mMouseHoveringAtEdge; private long mLastFlingTime; + public SystemGesturesPointerEventListener(Context context, Callbacks callbacks) { mContext = context; @@ -104,6 +106,14 @@ public class SystemGesturesPointerEventListener implements PointerEventListener mCallbacks.onMouseLeaveFromEdge(); } mCallbacks.onDown(); + //Log.d("gatsby", "XXXgetRawX->" + event.getRawX() + "YYYgetRawY->" + event.getRawY()); + //if (DEBUG) Slog.d("gatsby", "XXXgetRawX->" + event.getRawX() + "YYYgetRawY->" + event.getRawY()); + float xhgetX = event.getRawX(); + if (xhgetX < 200.01){ + if (DEBUG) Slog.d("gatsby", "ZZZZZZZZZZZZZZZZZZZZZZ " ); + XhDown = true; + } + break; case MotionEvent.ACTION_POINTER_DOWN: captureDown(event, event.getActionIndex()); @@ -131,7 +141,15 @@ public class SystemGesturesPointerEventListener implements PointerEventListener } else if (swipe == SWIPE_FROM_LEFT) { if (DEBUG) Slog.d(TAG, "Firing onSwipeFromLeft"); mCallbacks.onSwipeFromLeft(); - } + } + if (DEBUG) Slog.d("gatsby", "qqqqqqqqqqqqqqqqqqqqqqq "+XhDown ); + + + if (DEBUG) Slog.d(TAG, "GGGGGXXXgetRawX->" + event.getRawX() + "GGGGYYYgetRawY->" + event.getRawY()); + if (XhDown && event.getPointerCount() == 2){ + if (DEBUG) Slog.d("gatsby", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB "+XhDown ); + mCallbacks.onMorePointerSwipe(); + } } break; case MotionEvent.ACTION_HOVER_MOVE: @@ -150,6 +168,11 @@ public class SystemGesturesPointerEventListener implements PointerEventListener } break; case MotionEvent.ACTION_UP: + + + XhDown = false; + if (DEBUG) Slog.d("gatsby", "ZZZZZZZZZZZZZZZZZZZZZZ "+XhDown ); + case MotionEvent.ACTION_CANCEL: mSwipeFireable = false; mDebugFireable = false; @@ -282,5 +305,6 @@ public class SystemGesturesPointerEventListener implements PointerEventListener void onMouseHoverAtBottom(); void onMouseLeaveFromEdge(); void onDebug(); + void onMorePointerSwipe(); } }
二.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.注册系统全局广播
--- 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