支持截取微博、知乎、今日头条等第三方APP……

先瞅瞅效果图:


再瞅瞅最终的长截图:

我是长截图一,瞅瞅嘛…

我是长截图二,再瞅一下嘛…

上一周脑子突然冒出长截图这个功能,想着如何截取如微博,知乎,头条等这些第三方APP的界面呢?出于好奇心,花了一周业余时间,撸一个看看。

不就是截屏+拼图,还能有什么难度么?这个。。。好像确实是。

1.如何截屏?

Android 5.0 API 21之前,想要系统截屏,是需要root,不过Android 5.0开始开放了响应的截屏接口:

MediaProjection (added in API level 21.) 
- A token granting applications the ability to capture screen contents and/or record system audio. The exact capabilities 
granted depend on the type of MediaProjection.

2.如何优雅的截图?

悬浮窗那么小,难道每次我都得滑一定的距离,然后点一次悬浮窗么,理论上可以,但体验不好。估计更多人倾向只要触摸屏幕就可以截图,所以选择监听悬浮窗外的触屏事件。

3.如何监听悬浮窗口外部的TouchEvent?

悬浮窗外的触屏事件都已经脱离整个应用了,如何监听呢?这里确实卡了些时间,因为确实找不到如何捕获这个事件的好,我感觉这个问题也是最烦的一个,后来来了点灵感,我设置一个全屏的透明背景,然后给这个背景设置onTouch事件,哦!!!恍然大悟,以为这样就可以了?错!!这样会出现整个手机的事件都将被这个透明背景拦截,无法传递到手机桌面,如果非开发人员安装了这个软件。。,告诉他,重新开机吧。。。所以翻了下WindowManager的源码,看到flag参数,把各种flag参数的注释看了遍,最后定位在如下几个flag参数值上。

 /** Window flag: this window won't ever get key input focus, so the* user can not send key or other button events to it.  Those will* instead go to whatever focusable window is behind it.  This flag* will also enable {@link #FLAG_NOT_TOUCH_MODAL} whether or not that* is explicitly set.** <p>Setting this flag also implies that the window will not need to* interact with* a soft input method, so it will be Z-ordered and positioned* independently of any active input method (typically this means it* gets Z-ordered on top of the input method, so it can use the full* screen for its content and cover the input method if needed.  You* can use {@link #FLAG_ALT_FOCUSABLE_IM} to modify this behavior. */public static final int FLAG_NOT_FOCUSABLE      = 0x00000008;/** Window flag: this window can never receive touch events. */public static final int FLAG_NOT_TOUCHABLE      = 0x00000010;/** Window flag: even when this window is focusable (its* {@link #FLAG_NOT_FOCUSABLE} is not set), allow any pointer events* outside of the window to be sent to the windows behind it.  Otherwise* it will consume all pointer events itself, regardless of whether they* are inside of the window. */public static final int FLAG_NOT_TOUCH_MODAL    = 0x00000020;/** Window flag: if you have set {@link #FLAG_NOT_TOUCH_MODAL}, you* can set this flag to receive a single special MotionEvent with* the action* {@link MotionEvent#ACTION_OUTSIDE MotionEvent.ACTION_OUTSIDE} for* touches that occur outside of your window.  Note that you will not* receive the full down/move/up gesture, only the location of the* first down as an ACTION_OUTSIDE.*/public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;

在全屏透明背景的环境下,本以为可以监听桌面的Down、Move、Up事件,但是出现事件全部被拦截死在这个透明背景上,无法传到手机桌面,再发现组合这些参数,总结这种思路不可取。

查看注释可以知道设置FLAG_WATCH_OUTSIDE_TOUCH可以在窗口外部(即App外部)接收一个指定事件MotionEvent#ACTION_OUTSIDE,但同时,你将无法接收到任何的Down、Move、Up事件。所以,也只能这样了。。有其它高招的兄弟指点下哈。

4.如何控制截屏频次?

在步骤3的基础上,基本可以做一个截图策略了,比如,每接收一次ACTION_OUTSIDE就截一次图,又或者,每次监听一次ACTION_OUTSIDE,就进行一次计数器的累加,为了保证截图能承上启下连贯,可以设置阈值为2这样。

5.如何拼图?

这里因人而异了,但目的都一样,将上述步骤所截的图对比出不同的地方,然后把不同的地方拼接起来。出于运算效率考虑,这里我是用JNI来实现的,主函数:

JNIEXPORT void JNICALL Java_com_zfw_screenshot_utils_SewUtils_merge(JNIEnv *env, jobject thiz, jobject bmp0, jobject bmp1, jobject bmp2, int h0, int h1, int h2, int samePart, int len) {int *pixels_0 = lockPixel(env, bmp0);int *pixels_1 = lockPixel(env, bmp1);int *pixels_2 = lockPixel(env, bmp2);/* -------------------- merge the difference ----------------------- */int index = 0;while(index < h0) {if(index < h1) {getRowPixels(pixels_0, index, pixels_1, index, len);} else {getRowPixels(pixels_0, index, pixels_2, index - h1 + samePart, len);}index++;}/* -------------------- merge the difference ----------------------- */unlockPixel(env, bmp0);unlockPixel(env, bmp1);unlockPixel(env, bmp2);
}

