日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android长图文截图的实现(支持截取微博,知乎,头条等第三方app)

發(fā)布時間:2023/12/10 Android 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android长图文截图的实现(支持截取微博,知乎,头条等第三方app) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

源碼:https://github.com/zengfw/LongScreenShot

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

先瞅瞅效果圖:

再瞅瞅最終的長截圖:

我是長截圖一,瞅瞅嘛…

我是長截圖二,再瞅一下嘛…

上一周腦子突然冒出長截圖這個功能,想著如何截取如微博,知乎,頭條等這些第三方APP的界面呢?出于好奇心,花了一周業(yè)余時間,擼一個看看。

不就是截屏+拼圖,還能有什么難度么?這個。。。好像確實(shí)是。

Question:

1.如何截屏?

Android 5.0 API 21之前,想要系統(tǒng)截屏,是需要root,不過Android 5.0開始開放了響應(yīng)的截屏接口:

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.如何優(yōu)雅的截圖?

懸浮窗那么小,難道每次我都得滑一定的距離,然后點(diǎn)一次懸浮窗么,理論上可以,但體驗(yàn)不好。估計(jì)更多人傾向只要觸摸屏幕就可以截圖,所以選擇監(jiān)聽?wèi)腋〈巴獾挠|屏事件。

3.如何監(jiān)聽?wèi)腋〈翱谕獠康腡ouchEvent?

懸浮窗外的觸屏事件都已經(jīng)脫離整個應(yīng)用了,如何監(jiān)聽呢?這里確實(shí)卡了些時間,因?yàn)榇_實(shí)找不到如何捕獲這個事件的好,我感覺這個問題也是最煩的一個,后來來了點(diǎn)靈感,我設(shè)置一個全屏的透明背景,然后給這個背景設(shè)置onTouch事件,哦!!!恍然大悟,以為這樣就可以了?錯!!這樣會出現(xiàn)整個手機(jī)的事件都將被這個透明背景攔截,無法傳遞到手機(jī)桌面,如果非開發(fā)人員安裝了這個軟件。。,告訴他,重新開機(jī)吧。。。所以翻了下WindowManager的源碼,看到flag參數(shù),把各種flag參數(shù)的注釋看了遍,最后定位在如下幾個flag參數(shù)值上。

/** 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;

在全屏透明背景的環(huán)境下,本以為可以監(jiān)聽桌面的Down、Move、Up事件,但是出現(xiàn)事件全部被攔截死在這個透明背景上,無法傳到手機(jī)桌面,再發(fā)現(xiàn)組合這些參數(shù),總結(jié)這種思路不可取。

查看注釋可以知道設(shè)置FLAG_WATCH_OUTSIDE_TOUCH可以在窗口外部(即App外部)接收一個指定事件MotionEvent#ACTION_OUTSIDE,但同時,你將無法接收到任何的Down、Move、Up事件。所以,也只能這樣了。。有其它高招的兄弟指點(diǎn)下哈。

4.如何控制截屏頻次?

在步驟3的基礎(chǔ)上,基本可以做一個截圖策略了,比如,每接收一次ACTION_OUTSIDE就截一次圖,又或者,每次監(jiān)聽一次ACTION_OUTSIDE,就進(jìn)行一次計(jì)數(shù)器的累加,為了保證截圖能承上啟下連貫,可以設(shè)置閾值為2這樣。

5.如何拼圖?

這里因人而異了,但目的都一樣,將上述步驟所截的圖對比出不同的地方,然后把不同的地方拼接起來。出于運(yùn)算效率考慮,這里我是用JNI來實(shí)現(xiàn)的,主函數(shù):

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); }

功能實(shí)現(xiàn)上沒什么難度,感覺更多的是得選好實(shí)現(xiàn)的策略,比如如何優(yōu)雅的監(jiān)聽?wèi)腋〈巴獾腡ouch事件,如何優(yōu)雅的實(shí)現(xiàn)一個“定點(diǎn)”截圖的策略,如何優(yōu)雅的對比兩個Bitmap的不同地方,進(jìn)行拼接。

源碼傳送門:https://github.com/zengfw/LongScreenShot

有什么好的策略以及問題,歡迎留言,一起探討哈,看看有沒有更優(yōu)雅的實(shí)現(xiàn)方式!

總結(jié)

以上是生活随笔為你收集整理的Android长图文截图的实现(支持截取微博,知乎,头条等第三方app)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。