最近在做项目时遇到需要处理SD卡拔出时的监听,在网上找了很多资料。总结了一下,
用接收广播处理最有效率
sd卡拔插时会发送广播,具体如下(摘自一位大虾的博客 来自:http://blog.csdn.net/giantgreen/article/details/41991291):
外部存储设备的状态变化时发出的广播
对比不同状态下的广播
1. 插入外部SD卡时:
2. 移除外部SD卡时:
3. 连接PC进入USB大容量存储模式时:
4. 连接PC退出USB大容量存储模式时:
代码实现监听
<strong> public void startListen()
{
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
intentFilter.setPriority( 1000 );
intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
intentFilter.addAction(Intent.ACTION_MEDIA_REMOVED);
intentFilter.addAction(Intent.ACTION_MEDIA_SHARED);
intentFilter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addAction(Intent.ACTION_MEDIA_CHECKING);
intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
intentFilter.addAction(Intent.ACTION_MEDIA_NOFS);
intentFilter.addAction(Intent.ACTION_MEDIA_BUTTON);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intentFilter.addDataScheme( "file" );
registerReceiver(broadcastRec, intentFilter);
}
private final BroadcastReceiver broadcastRec = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d( "MediaAction" , action);
if (action.equals( "android.intent.action.MEDIA_MOUNTED" ))
{
//todo
} else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED))
{
//todo
} else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)){
} else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)){
} else if (action.equals(Intent.ACTION_MEDIA_SHARED)){
} else {
}
}
}; </strong>
|
用接收广播处理SD卡拔插有两种情况:
1)整个程序都需要响应这一事件
在清单中注册静态广播
intentFilter.setPriority(1000);// 设置最高优先级
- <receiver android:name=".StaticBroadcastReceiver">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- <category android:name="android.intent.category.HOME" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.MEDIA_MOUNTED"/>
- <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="file" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
- <action android:name="android.intent.action.USER_PRESENT" />
- </intent-filter>
- </receiver>
- public class StaticBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // TODO Auto-generated method stub
- if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
- Log.d(TAG, "onReceive boot: ");
- Intent new_intent = new Intent(context,TestLauncher.class);
- //popup the activity
- new_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(new_intent);
- }else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
- Log.d(TAG, "onReceive ACTION_USER_PRESENT: ");
- }
- }
- }
2)只有某个activity需要响应:
在代码中注册动态广播
1.注册广播
[java] view plaincopy
- // 在IntentFilter中选择你要监听的行为
- IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);// sd卡被插入,且已经挂载
- intentFilter.setPriority(1000);// 设置最高优先级
- intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);// sd卡存在,但还没有挂载
- intentFilter.addAction(Intent.ACTION_MEDIA_REMOVED);// sd卡被移除
- intentFilter.addAction(Intent.ACTION_MEDIA_SHARED);// sd卡作为 USB大容量存储被共享,挂载被解除
- intentFilter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);// sd卡已经从sd卡插槽拔出,但是挂载点还没解除
- intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);// 开始扫描
- intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);// 扫描完成
- intentFilter.addDataScheme("file");
- registerReceiver(broadcastRec, intentFilter);// 注册监听函数
2.接收广播事件处理
[java] view plaincopy
- private final BroadcastReceiver broadcastRec = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals("android.intent.action.MEDIA_MOUNTED"))// SD
- // 卡已经成功挂载
- {
- imagepath = android.os.Environment.getExternalStorageDirectory();// 你的SD卡路径
- Toast.makeText(MyService.this, "我的卡已经成功挂载", 0).show();
- } else if (action.equals("android.intent.action.MEDIA_REMOVED")// 各种未挂载状态
- || action.equals("android.intent.action.ACTION_MEDIA_UNMOUNTED")
- || action.equals("android.intent.action.ACTION_MEDIA_BAD_REMOVAL")) {
- imagepath = android.os.Environment.getDataDirectory();// 你的本地路径
- Toast.makeText(MyService.this, "我的各种未挂载状态", 0).show();
- }else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)){//开始扫描
- Toast.makeText(MyService.this, "开始扫描...", 0).show();
- }else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)){//扫描完成
- Toast.makeText(MyService.this, "扫描完成...", 0).show();
- }else if (action.equals(Intent.ACTION_MEDIA_SHARED)){//扩展介质的挂载被解除 (unmount)。因为它已经作为 USB 大容量存储被共享
- Toast.makeText(MyService.this, " USB 大容量存储被共享...", 0).show();
- }else {
- Toast.makeText(MyService.this, "其他状态...", 0).show();
- }
- Log.i(TAG, "imagepath---" + imagepath);
- }
- };
3.取消注册
[java] view plaincopy
- unregisterReceiver(broadcastRec);//取消注册
4.需要在AndroidManifest.xml中添加操作SDCard的权限
1.<!-- 在SDCard中创建与删除文件权限 -->
2. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
3. <!-- 往SDCard写入数据权限 -->
4.<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />