现在有个需求:u盘里面有一个工厂apk,u盘插入android设备后客制化的sdmc apk会接收到ACTION_MEDIA_MOUNTED广播后使用pm.getPackageArchiveInfo(absPath, PackageManager.GET_ACTIVITIES)去获取u盘里面的工厂apk信息,在这个时候突然把u盘拔掉,在系接收到ACTION_MEDIA_EJECT或者ACTION_MEDIA_UNMOUNTED广播后,可以做哪些处理使得U盘可以成功卸载,不会再下次插入的时候系统提示“vold : ForceUnmount failed: Device or resource busy” 请通过代码来实现
时间: 2024-02-18 08:59:24 浏览: 129
好的,以下是一个示例代码,用于在接收到ACTION_MEDIA_EJECT或ACTION_MEDIA_UNMOUNTED广播后,停止使用U盘的进程和服务,并卸载U盘:
```java
private static final String USB_STORAGE_PATH = "/mnt/usb_storage"; // U盘挂载路径
private BroadcastReceiver mUsbStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == null) {
return;
}
if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {
// U盘插入,获取工厂apk信息
String path = intent.getData().getPath();
if (USB_STORAGE_PATH.equals(path)) {
PackageInfo packageInfo = getPackageInfoFromUsb();
// TODO: 处理工厂apk信息
}
} else if (Intent.ACTION_MEDIA_EJECT.equals(action)
|| Intent.ACTION_MEDIA_UNMOUNTED.equals(action)) {
// U盘卸载,停止使用U盘的进程和服务,并卸载U盘
String path = intent.getData().getPath();
if (USB_STORAGE_PATH.equals(path)) {
stopUsingUsb();
unmountUsb();
}
}
}
};
// 获取U盘中的工厂apk信息
private PackageInfo getPackageInfoFromUsb() {
String apkPath = USB_STORAGE_PATH + "/factory.apk";
PackageManager pm = getPackageManager();
PackageInfo packageInfo = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
return packageInfo;
}
// 停止使用U盘的进程和服务
private void stopUsingUsb() {
// TODO: 停止使用U盘的进程和服务
}
// 卸载U盘
private void unmountUsb() {
try {
Process process = Runtime.getRuntime().exec("su");
OutputStream os = process.getOutputStream();
os.write(("umount " + USB_STORAGE_PATH + "\n").getBytes("UTF-8"));
os.write(("am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///mnt/sdcard\n").getBytes("UTF-8"));
os.flush();
os.close();
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
```
需要注意的是,上述代码需要在具有root权限的设备上运行。如果设备没有root权限,则需要在接收到广播后,提示用户手动卸载U盘。
阅读全文