對Android稍有熟悉的人都知道,Android Media Scanner只對SD卡上的媒體文件進(jìn)行掃描。其掃描的策略,請參考《Android Media Scanner Process》。假如我們的硬件平臺上面沒(méi)有提供SD卡槽,難道Android就不能進(jìn)行對媒體文件播放了嗎?當然不是的,否則Android系統將不會(huì )成為一個(gè)完善的Framework。本文結合本人的經(jīng)驗介紹一下,怎樣修改多媒體文件的掃描路徑。
根據《Android Media Scanner Process》的介紹我們可以知道,Android scanner掃描媒體完成之后,會(huì )把媒體文件存放在數據庫中,由MediaProvider為上層的應用程序提供服務(wù)。
經(jīng)過(guò)研究Media scanner的代碼發(fā)現,他的掃描路徑為android.os.Environment.EXTERNAL_STORAGE_DIRECTORY。定義該變量文件位于:
frameworks/base/core/java/android/os/Environment.java
默認情況下,Android將會(huì )搜索/sddisk目錄:
private static final File EXTERNAL_STORAGE_DIRECTORY = getDirectory("EXTERNAL_STORAGE", "/sddisk");
為了讓其進(jìn)行搜索我們自定義的路徑,可以修改該變量的定義,加入我們希望掃描/external目錄。代碼修改如下:
private static final File EXTERNAL_STORAGE_DIRECTORY = getDirectory("EXTERNAL_STORAGE", "/external");
這樣Android Media Scanner將會(huì )搜索/external目錄來(lái)查找媒體文件。
下一步我們需要保證這個(gè)文件一定要存在,我們需要修改init.rc文件。增加如下的定義:
mkdir /external 0777 system system
這樣在開(kāi)機的時(shí)候,如果/external目錄不存在,則會(huì )創(chuàng )建一個(gè)。如果已經(jīng)存在,則不會(huì )有任何動(dòng)作。
另外怎樣觸發(fā)Media Scanner?根據《Android Media Scanner Process》的介紹,當收到ACTION_BOOT_COMPLETED,ACTION_MEDIA_MOUNTED,ACTION_MEDIA_SCANNER_SCAN_FILE消息的時(shí)候才會(huì )進(jìn)行掃描。以前是掃描SD卡,當SD卡mount的時(shí)候Android系統會(huì )有ACTION_MEDIA_MOUNTED消息通知,Media Scanner開(kāi)始掃描媒體文件。但是我們的/external目錄修改之后,怎樣通知Android media scanner掃描呢?一個(gè)辦法是重啟,沒(méi)有人樂(lè )意這樣做。另外一個(gè)辦法是運行menu->dev tools->Media Scan,這樣將會(huì )進(jìn)行掃描。目前我還沒(méi)有讓目錄修改之后,自動(dòng)掃描的辦法。如果你有好的點(diǎn)子,請你給我留言。
通過(guò)以上的步驟,可以在A(yíng)ndroid的/external目錄存放媒體文件,并且被music應用程序播放了。當然還有不完善的地方歡迎各位朋友指正。
補充(于2010-9-20)
研究為什么Android系統會(huì )自動(dòng)調用MediaScaner掃描文件呢?研究MediaScannerReceiver的源碼發(fā)現:
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Uri uri = intent.getData(); String externalStoragePath = Environment.getExternalStorageDirectory().getPath(); if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { // scan internal storage scan(context, MediaProvider.INTERNAL_VOLUME); } else { if (uri.getScheme().equals("file")) { // handle intents related to external storage String path = uri.getPath(); if (action.equals(Intent.ACTION_MEDIA_MOUNTED) && externalStoragePath.equals(path)) { scan(context, MediaProvider.EXTERNAL_VOLUME); } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) && path != null && path.startsWith(externalStoragePath + "/")) { scanFile(context, path); } } } }
我們發(fā)現在收到ACTION_BOOT_COMPLETED消息時(shí),Android系統會(huì )掃描內存中的媒體文件。當系統收到ACTION_MEDIA_MOUNTED才會(huì )去掃描系統中的擴展內存(一般是SD卡)。
假如系統中有SD卡的話(huà),系統啟動(dòng)的時(shí)候是可以收到ACTION_MEDIA_MOUNTED消息和ACTION_BOOT_COMPLETED消息的,這樣開(kāi)機的時(shí)候系統會(huì )對系統進(jìn)行媒體文件掃描。當SD卡文件修改了(比如用數據線(xiàn),連接PC),一般也是有ACTION_MEDIA_MOUNTED消息上報的。這樣也可以實(shí)時(shí)更新媒體數據。
但是我們上面沒(méi)有真正的SD卡,而是把一個(gè)內存中的目錄設定為擴展內存。那么我們將永遠不會(huì )受到ACTION_MEDIA_MOUNTED消息,所以也不會(huì )自動(dòng)掃描外存儲內存中的媒體文件。那么你可能會(huì )問(wèn):為什么運行menu->dev tools->Media Scan就可以?huà)呙柰獯鎯却嬷械臄祿??這段代碼的實(shí)現,在文件Development\src\com\android\development\MediaScannerActivity.java中:
@Override public void onResume() { super.onResume(); ........ sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); ........ }
可以看出這里面廣播了一個(gè)ACTION_MEDIA_MOUNTED消息,這樣MediaScannerReceiver將會(huì )掃描外存儲內存中的媒體文件。
聯(lián)系客服