android4.0 usb状态相关处理[转]



在TabletStatusBar.javastart()函数中,有这样关于USB的状态监听机制:


 // storage

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

 mStorageManager.registerListener(

               new com.android.systemui.usb.StorageNotification(context));

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

  public void registerListener(StorageEventListener listener) {

        if (listener == null) {

            return;

        }

        synchronized (mListeners) {

            mListeners.add(new ListenerDelegate(listener));

        }

    }

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

查看ListenerDelegate

ListenerDelegate(StorageEventListener listener) {

            mStorageEventListener = listener;

            mHandler = new Handler(mTgtLooper) {

                @Override

                public void handleMessage(Message msg) {

                    StorageEvent e = (StorageEvent) msg.obj;

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

                        UmsConnectionChangedStorageEvent ev = (UmsConnectionChangedStorageEvent) e;

                        mStorageEventListener.onUsbMassStorageConnectionChanged(ev.available);

                    } else if (msg.what == StorageEvent.EVENT_STORAGE_STATE_CHANGED) {

                        StorageStateChangedStorageEvent ev = (StorageStateChangedStorageEvent) e;

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

                    } else {

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

                    }

                }

            };

        }

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

先插卡StorageManager类的构造函数:

  public StorageManager(Looper tgtLooper) throws RemoteException {

        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 = new MountServiceBinderListener();

        mMountService.registerListener(mBinderListener);

    }

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

它的作用是这样的:

private class MountServiceBinderListener extends IMountServiceListener.Stub {

        public void onUsbMassStorageConnectionChanged(boolean available) {

            final int size = mListeners.size();

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

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

            }

        }

        public void onStorageStateChanged(String path, String oldState, String newState) {

            final int size = mListeners.size();

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

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

            }

        }

    }

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

EVENT_STORAGE_STATE_CHANGED

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

MountService.java中,

  public void registerListener(IMountServiceListener listener) {

        synchronized (mListeners) {

            MountServiceBinderListener bl = new MountServiceBinderListener(listener);

            try {

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

                mListeners.add(bl);

            } catch (RemoteException rex) {

                Slog.e(TAG, "Failed to link to listener death");

            }

        }

    }

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

public boolean onEvent(int code, String raw, String[] cooked),它在有关状态发生变化时会调用相关函数,比如VolumeStateChange时,notifyShareAvailabilityChange(),而在 notifyShareAvailabilityChange()中会更新:

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

在这里:

synchronized (mListeners) {

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

                MountServiceBinderListener bl = mListeners.get(i);

                try {

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

                } catch (RemoteException rex) {

                    Slog.e(TAG, "Listener dead");

                    mListeners.remove(i);

                } catch (Exception ex) {

                    Slog.e(TAG, "Listener failed", ex);

                }

            }

        }

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

请使用浏览器的分享功能分享到微信等