您的位置:首页 > 移动开发 > Android开发

Android N 插拔USB行为分析

2018-01-20 10:11 441 查看
        在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);

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;        可以看出当拔出USB时,会更新mConnected的值,最终如果值为false的话会调用
setEnabledFunctions(null, false);//设置usb功能为空,也就是充电模式        那要想改这块的逻辑,是不是把这段代码注释了就可以了?我试了,是不行的,虽然persist.sys.usb.config和sys.usb.config的值是mtp,adb,但是实际mtp功能是不能用的,到底为什么呢?答案在下面的代码:
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;
}
intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked);//奥秘就在这里
        把这段代码里面的mUsbDataUnlocked改为true就可以达到Android L的效果。具体为什么,我没有去看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: