三指截屏是用户三个手机点击屏幕向下滑,最终调用systemui的截屏服务实现截屏。所以其他只是做一个策略的实现。目前很多不少手机都实现了该功能,因此自己也尝试着实现该功能。1.首先是注册事件,监听用户是否设置打开了三指截屏功能。
if(Feature.FEATURE_THREE_FINGER_SCREENSHOT){                                                                       resolver.registerContentObserver( Settings.System.getUriFor("pointer_screenshotchord"), false, this,    UserHandle.USER_ALL);}

监听pointer_screenshotchord 这个值得变化
如果发生了改变获取该值得数据并通过Handler发送消息:

f(Feature.FEATURE_THREE_FINGER_SCREENSHOT){if (mSystemReady) {int pointerScreenshotChordMode = Settings.System.getIntForUser(resolver,"pointer_screenshotchord", 0, UserHandle.USER_CURRENT);if (mPointerScreenshotChordMode != pointerScreenshotChordMode) {mPointerScreenshotChordMode = pointerScreenshotChordMode;mHandler.sendEmptyMessage(pointerScreenshotChordMode != 0 ?MSG_ENABLE_POINTER_SCREEN_SHOT_CHORD : MSG_DISABLE_POINTER_SCREEN_SHOT_CHORD);}}}

如果pointerScreenshotChordMode!=0则发送MSG_ENABLE_POINTER_SCREEN_SHOT_CHORD消息开启截屏否则取消截屏功能。
下面看看消息怎么处理的。

