usb状态相关处理

本文详细解析了Android系统中SD卡状态变化及USB连接状态的通知机制。包括如何在状态栏显示SD卡插入状态通知,以及USB连接调试时的通知实现。重点介绍了通过StorageManager和MountService监听SD卡状态变化的过程,以及USBService如何监听USB状态。

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

关于Usb的检测,相关联的和sdcard一起研究。

在状态栏如何进行显示Sd卡插入状态的NotificationUsbDebugging时的Notification的?

先来看Sd卡的Notification显示:

StatusBarPolicy.javaStatusBarPolicy类的构造函数中,有这样关于Sd卡的状态监听机制:

//storage

mStorageManager=(StorageManager)context.getSystemService(Context.STORAGE_SERVICE);

mStorageManager.registerListener(

newcom.android.systemui.usb.StorageNotification(context));

进入StorageManager.javaregisterListener去查看是怎样监听的:

publicvoidregisterListener(StorageEventListenerlistener){

if(listener==null){

return;

}

synchronized(mListeners){

mListeners.add(newListenerDelegate(listener));

}

}

可见所谓注册过程就是将监听类添加到监听的List表中,那么,在这个表中如何监听的?

查看ListenerDelegate

ListenerDelegate(StorageEventListenerlistener){

mStorageEventListener=listener;

mHandler=newHandler(mTgtLooper){

@Override

publicvoidhandleMessage(Messagemsg){

StorageEvente=(StorageEvent)msg.obj;

if(msg.what==StorageEvent.EVENT_UMS_CONNECTION_CHANGED){

UmsConnectionChangedStorageEventev=(UmsConnectionChangedStorageEvent)e;

mStorageEventListener.onUsbMassStorageConnectionChanged(ev.available);

}elseif(msg.what==StorageEvent.EVENT_STORAGE_STATE_CHANGED){

StorageStateChangedStorageEventev=(StorageStateChangedStorageEvent)e;

mStorageEventListener.onStorageStateChanged(ev.path,ev.oldState,ev.newState);

}else{

Log.e(TAG,"Unsupportedevent"+msg.what);

}

}

};

}

实际上就是开启一个无线循环的Handler等待消息的传送过来,到这一步自然就会想到是谁发送消息?

先插卡StorageManager类的构造函数:

publicStorageManager(LoopertgtLooper)throwsRemoteException{

mMountService=IMountService.Stub.asInterface(ServiceManager.getService("mount"));

if(mMountService==null){

Log.e(TAG,"Unabletoconnecttomountservice!-isitrunningyet?");

return;

}

mTgtLooper=tgtLooper;

mBinderListener=newMountServiceBinderListener();

mMountService.registerListener(mBinderListener);

}

在开启StorageManager的时候实际上就开启一个MountService,将MountServiceBinderListener注册为监听类:

它的作用是这样的:

privateclassMountServiceBinderListenerextendsIMountServiceListener.Stub{

publicvoidonUsbMassStorageConnectionChanged(booleanavailable){

finalintsize=mListeners.size();

for(inti=0;i<size;i++){

mListeners.get(i).sendShareAvailabilityChanged(available);

}

}

publicvoidonStorageStateChanged(Stringpath,StringoldState,StringnewState){

finalintsize=mListeners.size();

for(inti=0;i<size;i++){

mListeners.get(i).sendStorageStateChanged(path,oldState,newState);

}

}

}

也就是实际发送StorageEvent.EVENT_UMS_CONNECTION_CHANGED或者另外的消息:

EVENT_STORAGE_STATE_CHANGED。

那么这个监听类如何知道状态变化的?

MountService.java中,

publicvoidregisterListener(IMountServiceListenerlistener){

synchronized(mListeners){

MountServiceBinderListenerbl=newMountServiceBinderListener(listener);

try{

listener.asBinder().linkToDeath(bl,0);

mListeners.add(bl);

}catch(RemoteExceptionrex){

Slog.e(TAG,"Failedtolinktolistenerdeath");

}

}

}

MountService中有一个可供守护进程调用的函数:

publicbooleanonEvent(intcode,Stringraw,String[]cooked),它在有关状态发生变化时会调用相关函数,比如VolumeStateChange时,notifyShareAvailabilityChange(),而在notifyShareAvailabilityChange()中会更新:

updatePublicVolumeState(),在这里我们看到实际就是通过Environment中相关函数判断Sd卡状态,

在这里:

synchronized(mListeners){

for(inti=mListeners.size()-1;i>=0;i--){

MountServiceBinderListenerbl=mListeners.get(i);

try{

bl.mListener.onStorageStateChanged(path,oldState,state);

}catch(RemoteExceptionrex){

Slog.e(TAG,"Listenerdead");

mListeners.remove(i);

}catch(Exceptionex){

Slog.e(TAG,"Listenerfailed",ex);

}

}

}

也就是守护进程检测sd卡状态变化时调用StorageManager中的mBinderListener对象的onStorageStateChanged,此时在StorageManager中,就依次向需要知道Storage状态变化的目标发送消息,刚才我们说的StorageManager开启的无限循环的Handler收到消息就开始了相应处理。

Usb插入时有无Debugging时的Notification是怎样产生的?

UsbService.java中,privatefinalUEventObservermUEventObserver=newUEventObserver()函数是用来监听底层Usb状态的机制。当"usb_connected""usb_configuration"、或者其它的Usb状态(Adb)发生变化时会发送一个Message,然后根据messageusbService做出相应的处理。

sourcecode中,adb变化时,有Note如下:

Note:wedonotbroadcastachangewhenafunctionisenabledordisabled.Wejustrecordthestatechangeforthenextbroadcast.

这就使得android系统不能及时更新UsbNotification状态。

handler处理函数处:

caseMSG_FUNCTION_ENABLED:

caseMSG_FUNCTION_DISABLED:

functionEnabledLocked((String)msg.obj,msg.what==MSG_FUNCTION_ENABLED);

break;

Note所说,仅仅是保存起来,并未进行更新。

要想即刻做出更新,应做出如下操作:

caseMSG_FUNCTION_ENABLED:

caseMSG_FUNCTION_DISABLED:

functionEnabledLocked((String)msg.obj,msg.what==MSG_FUNCTION_ENABLED);

//sendastickybroadcastcontainingcurrentUSBstate

Intentintent=newIntent(UsbManager.ACTION_USB_STATE);

intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

intent.putExtra(UsbManager.USB_CONNECTED,mConnected!=0);

intent.putExtra(UsbManager.USB_CONFIGURATION,mConfiguration);

addEnabledFunctionsLocked(intent);

mContext.sendStickyBroadcast(intent);

break;

这就完成了及时更新策略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值