在Anrdoid L的版本上,如果用户USB连接PC设备后,选择MTP模式,然后移除连接,再次重新连接之后,设备还是以MTP模式连接的。而在Android N上,如果用户按照相同的操作,设备却是以充电模式连接的,这是为什么呢?如果更改才能回到以前的逻辑呢?
private static final String USB_STATE_MATCH = "DEVPATH=/devices/virtual/android_usb/android0";
private final UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString());
String state = event.get("USB_STATE");
String accessory = event.get("ACCESSORY");
if (state != null) {
mHandler.updateState(state);
} else if ("START".equals(accessory)) {
if (DEBUG) Slog.d(TAG, "got accessory start");
startAccessoryMode();
}
}
};
mUEventObserver.startObserving(USB_STATE_MATCH);
首先UsbDeviceManager中注册了UEvent接收内核中USB拔插的消息,收到消息后会调用mHandler.updateState(state);
可以看出当拔出USB时,会更新mConnected的值,最终如果值为false的话会调用public void updateState(String state) { int connected, configured; if ("DISCONNECTED".equals(state)) { connected = 0; configured = 0; } else if ("CONNECTED".equals(state)) { connected = 1; configured = 0; } else if ("CONFIGURED".equals(state)) { connected = 1; configured = 1; } else { Slog.e(TAG, "unknown state " + state); return; } removeMessages(MSG_UPDATE_STATE); Message msg = Message.obtain(this, MSG_UPDATE_STATE); msg.arg1 = connected; msg.arg2 = configured; // debounce disconnects to avoid problems bringing up USB tethering sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0); } case MSG_UPDATE_STATE: mConnected = (msg.arg1 == 1); mConfigured = (msg.arg2 == 1); if (!mConnected) { // When a disconnect occurs, relock access to sensitive user data mUsbDataUnlocked = false; } updateUsbNotification(); updateAdbNotification(); if (UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) { updateCurrentAccessory(); } else if (!mConnected) { // restore defaults when USB is disconnected setEnabledFunctions(null, false);//设置usb功能为空,也就是充电模式 } if (mBootCompleted) { updateUsbStateBroadcastIfNeeded(); updateUsbFunctions(); } break;
那要想改这块的逻辑,是不是把这段代码注释了就可以了?我试了,是不行的,虽然persist.sys.usb.config和sys.usb.config的值是mtp,adb,但是实际mtp功能是不能用的,到底为什么呢?答案在下面的代码:setEnabledFunctions(null, false);//设置usb功能为空,也就是充电模式
if (!mConnected) { // When a disconnect occurs, relock access to sensitive user data mUsbDataUnlocked = false; }
private void updateUsbStateBroadcastIfNeeded() { // send a sticky broadcast containing current USB state Intent intent = new Intent(UsbManager.ACTION_USB_STATE); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(UsbManager.USB_CONNECTED, mConnected); intent.putExtra(UsbManager.USB_HOST_CONNECTED, mHostConnected); intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked);//奥秘就在这里 if (mCurrentFunctions != null) { String[] functions = mCurrentFunctions.split(","); for (int i = 0; i < functions.length; i++) { final String function = functions[i]; if (UsbManager.USB_FUNCTION_NONE.equals(function)) { continue; } intent.putExtra(function, true); } } // send broadcast intent only if the USB state has changed if (!isUsbStateChanged(intent)) { if (DEBUG) { Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras()); } return; } if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras()); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); mBroadcastedIntent = intent; }
把这段代码里面的mUsbDataUnlocked改为true就可以达到Android L的效果。具体为什么,我没有去看。intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked);//奥秘就在这里