一、 热插拔sd卡
1. 直接拔掉sdcard
BroadcastReceiver.android.intent.action.MEDIA_UNMOUNTED
BroadcastReceiver.android.intent.action.MEDIA_BAD_REMOVAL
BroadcastReceiver.android.intent.action.MEDIA_EJECT
BroadcastReceiver.android.intent.action.MEDIA_SCANNER_STARTED
BroadcastReceiver.android.intent.action.MEDIA_SCANNER_FINISHED
2. 再次插入sd卡
BroadcastReceiver.android.intent.action.MEDIA_CHECKING
BroadcastReceiver.android.intent.action.MEDIA_MOUNTED
BroadcastReceiver.android.intent.action.MEDIA_SCANNER_STARTED
BroadcastReceiver.android.intent.action.MEDIA_SCANNER_FINISHED
3. 在通知栏卸载sdcard
BroadcastReceiver.android.intent.action.MEDIA_EJECT
BroadcastReceiver.android.intent.action.MEDIA_UNMOUNTED
注意:接收到 ACTION_MEDIA_EJECT 广播之后,sd 卡还是可以读写的,
直到接收到 ACTION_MEDIA_REMOVED、ACTION_MEDIA_UNMOUNTED等广播之后,sd 卡才不可以读写。
二、 Sd卡示例
1. 获取sd卡路径
public static String getSDPath(Context context) {
String sd = null;
StorageManager storageManager = (StorageManager) context
.getSystemService(Context.STORAGE_SERVICE);
StorageVolume[] volumes = storageManager.getVolumeList();
for (int i = 0; i < volumes.length; i++) {
if (volumes.isRemovable()&& volumes.allowMassStorage()
&& volumes.getDescription(context).contains("SD")) {
sd = volumes.getPath();
}
}
return sd;
}
2. 编写广播接收器
public void registerReceivers(){
if(mReceiver == null){
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i("usb", "BroadcastReceiver."+ intent.getAction());
String action = intent.getAction();
if(action.equals("android.intent.action.MEDIA_CHECKING")){
Toast.makeText(context, "sdcard MEDIA_CHECKING",0).show();
//updateListMounted();01-01 09:20:41.663: I/usb(14544):path:/storage/emulated/0
/*String path = getSDPath(context);
Log.i("liting","path = " + path);
MediaScannerConnection.scanFile(context,
newString[]{path + "/DICM"},
null,null);
updateListMounted();*/
ad.start();
loading_layout.setVisibility(View.VISIBLE);
list_layout.setVisibility(View.INVISIBLE);
loading_text.setVisibility(View.VISIBLE);
}else if(action.equals("android.intent.action.MEDIA_SCANNER_FINISHED")){
Toast.makeText(context, "sdcard MEDIA_SCANNER_FINISHED", 0).show();
if(ad.isRunning()){
ad.stop();
loading_layout.setVisibility(View.INVISIBLE);
list_layout.setVisibility(View.VISIBLE);
loading_text.setVisibility(View.INVISIBLE);
}
}else if(action.equals("android.intent.action.ACTION_MEDIA_UNMOUNTED")){
Toast.makeText(context, "sdcard ACTION_MEDIA_UNMOUNTED", 0).show();
if(ad.isRunning()){
ad.stop();
loading_layout.setVisibility(View.INVISIBLE);
}
}
}
};
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);
filter.addAction(Intent.ACTION_MEDIA_BUTTON);
filter.addAction(Intent.ACTION_MEDIA_CHECKING);
filter.addAction(Intent.ACTION_MEDIA_EJECT);
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_NOFS);
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
filter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
filter.addAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
filter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTABLE);
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
filter.addAction(Intent.ACTION_MEDIA_SHARED);
filter.addDataScheme("file");
registerReceiver(mReceiver, filter);
}
}
3. 注册/取消注册广播监听器
四、 媒体数据库刷新
1. 手动扫描刷新
当android的系统启动的时候,系统会自动扫描sdcard内的文件,并把获得的媒体文件信息保存在一个系统媒体数据库中,程序想要访问多媒体文件,就可以直接访问媒体数据库中即可,而用直接去sdcard中取。但是,如果系统在不重新启动情况下,媒体数据库信息是不会更新的,这里举个例子,当应用程序保存一张图片到本地后(已成功),但打开系统图片库查看时候,你会发现图片库内并没有你刚刚保存的那张图片,原因就在于系统媒体库没有及时更新,这时就需要手动刷新文件系统了。
2. 自动刷新
在后视镜的视频回放中,热插拔sd卡,当插上sd卡时,sd卡会扫描好久的数据库。通过log分析,在MEDIA_SCANNER_STARTED到MEDIA_SCANNER_FINISHED之间花费了太久的时间。如此提高系统扫描的速度呢?
\packages\providers\MediaProvider\src\com\android\providers\media\MediaScannerService.java
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND+
Process.THREAD_PRIORITY_LESS_FAVORABLE);将值降低