功能实现上没什么难度,感觉更多的是得选好实现的策略,比如如何优雅的监听悬浮窗外的Touch事件,如何优雅的实现一个“定点”截图的策略,如何优雅的对比两个Bitmap的不同地方,进行拼接。

源码传送门:https://github.com/zengfw/LongScreenShot

Android长图文截图的实现(支持截取第三方app)-(一)相关推荐

  1. android 第三方加密软件,Android实用图文教程之代码混淆、第三方平台加固加密、渠道分发...

    第一步:代码混淆(注意引入的第三方jar) 在新版本的ADT创建项目时,混码的文件不再是proguard.cfg,而是project.properties和proguard-project.txt. ...

  2. Android 系统 (39)---OTA后启动第三方APP出现APP Crash

    FOTA/OTA之後启动第三方APP出現APP Crash 1.问题   用FOTA下载OTA包,下载完毕更新:   更新完毕后点击多个三方APP无法进入,提示报错(这些APK都是正常安装,非预置). ...

  3. android 8.1 9.0 10.0 默认允许安装第三方app去掉未知来源弹窗直接安装apk

    1.概述 在10.0的产品开发中,8.0以后对于安装第三方app时需要申请 REQUEST_INSTALL_PACKAGES权限,那么没有申请权限时就会弹出 安装未知来源的对话框,而在定制化开发中,有 ...

  4. 苹果屏幕上的小圆点_今天才发现,苹果手机点一下屏幕就能截图,还支持长截图学到了...

    今天才发现,苹果手机点1下屏幕就能截图,还支持长截图学到了 我们现在买手机,不仅注重颜值和拍照,还注重实用性.实用性强的手机往往能给我们生活带来很多便利. 今天笔者以苹果手机为例,教大家怎样点一下苹果 ...

  5. Google Maps API v2 android版本开发 国内手机不支持google play Service相关问题解决--图文教程

    Google Maps API v2 android版本开发 国内手机不支持google play Service相关问题解决--图文教程 参考文章: (1)Google Maps API v2 an ...

  6. Android长截图与长图分享

    1.第一步如何实现长截图 Android长截屏– ScrollView,ListView及RecyclerView截屏 这个链接地址写的很清楚了,建议进行实际操作. 概述:其实长截图就是将布局存成图像 ...

  7. Qt on Android:图文详解Hello World全过程

    这是系列文章中的一篇,阅读本文前请先阅读<Windows下Qt 5.2 for Android开发入门>,以便确保开发环境和作者一致. 部分文章被转发/转载却没有注明出处,特此声明:版权所 ...

  8. android获取activity截图,Android Activity 不能被截屏的解决方法

    Android Activity 不能被截屏的解决方法 在Activity 添加即可 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECU ...

  9. android长截屏代码,android长截屏原理及实现代码

    android长截屏原理及实现代码 发布时间:2020-08-31 06:55:16 来源:脚本之家 阅读:158 作者:Android笔记 小米系统自带的长截屏应该很多人都用过,效果不错.当长截屏时 ...

最新文章

  1. Spring testcontext
  2. C# 实现基于ffmpeg加虹软的人脸识别
  3. 手机php文件怎么改后辍,php修改文件后缀名的方法
  4. dojo中的dojo/dom-construct
  5. 解决 Azure AD 在 Azure Front Door 下登录失败的问题
  6. greenplum配置高可用_0665-6.2.0-如何在CDH中配置HMS高可用
  7. ASP.Net学习笔记014--ViewState初探3
  8. jedis java.lang.verifyerror_需要使用jfinal中的JedisPlugin的一些问题
  9. Uploadify 3.2 参数属性、事件、方法函数详解
  10. 黑进iPhone让手机崩溃重启,只需15行代码:iOS漏洞你可知?
  11. setTimeout和setInteval
  12. Tomcat 7源码学习笔记 -5 web app自动reload
  13. 四、公文流转的基本过程
  14. 无能的力量 -- 《看见》
  15. 数字电路(4)门电路(三)
  16. 中华小子剧情介绍,中华小子在线观看
  17. 卷积神经网络超详细介绍
  18. python时间序列分析航空旅人_大佬整理的Python数据可视化时间序列案例,建议收藏(附代码)...
  19. 手机社会化分享到qq好友、qq空间、微信、微信朋友圈、微博等(区分浏览器)
  20. 第五期 中断设计 基于ARTY A7的MicroBlaze系统搭建与应用

热门文章

  1. linux自带视频播放VLC,如何将VLC媒体播放器设置为默认视频播放器?
  2. 如何让公司其他人(同一个局域网)访问自己电脑静态.html
  3. Qt与设计模式(全)
  4. 百度地图API Android SDK 常见问题
  5. CAP理论举例及说明
  6. Android学习1——开发环境搭建、Android Studio安装
  7. 整理!这10款PC端软件,设计师必备!
  8. html使用表格实现网页制作
  9. JS中typeof() !== 'undefined'的解释
  10. 基于令牌的服务器访问验证失败