By 吳思博 20180428
1. 背景 :
? ? 具體來說就是牺蹄,檢測到了用戶在應(yīng)用內(nèi)有截圖忘伞,彈出一個分享界面, 在截圖下方添加一個二維碼沙兰,進行分享氓奈。
先展示下效果圖
2. 前言
Android系統(tǒng)沒有直接對截屏事件監(jiān)聽的接口,也沒有廣播鼎天,只能自己動手來豐衣足食舀奶,一般有三種方法。
利用FileObserver監(jiān)聽某個目錄中資源變化情況
利用ContentObserver監(jiān)聽全部資源的變化
監(jiān)聽截屏快捷按鍵? ( 由于廠商自定義Android系統(tǒng)的多樣性斋射,再加上快捷鍵的不同以及第三方應(yīng)用育勺,監(jiān)聽截屏快捷鍵這事基本不靠譜,可以直接忽略 )
3.Android截屏系統(tǒng)做的事情
通過讀源碼(TakeScreenshotService 和 GlobalScreenshot )總結(jié)Android截屏系統(tǒng)做的事情:
保存截屏Bitmap到本地文件
把圖片記錄插入到ContentProvider中
發(fā)送一個截圖相關(guān)的Notification
解決方法:
利用FileObserver監(jiān)聽某個目錄中資源變化情況
利用ContentObserver監(jiān)聽全部資源的變化
4. FileObserver 與 ContentObserver 比較
對于截圖監(jiān)聽有兩種常用方案
方案一: 通過FileObserver監(jiān)聽截屏文件夾罗岖,當(dāng)有新的截屏文件產(chǎn)生時怀大,調(diào)用設(shè)定的回調(diào)函數(shù)執(zhí)行相關(guān)操作。
優(yōu)點:
1. 實現(xiàn)簡單
缺點:
1. 不同手機默認的截屏路徑可能不同呀闻,需要做適配處理
2. 不同手機截屏觸發(fā)的事件名稱可能不同化借,需要測試適配
3. 監(jiān)聽到截屏事件后馬上獲取圖片獲取不到,需要延遲一段時間
方案二:通過ContentObserver監(jiān)聽多媒體圖片庫資源的變化捡多。當(dāng)手機上有新的圖片文件產(chǎn)生時都會通過MediaProvider類向圖片數(shù)據(jù)庫插入一條記錄蓖康,以方便系統(tǒng)的圖片庫進行圖片查詢铐炫,可以通過ContentObserver接收圖片插入事件,并獲取插入圖片的URI蒜焊。
優(yōu)點:
1. 不同手機觸發(fā)的事件是一樣的
缺點:
1. 不同手機截屏文件的前綴可能不同倒信,需要做適配
2. 監(jiān)聽到截屏事件后馬上獲取圖片獲取不到,需要延遲一段時間
4.1 FileObserver實現(xiàn)
最開始就是想到這個方法泳梆, 當(dāng)FileObserver監(jiān)聽某個目錄中資源變化情況鳖悠,時候獲取到文件路徑
a. 關(guān)鍵代碼:
監(jiān)聽到截屏事件后馬上獲取圖片獲取不到,可能需要延遲一段時間优妙。? 做while循環(huán)乘综,收到Create時間后,Thread.sleep(600)套硼, 當(dāng)嘗試最大次數(shù)(MAX_TRYS)失敗后放棄卡辰。
SNAP_SHOT_FOLDER_PATH? 的路徑不同手機不一樣,要去適配各種手機的路徑
需要權(quán)限邪意,否則可能收不到事件九妈。
? ? (如果沒有收到事件,檢查一下權(quán)限和監(jiān)聽的目錄)
b. 小結(jié):
每一次截屏雾鬼,有多個事件回調(diào)
每一次截屏萌朱,不同的手機,事件回調(diào)可能有些不同策菜。
不同的手機晶疼,默認截屏圖片儲存的文件夾可能不同
FileObserver只能監(jiān)聽文件夾中子文件和子文件夾的變化情況,不能監(jiān)聽子文件夾內(nèi)部的資源變化
基于? 不同的手機做入,默認截屏圖片儲存的文件夾可能不同 和 可能收不到事件冒晰,這種方法并不能適用于所有的機型。
4.2 .ContentObserver實現(xiàn)
放棄了FileObserver方法竟块, 最后選擇了ContentObserver方法壶运。通過ContentObserver監(jiān)聽多媒體圖片庫資源的變化。當(dāng)手機上有新的圖片文件產(chǎn)生時都會通過MediaProvider類向圖片數(shù)據(jù)庫插入一條記錄浪秘,以方便系統(tǒng)的圖片庫進行圖片查詢蒋情,可以通過ContentObserver接收圖片插入事件,并獲取插入圖片的URI耸携。
a.步驟
(1)添加權(quán)限
(2)初始化棵癣、注冊和取消監(jiān)聽
(3)媒體內(nèi)容觀察者 (觀察媒體數(shù)據(jù)庫的改變)
(4)數(shù)據(jù)改變時查詢數(shù)據(jù)庫中最后加入的一條數(shù)據(jù),處理獲取到的第一行數(shù)據(jù)夺衍。
(5)處理監(jiān)聽到的資源狈谊, 設(shè)置最大等待時間500ms (因為某些魅族手機保存有延遲)
(6)設(shè)置回調(diào)工具
b.遇到問題:
主要問題都在第五步:
(1)因為某些魅族手機保存有延遲 , 輪詢與延遲,設(shè)置最大等待時間500ms
(2)要判斷是否是截屏河劝,有可能是用戶自己再文件夾中添加了一張圖片
c. 小結(jié):
ContentObserver會監(jiān)聽到所有圖片資源的變化情況壁榕,要做好去重過濾工作
根據(jù)uri去讀取ContentProvider內(nèi)容時候,記得關(guān)閉cursor赎瞎,防止內(nèi)存泄漏
關(guān)鍵字可擴展牌里,大大增加的監(jiān)聽的范圍,比FileObserver好用多了务甥,但是去重過濾會比FileObserver復(fù)雜一些牡辽。
5.? 二維碼拼接(bitmap)
1、Bitmap縱向拼接
補充 :
今天測試時候 敞临,發(fā)現(xiàn)個別手機會自己修改截圖文件夾的文件态辛, 截屏功能會誤以為是用戶在截屏操作,進行捕獲哟绊。 所以加了一個時間判斷
打印觀察到截圖插入時間不會改變
附上 : 獲取插入時間(單位是秒非毫秒)
參考文獻
1因妙、Android 截屏事件監(jiān)聽https://juejin.im/entry/58647ee9128fe1006d0f4454
2痰憎、嚴選Android-截圖分享功能實現(xiàn)與踩坑分享 http://ks.netease.com/blog?id=7038
3票髓、Android App內(nèi)截屏監(jiān)控及涂鴉功能實現(xiàn) http://www.reibang.com/p/2e6d52abf115