寫這篇文章是因?yàn)檫@個(gè)坑,耗費(fèi)了我三天時(shí)間,甚至懷疑過(guò)人家一個(gè)大牛作者寫的圖片選擇庫(kù)(罪過(guò)。。。),
? ? 本人在項(xiàng)目中使用了PictureSelector這個(gè)圖片、視頻、錄音的庫(kù)(非常棒的第三方工具,就是作者不經(jīng)常在群里回答問(wèn)題。。。),這個(gè)庫(kù)中可以根據(jù)用戶需求,設(shè)置拍攝完文件的保存路徑(音頻文件作者沒(méi)有設(shè)置保存路徑,是直接保存在系統(tǒng)默認(rèn)的文件夾下),還有其他很多的自定義設(shè)置,如下:

? ? ?引用第三方是節(jié)省了很多時(shí)間,同時(shí)也幫助也很多小白(向我一樣的~哈哈),但是有一點(diǎn)不好,就是不懂他的原理,下面進(jìn)入正題
? ? 我的項(xiàng)目是倆個(gè)人一起開(kāi)發(fā)的通過(guò)svn提交合并,項(xiàng)目中有需要圖片、視頻、音頻拍攝和選擇本地的倆個(gè)同能,所以我選擇了上面這個(gè)第三方的庫(kù),但是我同事那邊的需求是只進(jìn)行拍攝錄音的功能不需要選擇本地,只需要查看固定文件夾下是否存在這個(gè)三中文件,并顯示出來(lái)的功能,所以他選擇了自定義拍攝圖片 視頻 和錄音,但這就導(dǎo)致了保存的文件,最后沒(méi)有經(jīng)過(guò)媒體庫(kù)掃描,我那邊在獲取本地文件的時(shí)候,無(wú)法獲取到他拍攝的文件,這就尷尬了。。。
? ? 開(kāi)始以為庫(kù)有問(wèn)題,引文直接打開(kāi)文件夾下面是由相應(yīng)的文件的,但是第三方庫(kù)獲取不到,不得已查了很多資料沒(méi)有找到,左后一個(gè)網(wǎng)友的提示才發(fā)現(xiàn)是因?yàn)楸4娴奈募唤?jīng)過(guò)媒體庫(kù)掃描,是無(wú)法查看到的,于是網(wǎng)上查了一番找到了解決方法 如下:
? ? 通知相冊(cè)更新:
//通知相冊(cè)更新
MediaStore.Images.Media.insertImage(getContentResolver(), BitmapFactory.decodeFile(file.getAbsolutePath()), file.getName(), null);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
sendBroadcast(intent);
? ? 但是這個(gè)只是更新相冊(cè)的,很尷尬的是我還需要視頻和錄音的都掃描,于是找到了下面這四種方式:
1.發(fā)送通知給系統(tǒng),進(jìn)行全盤掃描:
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
代碼很簡(jiǎn)單,就這么一行代碼,該方法對(duì)于android4.4以前的版本是試用的,但是因?yàn)橄到y(tǒng)進(jìn)行全盤掃描特別耗費(fèi)電量等,所以android4.4之后,系統(tǒng)就禁止自己的應(yīng)用去發(fā)送此廣播了。android4.4之后想要全盤掃描,除非您具有系統(tǒng)權(quán)限。
2.通知系統(tǒng)去掃描具體的文件,這種掃面又包括三種方法:
1>和通知系統(tǒng)全盤掃描的方法一樣,我們可以通知系統(tǒng)進(jìn)行某個(gè)文件的掃描:
public void fileScan(String file) {
Uri data = Uri.parse("file://" + file);
Log.d("TAG", "file:" + file);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, data));
}
通過(guò)此方法,傳入要掃描的具體的路徑,就可以進(jìn)行掃描具體的文件了
假如你要掃描具體的文件夾的話,我現(xiàn)在還沒(méi)有發(fā)現(xiàn)好的方法,我所總結(jié)的就是迭代的方法,因?yàn)樵诖朔椒ㄖ屑词鼓銈魅胛募A的名字,他也不會(huì)掃描
/**
* 迭代掃描文件夾
*?
* @param path
*/
public void folderScan(String path) {
File file = new File(path);
if (file.isDirectory()) {
File[] array = file.listFiles();
for (int i = 0; i < array.length; i++) {
File f = array[i];
if (f.isFile()) {// FILE TYPE
String name = f.getName();
// if(name.contains(".mp3")){
fileScan(f.getAbsolutePath());
// }
} else {// FOLDER TYPE
folderScan(f.getAbsolutePath());
}
}
}
}
2>可以跨進(jìn)程調(diào)用系統(tǒng)的服務(wù)來(lái)完成掃描
MediaScannerConnection connection;
MediaScannerConnectionClient client = new MediaScannerConnectionClient() {
\\當(dāng)掃描完成后執(zhí)行此方法
@Override
public void onScanCompleted(final String path, Uri uri) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "onScanCompleted: " + path, 1).show();
imageCount = imageCount-1;
if (imageCount == 0) {
pictureSelect();
}
}
});
}
@Override
public void onMediaScannerConnected() {
runOnUiThread(new Runnable() {
public void run() {
// Toast.makeText(getApplicationContext(), "onMediaScannerConnected", 1).show();
}
});
}
};
//可以在oncreate方法中進(jìn)行連接
connection = new MediaScannerConnection(getApplicationContext(), client);
connection.connect();
然后就可以在具體需要掃描的地方進(jìn)行掃描了,傳入的是要掃描的文件路徑
public void scanFile(String fileName) {
connection.scanFile(fileName, null);
}
3>最后一種方法是調(diào)用系統(tǒng)的api進(jìn)行掃描
public void scanFile(String fileName) {
MediaScannerConnection.scanFile(this, new String[] { fileName },
null, new OnScanCompletedListener() {
?public void onScanCompleted(String path, Uri uri) {
Toast.makeText(getApplicationContext(), "onScanCompleted", 1).show();
?Log.i("ygs", "onScanCompleted");
}
?});
}
上面四種個(gè)人建議使用第一種,這樣省區(qū)很多麻煩,當(dāng)你的文件夾下面有非常多的文件時(shí),其他方法會(huì)導(dǎo)致長(zhǎng)程序卡頓,甚至死機(jī)的問(wèn)題,以上就是個(gè)人的這次經(jīng)驗(yàn)。
? ? 順便說(shuō)一下,使用PictureSelector庫(kù)時(shí),當(dāng)錄音文件需要自定義路徑時(shí),可以將錄制的文件拷貝到指定文件夾并刪除丟源文件,注意一點(diǎn)要把拷貝好的文件經(jīng)過(guò)媒體掃描一下才能顯示出來(lái)啊,
附上倆位作者的連接: