【技術流】Android 截屏監聽:如何實現截圖分享功能?

【技術流】Android 截屏監聽:如何實現截圖分享功能?

1. 背景 :

具體來說就是,檢測到了用戶在應用內有截圖,彈出一個分享界面, 在截圖下方添加一個二維碼,進行分享。

2. 前言

Android系統沒有直接對截屏事件監聽的介面,也沒有廣播,只能自己動手來豐衣足食,一般有三種方法。

  • 利用FileObserver監聽某個目錄中資源變化情況
  • 利用ContentObserver監聽全部資源的變化
  • 監聽截屏快捷按鍵 ( 由於廠商自定義Android系統的多樣性,再加上快捷鍵的不同以及第三方應用,監聽截屏快捷鍵這事基本不靠譜,可以直接忽略 )

3.Android截屏系統做的事情

通過讀源碼(TakeScreenshotService 和 GlobalScreenshot )總結Android截屏系統做的事情:

  1. 保存截屏Bitmap到本地文件
  2. 把圖片記錄插入到ContentProvider中
  3. 發送一個截圖相關的Notification

解決方法:

  • 利用FileObserver監聽某個目錄中資源變化情況
  • 利用ContentObserver監聽全部資源的變化

4. FileObserver 與 ContentObserver 比較

對於截圖監聽有兩種常用方案

方案一: 通過FileObserver監聽截屏文件夾,當有新的截屏文件產生時,調用設定的回調函數執行相關操作。

優點:

  • 實現簡單

缺點:

  • 不同手機默認的截屏路徑可能不同,需要做適配處理
  • 不同手機截屏觸發的事件名稱可能不同,需要測試適配
  • 監聽到截屏事件後馬上獲取圖片獲取不到,需要延遲一段時間

方案二:通過ContentObserver監聽多媒體圖片庫資源的變化。當手機上有新的圖片文件產生時都會通過MediaProvider類向圖片資料庫插入一條記錄,以方便系統的圖片庫進行圖片查詢,可以通過ContentObserver接收圖片插入事件,並獲取插入圖片的URI。

優點:

  • 不同手機觸發的事件是一樣的

缺點:

  • 不同手機截屏文件的前綴可能不同,需要做適配
  • 監聽到截屏事件後馬上獲取圖片獲取不到,需要延遲一段時間

4.1 FileObserver實現

最開始就是想到這個方法, 當FileObserver監聽某個目錄中資源變化情況,時候獲取到文件路徑

a. 關鍵代碼:

  • 監聽到截屏事件後馬上獲取圖片獲取不到,可能需要延遲一段時間。 做while循環,收到Create時間後,Thread.sleep(600), 當嘗試最大次數(MAX_TRYS)失敗後放棄。
  • SNAP_SHOT_FOLDER_PATH 的路徑不同手機不一樣,要去適配各種手機的路徑

  • 需要許可權,否則可能收不到事件。

(如果沒有收到事件,檢查一下許可權和監聽的目錄)

b. 小結:

  • 每一次截屏,有多個事件回調
  • 每一次截屏,不同的手機,事件回調可能有些不同。
  • 不同的手機,默認截屏圖片儲存的文件夾可能不同
  • FileObserver只能監聽文件夾中子文件和子文件夾的變化情況,不能監聽子文件夾內部的資源變化

基於 不同的手機,默認截屏圖片儲存的文件夾可能不同可能收不到事件,這種方法並不能適用於所有的機型。

4.2 .ContentObserver實現

放棄了FileObserver方法, 最後選擇了ContentObserver方法。通過ContentObserver監聽多媒體圖片庫資源的變化。當手機上有新的圖片文件產生時都會通過MediaProvider類向圖片資料庫插入一條記錄,以方便系統的圖片庫進行圖片查詢,可以通過ContentObserver接收圖片插入事件,並獲取插入圖片的URI。

a.步驟

(1)添加許可權

(2)初始化、註冊和取消監聽

(3)媒體內容觀察者 (觀察媒體資料庫的改變)

(4)數據改變時查詢資料庫中最後加入的一條數據,處理獲取到的第一行數據。

(5)處理監聽到的資源, 設置最大等待時間500ms (因為某些魅族手機保存有延遲)

(6)設置回調工具

b. 遇到問題

主要問題都在第五步:

(1)因為某些魅族手機保存有延遲 , 輪詢與延遲,設置最大等待時間500ms

(2)要判斷是否是截屏,有可能是用戶自己再文件夾中添加了一張圖片

c. 小結:

  • ContentObserver會監聽到所有圖片資源的變化情況,要做好去重過濾工作
  • 根據uri去讀取ContentProvider內容時候,記得關閉cursor,防止內存泄漏
  • 關鍵字可擴展,大大增加的監聽的範圍,比FileObserver好用多了,但是去重過濾會比FileObserver複雜一些。

5. 二維碼拼接(bitmap)

  • Bitmap縱向拼接

參考文獻

1、Android 截屏事件監聽juejin.im/entry/58647ee

2、嚴選Android-截圖分享功能實現與踩坑分享 ks.netease.com/blog?

3、Android App內截屏監控及塗鴉功能實現 jianshu.com/p/2e6d52abf

本文作者:吳思博,網易杭州研究院文學漫畫產品部。


推薦閱讀:

Android 6.0 還需要使用綠色守護嗎?
JS 如何獲取和監聽屏幕方向的改變?
如何看待 MIUI 測試手機會員去廣告功能?
如何看待三星旗艦s8/s8+ 也是混用快閃記憶體晶元?
為什麼安卓國行比水貨貴那麼多?

TAG:Android | Android開發 | 截屏 |