一、检测三个手指下滑消息,SystemGesturesPointerEventListener里面处理手势下滑消息frameworks\base\services\core\java\com\android\server\wm\SystemGesturesPointerEventListener.java

 二、接收三手指滑动信息,然后发送截屏广播frameworks\base\services\core\java\com\android\server\wm\DisplayPolicy.java

SystemGesturesPointerEventListener

三、检测到三个手指的时候,拦截手指下滑消息,不然截屏的同时会把界面下滑,如果是在菜单界面,会把内容下滑。我们需要截屏的时候保持原先的界面。

四、测试log,三指滑下,截屏。 

五、测试效果,三指滑下成功截屏。

六、整个过程重需要修改的内容

diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
old mode 100644
new mode 100755
index ca424e7..eb41453
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14564,6 +14564,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,*/@UnsupportedAppUsagepublic final boolean dispatchPointerEvent(MotionEvent event) {
+         Log.e(VIEW_LOG_TAG, "dispatchPointerEvent   $$$$$$$$$$$$$$$$$$$$$");if (event.isTouchEvent()) {return dispatchTouchEvent(event);} else {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
old mode 100644
new mode 100755
index 77fedd7..2eb3eb2
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -201,6 +201,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager// Lazily created int[2] for dispatch to childrenprivate int[] mTempLocation;+// Layout animationprivate LayoutAnimationController mLayoutAnimationController;private Animation.AnimationListener mAnimationListener;
@@ -239,6 +240,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager// True if the view group is capable of showing a tooltip and the pointer is directly// over the view group but not one of its child views.private boolean mTooltipHoveredSelf;
+  private boolean checkout_three_finger = false;/*** Internal flags.
@@ -3286,6 +3288,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager&& isOnScrollbarThumb(ev.getX(), ev.getY())) {return true;}
+      if(ev.getAction() == MotionEvent.ACTION_DOWN)
+           checkout_three_finger = false;
+
+      //if((ev.getPointerCount() >= 3 )&&(ev.getAction() == MotionEvent.ACTION_MOVE)){
+      if(ev.getPointerCount() >= 3 ){
+           checkout_three_finger = true;
+           return true;
+      }
+      else if(checkout_three_finger && ev.getAction() == MotionEvent.ACTION_UP){
+           return true;
+      }
+      return false;}diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
old mode 100644
new mode 100755
index 18e9ef0..573b67d
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -612,7 +612,7 @@ public final class ViewRootImpl implements ViewParent,private long mFpsStartTime = -1;private long mFpsPrevTime = -1;private int mFpsNumFrames;
-
+    public  boolean checkout_three_finger_up = false;private int mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED;private PointerIcon mCustomPointerIcon = null;@@ -6019,7 +6019,32 @@ public final class ViewRootImpl implements ViewParent,mAttachInfo.mUnbufferedDispatchRequested = false;mAttachInfo.mHandlingPointerEvent = true;
-            boolean handled = mView.dispatchPointerEvent(event);
+          Slog.d("View", "processPointerEvent dispatchPointerEvent  ***************");
+
+          boolean handled ;
+/*
+          if(event.isTouchEvent())
+          {
+                  if((event.getPointerCount() == 3 )&&(event.getAction() == MotionEvent.ACTION_MOVE))
+                    {
+                       checkout_three_finger_up = true;
+                       handled = false ;
+                    }
+                  else {
+                      if(checkout_three_finger_up && event.getAction() == MotionEvent.ACTION_UP)
+                           handled = false ;
+                      else
+                           handled = mView.dispatchPointerEvent(event);
+                  }
+
+                 if(event.getAction() == MotionEvent.ACTION_DOWN)
+                      checkout_three_finger_up = false;
+
+          }else
+*/
+              handled = mView.dispatchPointerEvent(event);
+
+            //boolean handled = mView.dispatchPointerEvent(event);maybeUpdatePointerIcon(event);maybeUpdateTooltip(event);mAttachInfo.mHandlingPointerEvent = false;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
old mode 100644
new mode 100755
index 29881cc..02cbb94
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -260,6 +260,7 @@ public class DisplayPolicy {private final DisplayContent mDisplayContent;private final Object mLock;private final Handler mHandler;
+  public final Handler mScreenshotHandler;private Resources mCurrentUserResources;@@ -520,10 +521,26 @@ public class DisplayPolicy {final Looper looper = UiThread.getHandler().getLooper();mHandler = new PolicyHandler(looper);
+        mScreenshotHandler = new Handler() {
+          public void handleMessage(Message msg) {
+              Slog.i(TAG, "mScreenshotHandler handleMessage msg.what:" + msg.what);
+              switch(msg.what){
+              case 1:
+                      Intent mscreenshot = new Intent("android.intent.action.SCREENSHOT");
+                        mContext.sendBroadcast(mscreenshot);
+                  break;
+
+              default:
+                  break;
+              }
+         }
+      };
+mSystemGestures = new SystemGesturesPointerEventListener(mContext, mHandler,new SystemGesturesPointerEventListener.Callbacks() {@Overridepublic void onSwipeFromTop() {
+                    Slog.i(TAG, "onSwipeFromTop: 0000000000000");synchronized (mLock) {if (mStatusBar != null) {requestTransientBars(mStatusBar);
@@ -534,6 +551,7 @@ public class DisplayPolicy {@Overridepublic void onSwipeFromBottom() {
+                        Slog.i(TAG, "onSwipeFromBottom: 0000000000000");synchronized (mLock) {if (mNavigationBar != null&& mNavigationBarPosition == NAV_BAR_BOTTOM) {
@@ -579,6 +597,7 @@ public class DisplayPolicy {@Overridepublic void onFling(int duration) {
+                      Slog.i(TAG, "onFling: 0000000000000");if (mService.mPowerManagerInternal != null) {mService.mPowerManagerInternal.powerHint(PowerHint.INTERACTION, duration);
@@ -597,15 +616,22 @@ public class DisplayPolicy {@Overridepublic void onDown() {
+                        Slog.i(TAG, "onDown: 0000000000000");final WindowOrientationListener listener = getOrientationListener();if (listener != null) {listener.onTouchStart();}}
+                  @Override
+                    public void onSwipeThreeFingerDown() {
+                        Slog.i(TAG, "onSwipeThreeFingerDown: 0000000000000");
+                      mScreenshotHandler.sendEmptyMessageDelayed(1,100);
+                    }@Overridepublic void onUpOrCancel() {final WindowOrientationListener listener = getOrientationListener();
+                      Slog.i(TAG, "onUpOrCancel: 0000000000000");if (listener != null) {listener.onTouchEnd();}
diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
old mode 100644
new mode 100755
index f3859b4..4d71ac6
--- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
@@ -38,7 +38,7 @@ import android.widget.OverScroller;*/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 systemprivate static final int UNTRACKED_POINTER = -1;
@@ -49,6 +49,7 @@ 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 final int SWIPE_DOWN = 5;private final Context mContext;private final Handler mHandler;
@@ -142,6 +143,8 @@ class SystemGesturesPointerEventListener implements PointerEventListener {mDebugFireable = true;mDownPointers = 0;captureDown(event, 0);
+
+              Slog.d(TAG, " MotionEvent.ACTION_DOWN:");if (mMouseHoveringAtEdge) {mMouseHoveringAtEdge = false;mCallbacks.onMouseLeaveFromEdge();
@@ -150,6 +153,7 @@ class SystemGesturesPointerEventListener implements PointerEventListener {break;case MotionEvent.ACTION_POINTER_DOWN:captureDown(event, event.getActionIndex());
+              Slog.d(TAG, "MotionEvent.ACTION_POINTER_DOWN event.getPointerCount()="+event.getPointerCount());if (mDebugFireable) {mDebugFireable = event.getPointerCount() < 5;if (!mDebugFireable) {
@@ -159,6 +163,7 @@ class SystemGesturesPointerEventListener implements PointerEventListener {}break;case MotionEvent.ACTION_MOVE:
+              Slog.d(TAG, " MotionEvent.ACTION_MOVE:");if (mSwipeFireable) {final int swipe = detectSwipe(event);mSwipeFireable = swipe == SWIPE_NONE;
@@ -174,10 +179,16 @@ class SystemGesturesPointerEventListener implements PointerEventListener {} else if (swipe == SWIPE_FROM_LEFT) {if (DEBUG) Slog.d(TAG, "Firing onSwipeFromLeft");mCallbacks.onSwipeFromLeft();
+                    } else if (swipe == SWIPE_DOWN) {
+                        if (DEBUG) Slog.d(TAG, "Firing onSwipeDown event.getPointerCount()"+event.getPointerCount());
+                      if(event.getPointerCount() >= 3 )
+                        mCallbacks.onSwipeThreeFingerDown();  }
+                  }break;case MotionEvent.ACTION_HOVER_MOVE:
+              Slog.d(TAG, " MotionEvent.ACTION_HOVER_MOVE:");if (event.isFromSource(InputDevice.SOURCE_MOUSE)) {if (!mMouseHoveringAtEdge && event.getY() == 0) {mCallbacks.onMouseHoverAtTop();
@@ -196,6 +207,7 @@ class SystemGesturesPointerEventListener implements PointerEventListener {case MotionEvent.ACTION_CANCEL:mSwipeFireable = false;mDebugFireable = false;
+              Slog.d(TAG, " MotionEvent.ACTION_UP ACTION_CANCEL event.getPointerCount()="+event.getPointerCount());mCallbacks.onUpOrCancel();break;default:
@@ -269,6 +281,9 @@ class SystemGesturesPointerEventListener implements PointerEventListener {&& y > fromY + mSwipeDistanceThreshold&& elapsed < SWIPE_TIMEOUT_MS) {return SWIPE_FROM_TOP;
+        }else if (y > fromY + mSwipeDistanceThreshold
+                && elapsed < SWIPE_TIMEOUT_MS) {
+            return SWIPE_DOWN;    }if (fromY >= screenHeight - mSwipeStartThreshold&& y < fromY - mSwipeDistanceThreshold
@@ -336,5 +351,6 @@ class SystemGesturesPointerEventListener implements PointerEventListener {void onMouseHoverAtBottom();void onMouseLeaveFromEdge();void onDebug();
+        void onSwipeThreeFingerDown();}}

七、有价值的参考文章

Android 触摸事件的分发_梁景杰Android的博客-CSDN博客_android触摸分发

Android三指截屏实现,一个简单的三指截屏功能实现_阿機米德的博客-CSDN博客

Android屏幕截图实现方式 系统截屏源码分析和三指截屏_Ansen360的博客-CSDN博客_android 截屏源码

2023-08-23 AndroidR 自主研究出来的三手指下滑截屏功能相关推荐

  1. English Learning - L2-2 英音地道语音语调 [iː] [ɜː] [æ] 2023.02.23 周四

    English Learning - L2-2 英音地道语音语调 [iː] [ɜː] [æ] 2023.02.23 周四 查音标的工具 怎么练习效果好 准备工作 大小声练习 大元音 开口度的对比 舌位 ...

  2. Berkeley共享自主研究:人-机组合应用model-free RL,优化无人机实时辅助控制

    内容来源:ATYUN AI平台 图为Lunar Lander游戏 左:不清楚摄像头指向位置的自主智能体飞行员: 中:未达到最佳标准的人类飞行员: 右:人-机组合 想象这样一个场景,无人机驾驶员远程操控 ...

  3. English Learning - L2-10 英音地道语音语调 鼻辅音 [m] [n] [ŋ] 舌边音 [l] [r] 2023.03.23 周四

    English Learning - L2-10 英音地道语音语调 鼻辅音 [m] [n] [ŋ] 舌边音 [l] [r] 2023.03.23 周四 课前准备活动和回顾 鼻辅音 鼻辅音 [m] 鼻辅 ...

  4. [AI助力] 2023.2.23 考研英语学习 2010 英语二翻译

    [AI助力] 2023.2.23 考研英语学习 2010 英语二翻译 文章目录 [AI助力] 2023.2.23 考研英语学习 2010 英语二翻译 2010年英语二翻译真题 自己写的 积累

  5. 1.atd和crond两个任务管理程序的区别​ 2.指定在2023/08/26 09:00将时间写入testmail.txt文件中​3.指定在每天凌晨4:00将该时间点之前的系统日志信息备份到个目录

    一.atd与crond的区别 1.运行方式不同,at只运行一次,而crontab则是循环运行: 2.依赖的服务不同,at对应的服务时atd,而crontab对应的服务时crond: 3.at一般是临时 ...

  6. English Learning - L2 语音作业打卡 辅音翘舌音 [ʃ] [ʒ] 空气摩擦音 [h] Day31 2023.3.23 周四

    English Learning - L2 语音作业打卡 辅音翘舌音 [ʃ] [ʒ] 空气摩擦音 [h] Day31 2023.3.23 周四

  7. FastReport.Net FastReport.Core 2023.2.23 Crack

    FastReport.Net & FastReport.Core 2023.2.23适用于 .NET 7..NET Core.Blazor.ASP.NET.MVC 和 Windows 窗体的全 ...

  8. 【新书推荐】【2018.08】电子防御系统概论(第三版)

    [2018.08]电子防御系统概论(第三版)Introduction to Electronic Defense Systems, Third Edition,共761页. 如果需要电子版,请联系QQ ...

  9. AI 绘画Stable Diffusion 研究(五)sd文生图功能详解(下)

    大家好,我是风雨无阻. 上一篇文章详细介绍了sd文生图的功能及使用注意事项,感兴趣的朋友可以前往查看:AI 绘画Stable Diffusion 研究(四)sd文生图功能详解(上) . 那今天这篇文章 ...

最新文章

  1. MAC OS下使用OpenSSL生成私钥和公钥的方法
  2. java数据结构库函数_Java8 内置函数(api)总结
  3. 发布地图服务属性表_Web3D地图来了!腾讯位置服务正式版发布!
  4. code iban 是有什么组成_「面试」new String(abc)和abc有什么区别?反编译看看原理吧...
  5. 翻译 github上How to be a good programmer
  6. 把MySQL中的各种锁及其原理都画出来
  7. 合集| 21 篇技术文章,带你从零入门 K8s
  8. addcslashes php,php addcslashes函数怎么用
  9. 界面上下固定_【技术浅析】三通道机床自动上下料控制方法应用
  10. 30 FI配置-财务会计-外币评估-准备外币评估的自动过账
  11. mysql function select 赋值_数据分析面试之mysql的分组排序和变量赋值顺序
  12. 小程序接入h5页面_原生小程序接入H5页面,请求后台接口,获取数据
  13. 查看使用yum安装的软件路径
  14. 十年前的5.19行情
  15. 微信小程序中-[渲染层网络层错误] pages/card/card.wxss 中的本地资源图片无法通过 WXSS 获取-解决办法
  16. 你还在找音乐网站吗?试试这几个吧
  17. Cache数据库入门
  18. jenkins插件下载镜像加速
  19. 通过CAN总线控制VESC驱动直流无刷电机
  20. 计算机与计算机网络_让计算机承担责任

热门文章

  1. c4d场景模型制作笔记(扩音器喇叭,座椅);
  2. 基于PHP的校园二手交易系统(前后台)
  3. 处理podman的overlay-containers中ctr.log日志文件过大的问题
  4. 【一周读书】你的理想
  5. (成信大篇)双系统中使用锐捷客户端的问题
  6. 10部能让ni爱上数学的经典电影
  7. 史上最污技术解读...啊哈~“好变态”~~~
  8. 日本最大社交网站Mixi宣布进军中国网络市场
  9. 使用 HandlerThread
  10. Proteus介绍以及下载、安装遇到的问题