Android 启用/禁用通过otg连接T卡功能

博客内容涉及修复Android系统中关于OTG功能的启用/禁用问题,以及在启用或禁用前后如何正确地挂载或卸载SD卡。通过修改`UsbHostManager`类,添加对用户限制的检查,并实现了在启用OTG前先挂载SD卡,在禁用后卸载SD卡的逻辑,以避免错误。同时,文章还展示了错误处理和日志打印,以及错误发生时的代码定位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.调用方法:

private String setSDOTGEnable(boolean enable) {
    if (enable)
		mDPM.clearUserRestriction(admin, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
	else
		mDPM.addUserRestriction(admin, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);	
}

2.在【mt67xx_11.0】上调用以上方法并不能控制到ES文件浏览器识别SD卡,增加以下控制:

--- a/alps/frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/alps/frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -50,6 +50,10 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedList;
+//add for setSDOTGEnable
+import android.os.UserHandle;
+import android.os.UserManager;
+//add end
 
 /**
  * UsbHostManager manages USB state in host mode.
@@ -353,6 +357,13 @@ public class UsbHostManager {
     @SuppressWarnings("unused")
     private boolean usbDeviceAdded(String deviceAddress, int deviceClass, int deviceSubclass,
             byte[] descriptors) {
+        //add by lfy for setSDOTGEnable
+        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        boolean flag = um.hasUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
 UserHandle.of(um.getUserHandle()));
+        if (flag) {
+            return false;
+        }
+        //add end
         if (DEBUG) {

以上方法实现的启用/禁用otg功能在使用过程中需要在调接口前先插拔otg设备,完善缺陷修改如下:
1.在禁用前先unmount已挂载的设备&在启用后mount已插入的设备,顺序不能乱

if(!enable){
	unmountSD(!enable);   //禁用前先unmount已挂载的设备
	mDPM.addUserRestriction(admin, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
}else{
	mDPM.clearUserRestriction(admin, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
	unmountSD(!enable);  //在启用后mount已插入的设备
}

private void unmountSD(boolean disabled) {
	try {   //一定要有try...catch
	    android.util.Log.d("lfy","mountUnmountSD......");
	    StorageManager mStorageManager = mContext.getSystemService(StorageManager.class);
	    StorageVolume[] volumeList = mStorageManager.getVolumeList();
	    if (volumeList.length > 0) {
	    	for (StorageVolume vol : volumeList) {
		    	android.util.Log.d(TAG," mountUnmountSD...vol="+vol+",getId="+vol.getId()+",path="+vol.getPath()+",InternalPath="+vol.getInternalPath()+",filePath="+vol.getPathFile().getPath()+",getDescription="+vol.getDescription(mContext));
				if (disabled) {
					if (!"/storage/emulated/0".equals(vol.getPath()) && "mounted".equals(vol.getState())) {
						mStorageManager.unmount(vol.getId());
					}
                }else{
                    if (!"/storage/emulated/0".equals(vol.getPath()) && "unmounted".equals(vol.getState())) {
						mStorageManager.mount(vol.getId());
					}
                }
		    }
	    }
	} catch(Exception e){
		android.util.Log.d("lfy","[FuncTools] mountUnmountSD...e="+e);
       e.printStackTrace();
    }
}

2.打印log
在这里插入图片描述

3.如果unmountSD顺序调用错误(统一在enable判断前调用会报如下错误)
在这里插入图片描述
4.报错信息具体出处:

//frameworks/base/services/core/java/com/android/server/StorageManagerService.java
@Override
 public void mount(String volId) {
     enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);

     final VolumeInfo vol = findVolumeByIdOrThrow(volId);
     if (isMountDisallowed(vol)) {   //决定存储是否能挂载的关键
         throw new SecurityException("Mounting " + volId + " restricted by policy");
     }

     mount(vol);
 }

/**
 * Decide if volume is mountable per device policies.
 */
private boolean isMountDisallowed(VolumeInfo vol) {
    UserManager userManager = mContext.getSystemService(UserManager.class);

    boolean isUsbRestricted = false;
    if (vol.disk != null && vol.disk.isUsb()) {
        isUsbRestricted = userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER,
                Binder.getCallingUserHandle());
    }

    boolean isTypeRestricted = false;
    if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE
            || vol.type == VolumeInfo.TYPE_STUB) {
        isTypeRestricted = userManager
                .hasUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
                Binder.getCallingUserHandle());
    }

    return isUsbRestricted || isTypeRestricted;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值