原文:http://blog.csdn.net/muojie/article/details/8315666
“USB连接方式”设置界面
选择MTP,PTP,UMS的选项界面就定义在UsbSettings.java,选择其中一个选项时会执行以下代码。
packages/apps/Settings/src/com/android/settings/deviceinfo/UsbSettings.java
if(preference == mMtp) {
mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MTP, true);
updateToggles(UsbManager.USB_FUNCTION_MTP);
} elseif(preference == mPtp) {
mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_PTP, true);
updateToggles(UsbManager.USB_FUNCTION_PTP);
} elseif(preference == mUms) {
mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MASS_STORAGE, true);
updateToggles(UsbManager.USB_FUNCTION_MASS_STORAGE);
}
updateToggle就是去让执行某些选项的选中与取消工作。
其中最重要的是mUsbManager.setCurrentFunction(),mUsbManger是这样得到的:
@Override
publicvoidonCreate(Bundle icicle) {
super.onCreate(icicle);
mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
}
它的实现在frameworks/base/core/java/android/hardware/usb/UsbManager.java。
它的接口实现在frameworks/base/core/java/android/hardware/usb/IUsbManager.aidl
frameworks/base/services/java/com/android/server/usb/UsbService.java
publicclassUsbServiceextendsIUsbManager.Stub {
privatefinalContext mContext;
privateUsbDeviceManager mDeviceManager;
privateUsbHostManager mHostManager;
privatefinalUsbSettingsManager mSettingsManager;
这个界面就是"com.android.settings.UsbSettings"
Activity。在frameworks/base/services/java/com/android/server/usb/UsbDeviceManager.java中被调用。
如果你选择了USB调试功能,还会弹出"com.android.settings.DevelopmentSettings"
Activity,也是在UsbDeviceManager.java中被调用。关于UsbDevcieManager,我们以后再细看。
如果你选择了UMS,还会弹出"com.android.systemui.usb.UsbStorageActivity"
Activity,就是“打开USB存储设备”的界面。它就义在定义在:
frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java。
这些界面只有在插入USB时才会有通知显示。在没有插USB的情况下,有些界面是没有入口的。我们就以UsbStorageActivity为例,介绍一下这些通知是怎么弹出来的。
通知是怎么弹出来的
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
// storage
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
mStorageManager.registerListener(
newcom.android.systemui.usb.StorageNotification(context));
这里注册了监听函数com.android.systemui.usb.StorageNotification,这个只是针对Phone,对于平板,有tablet/TabletStatusBarPolicy.java
我们来看一下注册的com.android.systemui.usb.StorageNotification
frameworks/base/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
publicclassStorageNotificationextendsStorageEventListener {
privatestaticfinalString TAG ="StorageNotification";
publicStorageNotification(Context context) {
mContext = context;
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
finalbooleanconnected = mStorageManager.isUsbMassStorageConnected();
Slog.d(TAG, String.format( "Startup with UMS connection %s (media state %s)", mUmsAvailable,
Environment.getExternalStorageState()));
HandlerThread thr = newHandlerThread("SystemUI StorageNotification");
thr.start();
mAsyncEventHandler = newHandler(thr.getLooper());
onUsbMassStorageConnectionChanged(connected);
}
在构造函数里就调用了onUsbMassStorageConnectionChanged函数,它最终会调到updateUsbMassStorageNotification(),
voidupdateUsbMassStorageNotification(booleanavailable) {
if(available) {
Intent intent = newIntent();
intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent,0);
setUsbStorageNotification(
com.android.internal.R.string.usb_storage_notification_title,
com.android.internal.R.string.usb_storage_notification_message,
com.android.internal.R.drawable.stat_sys_data_usb,
false,true, pi);
} else{
setUsbStorageNotification(0,0,0,false,false,null);
}
}
也就是说UsbStorageActivity和StorageNotification绑定在了一起,什么时候弹出这个通知,就可以进入这个Activity了。
如果连接了USB,就会在通知栏里显示USB选项的通知。如果没有连接,就会把这个通知给取消掉。那我们看一下,这个通知是怎么弹出来的。
StorageManager
frameworks/base/core/java/android/os/storage/StorageManager.java
publicvoidregisterListener(StorageEventListener listener) {
if(listener ==null) {
return;
}
synchronized(mListeners) {
mListeners.add(newListenerDelegate(listener));
}
}
mListeners会被私有成员MountServiceBinderListener用到,而MountServiceBinderListener又是继承自IMountServiceListener.Stub,在构造函数里被注册。
publicStorageManager(Looper tgtLooper)throwsRemoteException {
mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
if(mMountService ==null) {
Log.e(TAG, "Unable to connect to mount service! - is it running yet?");
return;
}
mTgtLooper = tgtLooper;
mBinderListener = newMountServiceBinderListener();
mMountService.registerListener(mBinderListener);
}
所以关键还是在mMountService。