下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android中對(duì)截圖事件進(jìn)行監(jiān)聽的原理是什么
這篇文章給大家介紹android中對(duì)截圖事件進(jìn)行監(jiān)聽的原理是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。1.監(jiān)聽截屏圖片所在目錄變化(FileObserver)2.監(jiān)聽媒體庫的變化(ContentObserver)
上面兩種方法均不是萬能的,需要結(jié)合使用才能達(dá)到良好的效果,首先看看如何監(jiān)控目錄在android中,我們可以通過FileObserver來監(jiān)聽目錄變化,先來看看如何使用private
static
final
File
DIRECTORY_PICTURES
=
new
File(Environment.getExternalStorageDirectory(),
Environment.DIRECTORY_PICTURES);
private
static
final
File
DIRECTORY_DCIM
=
new
File(Environment.getExternalStorageDirectory(),
Environment.DIRECTORY_DCIM);
if
(manufacturer.equalsIgnoreCase("xiaomi"))
{
DIRECTORY_SCREENSHOT
=
new
File(DIRECTORY_DCIM,
"Screenshots");
}
else
{
DIRECTORY_SCREENSHOT
=
new
File(DIRECTORY_PICTURES,
"Screenshots");
}
FILE_OBSERVER
=
new
FileObserver(DIRECTORY_SCREENSHOT.getPath(),
FileObserver.ALL_EVENTS)
{
@Override
public
void
onEvent(int
event,
String
path)
{
if
(event
==
FileObserver.CREATE)
{
String
newPath
=
new
File(DIRECTORY_SCREENSHOT,
path).getAbsolutePath();
Log.d(TAG,
"path:
"
+
newPath);
}
}
};我們對(duì)指定目錄的指定事件監(jiān)聽即可,當(dāng)事件被觸發(fā)時(shí)onEvent會(huì)回調(diào)。這里我們只關(guān)心目錄中有沒有新的文件生成???:在實(shí)踐中發(fā)現(xiàn),并不是所有手機(jī)都允許如此監(jiān)聽或者說都能收到回調(diào)。有的手機(jī)上面無法收到CREATE事件,但是可以收到其他事件。我還發(fā)現(xiàn),有的時(shí)候收到的事件并沒有在FileObserver中定義,比如32768!下面是Linux中相應(yīng)event對(duì)應(yīng)的含義,32768=IN_IGNORED,但是為什么會(huì)ignore,并不清楚。/lxr/http/source/include/linux/inotify.h?a=m68k#L45還遇到過1073741856(1073741856=0x40000000|0x20,即IN_OPEN|IN_ISDIR)和1073741840(1073741840=0x40000000|0x10,即IN_CLOSE_NOWRITE|IN_ISDIR)???:不同手機(jī),監(jiān)聽的目錄并不一致。小米需要監(jiān)聽Environment.DIRECTORY_DCIM,其他監(jiān)聽Environment.DIRECTORY_PICTURES即可。關(guān)于FileObserver這里再多說兩句,F(xiàn)ileObserver無法進(jìn)行遞歸監(jiān)聽,也就是說,我們監(jiān)聽的文件夾中如果有子文件夾,并且我們想知道其中變化,這種方式是不可行的。需要手動(dòng)對(duì)子文件進(jìn)行操作。另外,當(dāng)我們監(jiān)聽的目錄/文件被刪除后又重新建立了一個(gè)同名的目錄/文件,之前的FileObserver不會(huì)繼續(xù)工作,需要重新設(shè)置監(jiān)聽才行。還要注意,F(xiàn)ileObserver回調(diào)并不在主線程中,而是在FileObserver線程中。鑒于上述原因,我們還要使用方法2,監(jiān)聽媒體庫變化。這個(gè)方法使用ContentObserver即可。private
static
final
ContentObserver
CONTENT_OBSERVER
=
new
ContentObserver(HANDLER)
{
@Override
public
void
onChange(boolean
selfChange,
Uri
uri)
{
//記得先檢查讀文件的權(quán)限
ContentResolver
resolver
=
GeneralInfoHelper.getContext().getContentResolver();
if
(uri.toString().matches(MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+
"(/\\d+)?"))
{
Cursor
cursor
=
resolver.query(uri,
PROJECTION,
null,
null,
MediaStore.MediaColumns.DATE_ADDED
+
"
DESC");
if
(cursor
!=
null
&&
cursor.moveToFirst())
{
//完整路徑
String
newPath
=
cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA));
File
file
=
new
File(newPath);
//file.exists()
判斷文件是否存在
}
if
(cursor
!=
null)
{
cursor.close();
}
}
}
};
getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
true,
CONTENT_OBSERVER);坑3:實(shí)踐中發(fā)現(xiàn),并不是所有手機(jī)都是監(jiān)聽相同的Uri,有的帶數(shù)字,有的不帶???:查詢數(shù)據(jù)庫時(shí)記得按MediaStore.MediaColumns.DATE_ADDED字段排序,注意,這個(gè)時(shí)間單位是秒,不是毫秒坑5:即使排了序,你拿到的仍然有可能不是正確的,在魅族E2上面出現(xiàn)了這個(gè)問題。但是當(dāng)我刪除了魅族E2截圖文件夾之后,一切又恢復(fù)正常了……這里我做了一個(gè)簡單的判斷,如何DATE_ADDED和當(dāng)前時(shí)間相差兩秒以內(nèi),那么從數(shù)據(jù)庫查出的這條數(shù)據(jù)我視為有效坑6:當(dāng)用戶刪除了截圖文件夾的時(shí)候,媒體庫此時(shí)會(huì)更新,所以此時(shí)onChange會(huì)收到大量回調(diào),所以這里需要判斷判斷文件是否存在??赡苡腥藭?huì)問,為什么不直接用第二種方法?原因有2,首先從坑5可以看出第二種方法也并非100%有效,其次,這種方法速度很慢,通常會(huì)有2-3秒的延遲。而第一種方法如果有效,通常都會(huì)比后者快很多。好了,障礙基本掃清,下面開始融合兩種方法首先使用成員變量記錄截圖文件路徑private
static
String
sScreenshotPath;當(dāng)方法1或者方法2收到結(jié)果時(shí),用收到的結(jié)果與sScreenshotPath對(duì)比,如果是同一個(gè)文件,那么就無需再次通知了,否則則進(jìn)行通知。邏輯太簡單,代碼就不寫了。但是實(shí)際情況是不會(huì)這么樂觀的???:在實(shí)踐中發(fā)現(xiàn),有的系統(tǒng)不直接保存截圖,而是先生成一個(gè)隱藏文件,比如叫.截圖.jpg,然后再修改文件名(去掉“.”)。這種情況下,我們可能就會(huì)收到兩次用戶截圖事件的回調(diào)(方法1和方法2都可能收到回調(diào)),但實(shí)際用戶只截了一次。這里我做了一個(gè)特殊處理,在判斷是否是同一個(gè)文件時(shí),只判斷文件名,而不去管文件的完整路徑也不管文件是否隱藏(也就是不比較文件名前面的“.”)//僅靠文件名而不是全路徑判斷是否為同一個(gè)截圖文件,因?yàn)橛行┫到y(tǒng)對(duì)截圖有move操作
private
static
boolean
isSameFile(String
newPath)
{
if
(TextUtils.isEmpty(sScreenshotPath))
{
return
false;
}
return
TextUtils.equals(removePrefixDot(new
File(sScreenshotPath).getName()),
removePrefixDot(new
File(newPath).getName()));
}
private
static
String
removePrefixDot(@NonNull
St
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版新型醫(yī)療設(shè)備研發(fā)與臨床試驗(yàn)合同3篇
- 二零二五年度醫(yī)療設(shè)備增壓泵供應(yīng)與售后服務(wù)合同3篇
- 二零二五年度工業(yè)用卷簾門采購與安全認(rèn)證合同2篇
- 二零二五年度商業(yè)地產(chǎn)租賃合同標(biāo)準(zhǔn)范本3篇
- 2024版餐飲企業(yè)財(cái)務(wù)咨詢服務(wù)合同
- 2025年度季度銷售獎(jiǎng)杯采購與銷售渠道合作協(xié)議3篇
- 二零二五年度危險(xiǎn)化學(xué)品安全使用指導(dǎo)協(xié)議3篇
- 二零二五年度國家級(jí)借調(diào)專家團(tuán)隊(duì)合作開發(fā)協(xié)議2篇
- 2025年外研版必修2地理下冊(cè)月考試卷含答案
- 無人化農(nóng)場(chǎng)項(xiàng)目評(píng)估報(bào)告
- 鐵路橋梁鋼結(jié)構(gòu)設(shè)計(jì)規(guī)范(TB100022--99)修訂簡介
- 照明公司個(gè)人工作總結(jié)范文
- 熱控專業(yè)施工質(zhì)量驗(yàn)收范圍劃分表
- 水文氣象報(bào)告
- 2022年sppb簡易體能狀況量表
- 錨桿、錨索框架梁施工方案
- 各類傳染病個(gè)案調(diào)查表集
- 全口義齒PPT課件
- 室內(nèi)裝飾裝修工程施工組織設(shè)計(jì)方案(完整版)
- 消防系統(tǒng)檢測(cè)方案(完整版)
- 關(guān)于童話故事的題目
評(píng)論
0/150
提交評(píng)論