case MSG_ENABLE_POINTER_SCREEN_SHOT_CHORD:if (Feature.FEATURE_THREE_FINGER_SCREENSHOT ) {enableFingerScreenshot(); //开启截屏}break;
case MSG_DISABLE_POINTER_SCREEN_SHOT_CHORD:if (Feature.FEATURE_THREE_FINGER_SCREENSHOT) {disableFingerScreenshot();//取消截屏}break;

接着看看enableFingerScreenshot()这个方法

private void enableFingerScreenshot() {// TODO Auto-generated method stubSlog.d(TAG, "enablePointerScreenshotChord");if (mFingerScreenshotView == null) {mFingerScreenshotView = new                   FingerScreenshotView(mContext);Slog.d(TAG, "new PointerScreenshotChordView");mFingerScreenshotPointerEventListener = new FingerScreenshotPointerEventListener();mWindowManagerFuncs.registerPointerEventListener(mFingerScreenshotPointerEventListener);}}

可以看出主要是注册事件监听

再看看disableFingerScreenshot():

private void disableFingerScreenshot() {// TODO Auto-generated method stubif (mFingerScreenshotPointerEventListener != null) {mWindowManagerFuncs.unregisterPointerEventListener(mFingerScreenshotPointerEventListener);mFingerScreenshotPointerEventListener = null;}if (mFingerScreenshotView != null) {/*WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);wm.removeView(mFingerScreenshotView);*/mFingerScreenshotView = null;}}

主要是取消注册事件。
接着就是对事件的监听和响应处理。

private final class FingerScreenshotPointerEventListener implements PointerEventListener {@Overridepublic void onPointerEvent(MotionEvent motionEvent) {if (mFingerScreenshotView != null) {mFingerScreenshotView.onTouchEvent(motionEvent);}}
}

可以看出最后是调用mFingerScreenshotView.onTouchEvent(motionEvent);方法处理

@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubint cnt = event.getPointerCount();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:printLog("\n\nACTION_DOWN ");initThreshold(mContext);printLog("MIN_DISTANCE :" + MIN_DISTANCE);fingercount = 0;ry_pointer3_down = 0;ry_pointer3_move = 0;break;case MotionEvent.ACTION_UP:if (isShotSuccess() && !isScreenLock(mContext)) {mHandler.post(mPointerScreenshotRunnable); //三指成功}restoreShotScreenPropertiesFlag();endTime = startTime;break;case MotionEvent.ACTION_MOVE:ry_pointer3_move = (int) event.getY();if (fingercount < event.getPointerCount()) {fingercount = event.getPointerCount();}if(3 == cnt){for(int i = 0; i < cnt; i ++){mEnd[i] = (int) event.getY(i);}}break;

如果三个手指成功了则执行一个线程
mHandler.post(mPointerScreenshotRunnable);

如下:

private final Runnable mPointerScreenshotRunnable = new Runnable() {public void run() {Intent intent = new Intent(PointerScreenshotChord);            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY| Intent.FLAG_RECEIVER_FOREGROUND);mContext.sendBroadcastAsUser(intent, UserHandle.ALL);}
};

这个是发送广播消息代表三指成功。
因此在phoneWindow下面必须动态注册广播。

mPointerScreenshotChordReceiver = new PointerScreenshotChordReceiver();IntentFilter screenOffIntentFilter = new IntentFilter();screenOffIntentFilter.addAction(PointerScreenshotChord);context.registerReceiver(mPointerScreenshotChordReceiver, screenOffIntentFilter);

//接收广播

private class PointerScreenshotChordReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Slog.d("PointerScreenshotChordView", "mScreenshotRunnable ");mHandler.post(mScreenshotRunnable);}
}

如果接受到了广播执行下面这个线程

private class ScreenshotRunnable implements Runnable {private int mScreenshotType = TAKE_SCREENSHOT_FULLSCREEN;public void setScreenshotType(int screenshotType) {mScreenshotType = screenshotType;}@Overridepublic void run() {takeScreenshot(mScreenshotType);}}

最后调用
takeScreenshot(mScreenshotType);方法截屏

//开始截屏private void takeScreenshot(final int screenshotType) {Log.d(TAG, "takeScreenshot: " + screenshotType);synchronized (mScreenshotLock) {if (mScreenshotConnection != null) {if (messenger != null) {Log.d(TAG, "takeScreenshot use old service to take screenshot");msg.what = screenshotType;msg.arg1 = msg.arg2 = 0;if (mStatusBar != null && mStatusBar.isVisibleLw())msg.arg1 = 1;if (mNavigationBar != null && mNavigationBar.isVisibleLw())msg.arg2 = 1;try {messenger.send(msg);} catch (RemoteException e) {}return;}Log.d(TAG, "takeScreenshot before multi-functional screenshot, unbind old service");mContext.unbindService(mScreenshotConnection);mScreenshotConnection = null;messenger = null;msg = null;//return;filletScreen(false);}final ComponentName serviceComponent = new ComponentName(SYSUI_PACKAGE,SYSUI_SCREENSHOT_SERVICE_EXT);final Intent serviceIntent = new Intent();serviceIntent.setComponent(serviceComponent);ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {synchronized (mScreenshotLock) {if (mScreenshotConnection != this) {return;}messenger = new Messenger(service);msg = Message.obtain(null, screenshotType);final ServiceConnection myConn = this;Handler h = new Handler(mHandler.getLooper()) {@Overridepublic void handleMessage(Message msg) {synchronized (mScreenshotLock) {if (mScreenshotConnection == myConn) {mContext.unbindService(mScreenshotConnection);mScreenshotConnection = null;mHandler.removeCallbacks(mScreenshotTimeout);messenger = null;msg = null;filletScreen(true);}}}};msg.replyTo = new Messenger(h);msg.arg1 = msg.arg2 = 0;if (mStatusBar != null && mStatusBar.isVisibleLw())msg.arg1 = 1;if (mNavigationBar != null && mNavigationBar.isVisibleLw())msg.arg2 = 1;try {messenger.send(msg);} catch (RemoteException e) {}}}@Overridepublic void onServiceDisconnected(ComponentName name) {synchronized (mScreenshotLock) {if (mScreenshotConnection != null) {mContext.unbindService(mScreenshotConnection);mScreenshotConnection = null;mHandler.removeCallbacks(mScreenshotTimeout);notifyScreenshotError();messenger = null;msg = null;filletScreen(true);}}}};if (mContext.bindServiceAsUser(serviceIntent, conn,Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,UserHandle.CURRENT)) {mScreenshotConnection = conn;//mHandler.postDelayed(mScreenshotTimeout, 10000);}}}

代码有点长,可以去分析,最终调用systemui的服务区开启截屏,看了一下源码,最后服务调用surfaceflinger开启截屏。后面的没再去分析了 。

Android三指截屏的实现相关推荐

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

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

  2. Android N版本 三指截屏

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

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

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

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

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

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

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

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

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

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

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

  8. Mr.Alright---基于安卓O(8.0)三指截屏的实现

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

  9. android 8.1 截屏,Android8.1 MTK平台 截屏功能分析

    前言 涉及到的源码有 frameworksbaseservicescorejavacomandroidserverpolicyPhoneWindowManager.java vendormediate ...

最新文章

  1. 中班游戏电子计算机,幼儿园中班数学游戏:小小快递员
  2. 先装vs还是先装sql_【家装话题】装修师先装门还是先装地板?
  3. 【牛客 - 303B第十五届浙江大学宁波理工学院程序设计大赛(同步赛)】Fibonacci and Counting(Fib数性质,gcd辗转相除法性质)
  4. 德芙网络营销策略ppt_德芙网络营销方案
  5. 使用火狐浏览器的原因是什么?使用英文版火狐的原因又是什么?
  6. 编译原理课程作业-Cminus语言的词法及语法分析器实现
  7. setNavigationBarTitle小程序基础性操作标题改变
  8. 非参数统计的Python实现—— Kruskal-Wallis 单因素方差分析
  9. 数学建模论文写作——框架和要点
  10. 阿里云P10技术专家褚霸:我是一个程序员
  11. 软件测试的正反两面性思维,软件测试中破坏性测试思维的思考
  12. 计算机网络ping用法,新手入门:ping命令的用法解释
  13. php课程设计感想,设计心得体会
  14. Python-docx 读写 Word 文档:插入图片、表格,设置表格样式,章节,页眉页脚等
  15. pip2 python2.7 安装opencv-python cv2遇到问题的可能解决办法 skbuild list(pattern)
  16. 24岁我有了自己的公司
  17. 欧拉图与半欧拉图的基本概念以及判定方法
  18. 模板字符串`${}` 各种函数中的this指向?
  19. 电视剧中一看就让人崩溃的镜头大全~
  20. Java Swing中JFreeChart构建柱状图(非3D)时关于取消柱体的高亮问题的解决纪要?

热门文章

  1. C4D模型工具—矩阵挤压
  2. MySQL实战45讲(前5讲)
  3. linux shell 脚本 入门到实战详解
  4. 处理podman的overlay-containers中ctr.log日志文件过大的问题
  5. java printwriter结尾写入_java-PrintWriter追加方法不追加
  6. python网络爬虫实列——站长之家url解码编码
  7. shell脚本实例,通向shell脚本大师的必经之路
  8. 稻盛和夫:人为什么要结婚,这是我听到最好的答案
  9. 短视频APP+不同类型社交应用发展分析+化妆品电商
  10. 寻找跨越100年的投资策略