Android三指截屏实现,一个简单的三指截屏功能实现
最近做了很多客制化的Touch需求,很多情况都可以直接通过GestureDetector来完成,这里挑选三指截屏简述原理。先来说说主要思路,在view的onInterceptTouchEvent方法中,处理pointerCount==3时的ACTION_MOVE事件,在这里可以判断手指滑动的速度,距离等,当满足我们需要的条件时,便可进行操作(这里的截屏是通过sendBroadcast(intent)后在PhoneWindowManager中接受广播进行截屏操作)。
在重写相关view的Touch操作时,先获取到当前的屏幕参数:
DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();//获取手机屏幕参数
mHeightPixels = metrics.heightPixels;//获取手机屏幕高度
重写onInterceptTouchEvent,利用Point存储手指移动前后X、Y轴的位置,可以在event.getPointerCount()满足需求时进行判断(不同屏幕支持多点触控的count也不相同,自己测试得到的最大值为5),同时定义了一个mMode变量,可以在case MotionEvent.ACTION_POINTER_DOWN中为其赋值,设置当前的mode类型,具体代码如下:
public boolean onInterceptTouchEvent(MotionEvent event) {
if(true) {
int pointerCount = event.getPointerCount();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mEnterTime = System.currentTimeMillis();
mMode = MODE_NONE;
CURRENT_SOUND_STEP = 15;//mAM.getStreamVolume(AudioManager.STREAM_SYSTEM);
initP0.x = preP0.x = (int)event.getX(0);
initP0.y = preP0.y = (int)event.getY(0);
break;
case MotionEvent.ACTION_MOVE:
//for when pointerCount ==3 but not go into ACTION_POINTER_DOWN
if(mMode == MODE_NONE || mMode == MODE_INTERUPT) {
break;
} else if((mMode == MODE_2) && (pointerCount == 2)) {
Point current0 = new Point((int)event.getX(0), (int)event.getY(0));
Point current1 = new Point((int)event.getX(1), (int)event.getY(1));
int step = (current0.y - preP0.y) / SOUND_STEP;
if(step != 0) {
int current = CURRENT_SOUND_STEP + (initP0.y - current0.y) / SOUND_STEP;
current = current < 0 ? 0 : current;
current = current > MAX_SOUND_STEP ? MAX_SOUND_STEP : current;
Log.i(TAG, "current:" + current);
//mAM.setMode(AudioManager.MODE_NORMAL);
mAM.setStreamVolume(AudioManager.STREAM_SYSTEM, current, AudioManager.FLAG_PLAY_SOUND);
preP0 = current0;
preP1 = current1;
} else if((mMode == MODE_3) && (pointerCount == 3)) {
Point current0 = new Point((int)event.getX(0), (int)event.getY(0));
Point current1 = new Point((int)event.getX(1), (int)event.getY(1));
Point current2 = new Point((int)event.getX(2), (int)event.getY(2));
if(Math.abs(current0.y - initP0.y) > (mHeightPixels / 10) &&
Math.abs(current1.y - initP1.y) > (mHeightPixels / 10) &&
Math.abs(current2.y - initP2.y) > (mHeightPixels / 10)) {
Intent intent = new Intent("intent.action.SendKey");
intent.putExtra("KeyCode", KeyEvent.KEYCODE_SYSRQ);
getContext().sendBroadcast(intent);
Log.e(TAG, "takeScreenshot!");
mMode = MODE_INTERUPT;
}
return true;//该touch事件终止向子view传递
}
break;
//有一个非主要的手指按下了
case MotionEvent.ACTION_POINTER_DOWN:
if(mMode == MODE_INTERUPT) {
break;
}
if(pointerCount == 2) {
mMode = MODE_2;
initP1.x = preP1.x = (int)event.getX(1);
initP1.y = preP1.y = (int)event.getY(1);
if(Math.abs(initP0.y - initP1.y) > (SOUND_STEP * 2)) {
mMode = MODE_INTERUPT;
Log.i(TAG, "ACTION_POINTER_DOWN p0 and p1 are too far.");
break;
}
Log.i(TAG, "ACTION_POINTER_DOWN MODE_2.");
} else if(pointerCount == 3) {
mMode = MODE_3;
initP1.x = preP1.x = (int)event.getX(1);
initP1.y = preP1.y = (int)event.getY(1);
initP2.x = preP2.x = (int)event.getX(2);
initP2.y = preP2.y = (int)event.getY(2);
Log.i(TAG, "ACTION_POINTER_DOWN MODE_3.");
}
if((System.currentTimeMillis() - mEnterTime) > 500) {
mMode = MODE_INTERUPT;
Log.i(TAG, "ACTION_POINTER_DOWN too slowly.");
}
break;
//有一个非主要的手指抬起了
case MotionEvent.ACTION_POINTER_UP:
mMode = MODE_INTERUPT;
break;
case MotionEvent.ACTION_UP:
mMode = MODE_NONE;
break;
}
}
}
具体的滑动距离,速度,方向等都可已自己根据需求修改。
接收广播时,registerReceiver与unregisterReceiver即可,注意在进行截屏前判断下当前的开关值
BroadcastReceiver mKeyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
boolean m3PTouchScreenshot;
if ("intent.action.SendKey".equals(action)) {
Bundle bundle = intent.getExtras();
int keycode = bundle.getInt("KeyCode");
Log.i(TAG, "mKeyReceiver:" + keycode);
switch(keycode) {
case KeyEvent.KEYCODE_SYSRQ:
boolean touchScreenshot = SystemProperties.getBoolean("3p_screenshot_off", false);
m3PTouchScreenshot = Settings.Global.getInt(context.getContentResolver(), "3p_touch_screenshot", (!touchScreenshot ? 1 : 0)) == 1;
Log.i(TAG, "m3PTouchScreenshot:" + m3PTouchScreenshot);
if(m3PTouchScreenshot)
takeScreenshot();
break;
}
}
}
};
takeScreenshot()就是执行的截屏操作啦~
Android三指截屏实现,一个简单的三指截屏功能实现相关推荐
- Android获取文字字数,如何实现一个简单的字数统计,限制功能
Layout样式: layout 代码:<?xml version="1.0" encoding="utf-8"?> xmlns:android= ...
- 一个五位数取前三位matlab,【有五个小球,分别是1,2,3,4,5号,有放回的从中取三次,每次取一个,...-前三后五取一颗-数学-关偈邓同学...
概述:本道作业题是关偈邓同学的课后练习,分享的知识点是前三后五取一颗,指导老师为习老师,涉及到的知识点涵盖:[有五个小球,分别是1,2,3,4,5号,有放回的从中取三次,每次取一个,...-前三后五取 ...
- android实现mysql数据库存储_一个简单的Android端对象代理数据库系统的实现(二、执行+存储)...
这是我之前在武汉大学彭智勇老师那边做过的一个对象代理数据库系统.文中给出了一整个系统的几乎所有代码,经测试可正常运行.文章比较长,超出了知乎的最长文章范围,因此分为两篇文章.这是第二篇. 执行 执行部 ...
- Android之使用VideoView组件播放一个简单的视频
1.在Android开发中,提供了VideoView组件用来播放视频文件.首先,要使用这个组件来播放视频,必须在布局文件下添加VideoView组件,然后再到Activity里获取这个组件,然后调用这 ...
- android sqlite 操作类封装,SQLiteUtils 一个简单的基于 Android 的 Sqlite 数据库的操作封装库 @codeKK Android开源站...
一个简单的基于 Android 的 Sqlite 数据库的操作封装,它有如下的好处: 便捷地创建表和增添表字段 通过操作对象来 insert 或者 update 表记录 支持多种查询方式,支持分页查询 ...
- 标题相似度算法_一个简单的计算文章相似度功能!
在做文章系统的时候,很多时候需要为这篇文章推荐最相近的文章. 解决思路是:给文章设定关键词然后模糊查询进行匹配.找到包含这个关键词的标题,然后给显示出来,作为最接近的文章. 但是有问题:这样的文章,排 ...
- android 模拟器作用,安卓模拟器:看似简单实则用处极大的日常功能
原标题:安卓模拟器:看似简单实则用处极大的日常功能 逍遥安卓模拟器每个版本都会推出一些实用性比较强大的功能,并不断完善现有功能,为用户带来良好的游戏体验,今天给大家带来的是每天使用率较高的功能完整版解 ...
- C语言求经理三个女儿的年龄,一个经理有三个女儿答案
问题: 一个经理有三个女儿,三个女儿的年龄加起来等于13,三个女儿的年龄乘起来等于经理自己的年龄,有一个下属已知道经理的年龄,但仍不能确定经理三个女儿的年龄,这时经理说只有一个女儿的头发是黑的,然后这 ...
- Android开发:ListView+SQLite实现一个简单的备忘录程序(ADT插件环境)
前话:明天要交安卓程序了,前几天在自己的电脑上配置了一下安卓环境,但是项目无法编译,原因好像是jdk版本过高,有一个包无法支持,然后换成1.8的jdk也不行,昨晚折腾到凌晨一点半也没成功,今天借了同学 ...
最新文章
- php能实现文本复制吗,php 简单复制文件的方法
- 测试Hibernate连接数据库的测试代码
- 解决虚拟机 Virtualbox 中 linux 共享文件夹只读问题
- e语言怎么连接mysql_大佬们E语言连接MYSQL输出中文乱码怎么破
- 破烂微软的.NET IDE环境
- 2019牛客暑期多校训练营(第七场)D Number(思维)
- 【最新合集】PAT甲级最优题解(题解+解析+代码)
- java笔试题_Java面试才到笔试就没有然后了?快来签收,高频笔试57题及解答
- 【数据结构与算法】伸展树的Java实现
- 在Cygwin上安装编辑器vim 【ZT】
- 过来人的亲身经验告诉你,如何从菜鸟晋升月薪过万的测试工程师
- 微信小程序中base64图片的显示与保存
- 10. python-es-8.3.3-IP范围聚合ip_range
- 利用ESP8266与米思齐从零制作模拟温室大棚--程序篇
- 《德鲁克管理思想精要》读书笔记2 - 企业的宗旨、目标
- ArcEngine实现要素类排序的四种方法
- 使用Python从头实现一个神经网络
- mac chrome 常用插件
- 软件工程第五章——总体设计
- 【ROS】[rosrun] Couldn't find executable named
热门文章
- 企业微信开发/主要代码分享(前端)
- 2021年“韭零后”基民人群洞察:学历高也免不了被“割”
- html5 刷分,实现web页面局部动态刷新
- 网页在线图片格式转换源码
- 故事快讲不下去的互联网新秀们
- SVN服务器搭建Visual Studio 2013 使用AnkhSVN 插件
- linux文件对用户隐藏,Linux就该这么学-文件的特殊权限、隐藏权限
- 认证(Authentication)和授权(Authorization)
- OSChina 周五乱弹 —— 真人 007
- 明明在同一个局域网下为啥我的电视不能投屏了