介绍:使用这种方式下拉状态栏也可以截图,思路就是拦截触摸事件,判断是不是三指并且符合一定的距离,最后发送截屏的广播,代码如下,后面的代码没有修改

//alps/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.javapackage com.android.systemui.statusbar.phone;import android.annotation.ColorInt;
import android.annotation.DrawableRes;
import android.annotation.LayoutRes;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.session.MediaSessionLegacyHelper;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ActionMode;
import android.view.InputDevice;
import android.view.InputQueue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.widget.FrameLayout;import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.view.FloatingActionMode;
import com.android.internal.widget.FloatingToolbar;
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;public class StatusBarWindowView extends FrameLayout {public static final String TAG = "StatusBarWindowView";public static final boolean DEBUG = StatusBar.DEBUG;private DragDownHelper mDragDownHelper;private DoubleTapHelper mDoubleTapHelper;private NotificationStackScrollLayout mStackScrollLayout;private NotificationPanelView mNotificationPanel;private View mBrightnessMirror;private int mRightInset = 0;private int mLeftInset = 0;private StatusBar mService;private final Paint mTransparentSrcPaint = new Paint();private FalsingManager mFalsingManager;// Implements the floating action mode for TextView's Cut/Copy/Past menu. Normally provided by// DecorView, but since this is a special window we have to roll our own.private View mFloatingActionModeOriginatingView;private ActionMode mFloatingActionMode;private FloatingToolbar mFloatingToolbar;private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;private boolean mTouchCancelled;private boolean mTouchActive;// add by alright on 2018/9/10 start private Context mConext;private int pointy1 = 0;private int pointy2 = 0;private int pointy3 = 0;private int mpointy1 = 0;private int mpointy2 = 0;private int mpointy3 = 0;private int mCanMoveDistance;private static boolean canget = false;// add by alright on 2018/9/10 end public StatusBarWindowView(Context context, AttributeSet attrs) {super(context, attrs);setMotionEventSplittingEnabled(false);mTransparentSrcPaint.setColor(0);mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));mFalsingManager = FalsingManager.getInstance(context);mDoubleTapHelper = new DoubleTapHelper(this, active -> {}, () -> {mService.wakeUpIfDozing(SystemClock.uptimeMillis(), this);return true;}, null, null);// add by alright on 2018/9/10 start mConext = context;WindowManager mWm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);mCanMoveDistance = (int)(mWm.getDefaultDisplay().getHeight()/5);// add by alright on 2018/9/10 end }@Overrideprotected boolean fitSystemWindows(Rect insets) {if (getFitsSystemWindows()) {boolean paddingChanged = insets.top != getPaddingTop()|| insets.bottom != getPaddingBottom();// Super-special right inset handling, because scrims and backdrop need to ignore it.if (insets.right != mRightInset || insets.left != mLeftInset) {mRightInset = insets.right;mLeftInset = insets.left;applyMargins();}// Drop top inset, and pass through bottom inset.if (paddingChanged) {setPadding(0, 0, 0, 0);}insets.left = 0;insets.top = 0;insets.right = 0;} else {if (mRightInset != 0 || mLeftInset != 0) {mRightInset = 0;mLeftInset = 0;applyMargins();}boolean changed = getPaddingLeft() != 0|| getPaddingRight() != 0|| getPaddingTop() != 0|| getPaddingBottom() != 0;if (changed) {setPadding(0, 0, 0, 0);}insets.top = 0;}return false;}private void applyMargins() {final int N = getChildCount();for (int i = 0; i < N; i++) {View child = getChildAt(i);if (child.getLayoutParams() instanceof LayoutParams) {LayoutParams lp = (LayoutParams) child.getLayoutParams();if (!lp.ignoreRightInset&& (lp.rightMargin != mRightInset || lp.leftMargin != mLeftInset)) {lp.rightMargin = mRightInset;lp.leftMargin = mLeftInset;child.requestLayout();}}}}@Overridepublic FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {return new LayoutParams(getContext(), attrs);}@Overrideprotected FrameLayout.LayoutParams generateDefaultLayoutParams() {return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);}@Overrideprotected void onFinishInflate() {super.onFinishInflate();mStackScrollLayout = (NotificationStackScrollLayout) findViewById(R.id.notification_stack_scroller);mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);mBrightnessMirror = findViewById(R.id.brightness_mirror);}@Overridepublic void onViewAdded(View child) {super.onViewAdded(child);if (child.getId() == R.id.brightness_mirror) {mBrightnessMirror = child;}}public void setService(StatusBar service) {mService = service;setDragDownHelper(new DragDownHelper(getContext(), this, mStackScrollLayout, mService));}@VisibleForTestingvoid setDragDownHelper(DragDownHelper dragDownHelper) {mDragDownHelper = dragDownHelper;}@Overrideprotected void onAttachedToWindow () {super.onAttachedToWindow();// We need to ensure that our window doesn't suffer from overdraw which would normally// occur if our window is translucent. Since we are drawing the whole window anyway with// the scrim, we don't need the window to be cleared in the beginning.if (mService.isScrimSrcModeEnabled()) {IBinder windowToken = getWindowToken();WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();lp.token = windowToken;setLayoutParams(lp);WindowManagerGlobal.getInstance().changeCanvasOpacity(windowToken, true);setWillNotDraw(false);} else {setWillNotDraw(!DEBUG);}}@Overridepublic boolean dispatchKeyEvent(KeyEvent event) {if (mService.interceptMediaKey(event)) {return true;}if (super.dispatchKeyEvent(event)) {return true;}boolean down = event.getAction() == KeyEvent.ACTION_DOWN;switch (event.getKeyCode()) {case KeyEvent.KEYCODE_BACK:if (!down) {mService.onBackPressed();}return true;case KeyEvent.KEYCODE_MENU:if (!down) {return mService.onMenuPressed();}case KeyEvent.KEYCODE_SPACE:if (!down) {return mService.onSpacePressed();}break;case KeyEvent.KEYCODE_VOLUME_DOWN:case KeyEvent.KEYCODE_VOLUME_UP:if (mService.isDozing()) {MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);return true;}break;}return false;}public void setTouchActive(boolean touchActive) {mTouchActive = touchActive;mStackScrollLayout.setTouchActive(touchActive);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;if (!isCancel && mService.shouldIgnoreTouch()) {return false;}if (isDown && mNotificationPanel.isFullyCollapsed()) {mNotificationPanel.startExpandLatencyTracking();}if (isDown) {setTouchActive(true);mTouchCancelled = false;} else if (ev.getActionMasked() == MotionEvent.ACTION_UP|| ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {setTouchActive(false);}if (mTouchCancelled) {return false;}mFalsingManager.onTouchEvent(ev, getWidth(), getHeight());if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {// Disallow new pointers while the brightness mirror is visible. This is so that you// can't touch anything other than the brightness slider while the mirror is showing// and the rest of the panel is transparent.if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {return false;}}if (isDown) {mStackScrollLayout.closeControlsIfOutsideTouch(ev);}if (mService.isDozing()) {mService.mDozeScrimController.extendPulse();}return super.dispatchTouchEvent(ev);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// Add by alright on 2018/10/13 for  start >>>>>>>>>>if ((Settings.System.getInt(mContext.getContentResolver(), "Three_fingers_screenshots", 0) == 1)&& ev.getPointerCount() == 3) {if (canShot(ev)) {Intent intent = new Intent("com.android.screen.shot");mContext.sendBroadcast(intent);return true;} else {return super.onInterceptTouchEvent(ev);}}// Add by alright on 2018/10/13 for 3-finger screenshot end <<<<<<<<<<<<<<<if (mService.isDozing() && !mStackScrollLayout.hasPulsingNotifications()) {// Capture all touch events in always-on.return true;}boolean intercept = false;if (mNotificationPanel.isFullyExpanded()&& mStackScrollLayout.getVisibility() == View.VISIBLE&& mService.getBarState() == StatusBarState.KEYGUARD&& !mService.isBouncerShowing()&& !mService.isDozing()) {intercept = mDragDownHelper.onInterceptTouchEvent(ev);}if (!intercept) {super.onInterceptTouchEvent(ev);}if (intercept) {MotionEvent cancellation = MotionEvent.obtain(ev);cancellation.setAction(MotionEvent.ACTION_CANCEL);mStackScrollLayout.onInterceptTouchEvent(cancellation);mNotificationPanel.onInterceptTouchEvent(cancellation);cancellation.recycle();}return intercept;}// Add by alright on 2018/10/13 for  start >>>>>>>>>>private boolean canShot(MotionEvent ev) {Log.d(TAG, "canShot: " + ev.getAction());if (ev.getAction() == MotionEvent.ACTION_POINTER_3_DOWN) {pointy1 = (int) ev.getAxisValue(MotionEvent.AXIS_Y, 0);pointy2 = (int) ev.getAxisValue(MotionEvent.AXIS_Y, 1);pointy3 = (int) ev.getAxisValue(MotionEvent.AXIS_Y, 2);canget = true;} else if (ev.getAction() == MotionEvent.ACTION_UP|| ev.getAction() == MotionEvent.ACTION_POINTER_2_UP|| ev.getAction() == MotionEvent.ACTION_POINTER_3_UP) {try {mpointy1 = (int) ev.getAxisValue(MotionEvent.AXIS_Y, 0);mpointy2 = (int) ev.getAxisValue(MotionEvent.AXIS_Y, 1);mpointy3 = (int) ev.getAxisValue(MotionEvent.AXIS_Y, 2);} catch (IllegalArgumentException e) {e.printStackTrace();}if (canget && Math.abs(mpointy1 - pointy1) >= mCanMoveDistance&& Math.abs(mpointy2 - pointy2) >= mCanMoveDistance&& Math.abs(mpointy3 - pointy3) >= mCanMoveDistance) {canget = false;return true;}canget = false;}return false;}// add by alright on 2018/9/3 end 

Mr.Alright---基于安卓O(8.0)三指截屏的实现相关推荐

  1. Android 基于4.4系统截屏的三指截屏

    根据上一篇文章Android 4.4系统原生截图解析 ,我们知道系统截屏是调用了TakeScreenshotService,为实现在任何界面都能实现三指截屏,我们就得在PhoneWindow(fram ...

  2. 滚动截屏软件_华为指关节截屏不如三指截屏好用?一步到位,实践出真知

    华为手机的指关节截屏功能想必只要是用过的朋友都知道,熟悉的朋友更会以此为依赖,比如我,现在换了个其他品牌手机用,一到截屏的时候还是会不由自主地拿指关节划区截屏,因为指关节截屏不仅仅是双击截屏,这个划区 ...

  3. Android三指截屏的实现

    三指截屏是用户三个手机点击屏幕向下滑,最终调用systemui的截屏服务实现截屏.所以其他只是做一个策略的实现.目前很多不少手机都实现了该功能,因此自己也尝试着实现该功能.1.首先是注册事件,监听用户 ...

  4. Android三指截屏实现,一个简单的三指截屏功能实现

    最近做了很多客制化的Touch需求,很多情况都可以直接通过GestureDetector来完成,这里挑选三指截屏简述原理.先来说说主要思路,在view的onInterceptTouchEvent方法中 ...

  5. Android N版本 三指截屏

    首先自己恭喜自己找到新的工作,这段时间也把自己的写过的一些功能做个总结. 手势快捷操作现在很多手机厂商都有做,三指截屏只是一个例子,可以通过这个例子去实现某个操作<->某个动作.本文只是写 ...

  6. Android8.1 MTK平台 增加三指截屏(仿IOS左下角显示缩略图点击放大显示)

    效果图 修改后动画如下 系统原动画如下 三指截屏 PhoneWindowManager 同级目录下的 SystemGesturesPointerEventListener.java 主要负责处理界面的 ...

  7. unity打包的apk无法三指截屏

    unity打包的apk无法三指截屏 环境 华为手机 问题 unity打包的游戏在手机上无法用三指截屏 原因 首先华为手机有一个应用助手 游戏空间的概念或者说是应用. 华为手机当判断此应用为游戏时,会将 ...

  8. SystemUI 三指截屏或Power键加音量键连续截屏比较慢

    不积跬步无以至千里 了解SystemUI模块的童鞋都知道截屏是处在SystemUI的代码逻辑中的,因此这里出现了截屏比较慢的问题,就是你连续的三指截屏或者power+音量键,但是不会去快速的截屏. 修 ...

  9. 荣耀android手机怎么截图,华为荣耀8怎么截图/截屏 荣耀8三种截屏方法教程

    昨天晚上,荣耀带来了又一款小屏旗舰新机----荣耀8,主打高颜值外观.该机关于7月19日正式全国上市.相信小伙伴们拿到真机之后,在使用过程当中难免会使用截图分享.那么荣耀8怎么截图呢?下面脚本之家小编 ...

最新文章

  1. 更大的工字型电感作为150kHz导航信号接收天线
  2. 使用R实现一个简单的连续系统模拟
  3. 图像分类、目标检测、语义分割、实例分割和全景分割的区别
  4. openstack-neutron基本的网络类型
  5. matlab上位机串口通信,MATLAB GUIDE 上位机串口通信开发 绘制图形
  6. WSS页面定制系列(1)--如何启用表单页面的编辑模式
  7. 字符串的展开(洛谷-P1098)
  8. Linux Shell脚本入门教程系列之(十六) Shell输入输出重定向
  9. python中返回值为ture表达式_python return逻辑判断表达式(21)|python教程|python入门|python教程...
  10. 为什么是 OnDraw(CDC* /*pDC*/) 而不是 OnDraw(CDC* pDC)
  11. Python快速构建神经网络
  12. System Verilog面向对象编程(OPP)基础——类(class)的基本使用
  13. radiobutton模拟tab点击效果
  14. Android如何实现音频输出路由的切换
  15. HTML动态视频背景全代码
  16. 华为荣耀8C安装Google play store的记录
  17. 均匀分布的期望和方差
  18. 服务器间文件拷贝显示busy,网站解决和优化Server is too busy的一些方法
  19. Markdown字体,字号,颜色和背景色设置
  20. Python图像处理【5】图像扭曲与逆扭曲详解

热门文章

  1. 实验八 :8259中断控制器实验(综合)
  2. 给自己留个发泄的地方
  3. 【编译原理】《编译原理第二版》LR0例题代码
  4. android SwitchPreference ListPreference使用
  5. 《最优化理论与算法》(陈宝林)——第10章:使用导数的最优化方法
  6. 早上被裁下午走人,女朋友也失业在家4个月,投字节简历堆成山
  7. html 偶数项 替换,JS通过奇数项和偶数项实现两种背景颜色的表格实现代码
  8. 2014年百度之星程序设计大赛 - 资格赛 (未完成)
  9. java语句witch,java程序流程控制--witch
  10. 开机黑屏显示html,电脑开机黑屏怎么办,教您电脑开机黑屏的解决方法