Android Tv U盘挂载
16lz
2021-01-23
判断Android tv U盘挂载不同于判断手机是否连接usb,我们没办法直接使用usbDevice类进行操作。
只能通过判断action动作,在android中,插入U盘的时候,kernal内核会向上发出action动作,让应用层来获取。
在代码中添加以下代码段,来监听U盘挂载:
intentFilter.addAction(Intent.ACTION_USB_DISK_MOUNTED); intentFilter.addAction(Intent.ACTION_USB_DISK_UNMOUNTED); intentFilter.addAction(Intent.ACTION_USB_DISK_UNMOUNTED); intentFilter.addDataScheme("file"); this.registerReceiver(usbReceiver, intentFilter);
注意:intentFilter.addDataScheme(“file”)–》是必须添加的,不然没办法监听action动作。
添加完成之后,就可以使用广播来进行动作监听事件触发:
private BroadcastReceiver usbReceiver = new BroadcastReceiver() { @Override public void onReceive(Context arg0, Intent arg1) { List infos = UsbDeviceManager.getAvaliableStorage(UsbDeviceManager.listAllStorage(arg0)); if (infos != null) { if (arg1.getAction().equals(Intent.ACTION_USB_DISK_MOUNTED)) { infos = UsbDeviceManager.getAvaliableStorage(UsbDeviceManager.listAllStorage(arg0)); for(StorageItemEntity sie:infos){ Log.i("LWL",sie.toString()); } } else if (arg1.getAction().equals(Intent.ACTION_USB_DISK_UNMOUNTED)) { Log.v(TAG, "ACTION_USB_DISK_UNMOUNTED::::" + arg1.getAction()); List aliveUsb = UsbDeviceManager.getAvaliableStorage(UsbDeviceManager.listAllStorage(arg0)); for(StorageItemEntity sie:aliveUsb){ Log.i("LWL",sie.toString()); } } } } };
StorageItemEntity类是用来存放所有挂载的U盘的信息:
/** * @author 李文烙 * */public class StorageItemEntity { //存储器的地址 private String uri; //存储器的类型 private int type = 0; //U盘的名字 private String manufactorName = null; //存储器的状态 private String state; //是否可以移除 private boolean isRemoveable; public StorageItemEntity(){ } public StorageItemEntity(String path){ this.uri=path; } public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } public int getType() { return type; } public void setType(int type) { this.type = type; } public String getManufactorName() { return manufactorName; } public void setManufactorName(String manufactorName) { this.manufactorName = manufactorName; } public String getState() { return state; } public void setState(String state) { this.state = state; } public boolean isRemoveable() { return isRemoveable; } public void setRemoveable(boolean removeable) { isRemoveable = removeable; } @Override public String toString() { return "StorageItemEntity=[ uri="+this.uri+",type="+type+",manufactorName="+manufactorName+",state="+state+",isRemoveable="+isRemoveable; }}
通过以上的代码并不能实现U盘挂载的监听,我们还需要添加一个工具类,用来判断所有挂载的磁盘以及现在处于挂载状态的U盘(未移除),:
/** * author: 李文烙 * date: 2017/11/17 * annotation */public class UsbDeviceManager { private static final String TAG = "UsbDeviceManager"; private static UsbDeviceManager usbManager; public static UsbDeviceManager getUsbDeviceManager() { if (usbManager != null) { return usbManager; } usbManager = new UsbDeviceManager(); return usbManager; } public static List listAllStorage(Context context) { ArrayList storages = new ArrayList(); StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); try { Class<?>[] paramClasses = {}; Method getVolumeList = StorageManager.class.getMethod("getVolumeList", paramClasses); Object[] params = {}; Object[] invokes = (Object[]) getVolumeList.invoke(storageManager, params); if (invokes != null) { StorageItemEntity info = null; Log.i(TAG,"getVolumeList"+getVolumeList.getName()); for (int i = 0; i < invokes.length; i++) { Object obj = invokes[i]; Method getPath = obj.getClass().getMethod("getPath", new Class[0]); String path = (String) getPath.invoke(obj, new Object[0]); info = new StorageItemEntity(path); Method getVolumeState = StorageManager.class.getMethod("getVolumeState", String.class); String state = (String) getVolumeState.invoke(storageManager, info.getUri()); info.setState(state); Method isRemovable = obj.getClass().getMethod("isRemovable", new Class[0]); info.setRemoveable(((Boolean) isRemovable.invoke(obj, new Object[0])).booleanValue()); Log.i(TAG,info.toString()); storages.add(info); } } } catch (Exception e) { e.printStackTrace(); } storages.trimToSize(); return storages; } public static List getAvaliableStorage(List infos) { List storages = new ArrayList(); for (StorageItemEntity info : infos) { File file = new File(info.getUri()); Log.i(TAG+"LWL",info.toString()); Log.i(TAG+"LWL","file"+file.exists()+file.isDirectory()+file.canWrite()); if ((file.exists()) && (file.isDirectory())) { if (info.getState() != null) { if (info.getState().equals("mounted") && info.isRemoveable()) { storages.add(info); } } } } return storages; }}
现在在Android sdk中已经将原本可以直接调用的getVolumeState方法给隐藏了,所以我们只能通过反射的方法去调用@hide的方法,源码如下:(有兴趣的同学可以直接查看Android sdk的源码):
第一个:android.os.storage.StorageManager
/** * Returns list of all mountable volumes. * @hide */ public StorageVolume[] getVolumeList() { if (mMountService == null) return new StorageVolume[0]; try { Parcelable[] list = mMountService.getVolumeList(); if (list == null) return new StorageVolume[0]; int length = list.length; StorageVolume[] result = new StorageVolume[length]; for (int i = 0; i < length; i++) { result[i] = (StorageVolume)list[i]; } return result; } catch (RemoteException e) { Log.e(TAG, "Failed to get volume list", e); return null; } } //在这里返回的是一个StorageVolume[]对象
第二个:android.os.storage.StorageVolume(这个类就是获取U盘挂载状态的核心,该类同样被隐藏)
/** * Description of a storage volume and its capabilities, including the * filesystem path where it may be mounted. * * @hide */public class StorageVolume implements Parcelable { // TODO: switch to more durable token private int mStorageId; private final File mPath; private final int mDescriptionId; private final boolean mPrimary; private final boolean mRemovable; private final boolean mEmulated; private final int mMtpReserveSpace; private final boolean mAllowMassStorage; /** Maximum file size for the storage, or zero for no limit */ private final long mMaxFileSize; /** When set, indicates exclusive ownership of this volume */ private final UserHandle mOwner; private String mUuid; private String mUserLabel; private String mState; // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING, // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED, // ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts. public static final String EXTRA_STORAGE_VOLUME = "storage_volume"; public StorageVolume(File path, int descriptionId, boolean primary, boolean removable, boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize, UserHandle owner) { mPath = path; mDescriptionId = descriptionId; mPrimary = primary; mRemovable = removable; mEmulated = emulated; mMtpReserveSpace = mtpReserveSpace; mAllowMassStorage = allowMassStorage; mMaxFileSize = maxFileSize; mOwner = owner; } private StorageVolume(Parcel in) { mStorageId = in.readInt(); mPath = new File(in.readString()); mDescriptionId = in.readInt(); mPrimary = in.readInt() != 0; mRemovable = in.readInt() != 0; mEmulated = in.readInt() != 0; mMtpReserveSpace = in.readInt(); mAllowMassStorage = in.readInt() != 0; mMaxFileSize = in.readLong(); mOwner = in.readParcelable(null); mUuid = in.readString(); mUserLabel = in.readString(); mState = in.readString(); } public static StorageVolume fromTemplate(StorageVolume template, File path, UserHandle owner) { return new StorageVolume(path, template.mDescriptionId, template.mPrimary, template.mRemovable, template.mEmulated, template.mMtpReserveSpace, template.mAllowMassStorage, template.mMaxFileSize, owner); } /** * Returns the mount path for the volume. * * @return the mount path */ public String getPath() { return mPath.toString(); } public File getPathFile() { return mPath; } /** * Returns a user visible description of the volume. * * @return the volume description */ public String getDescription(Context context) { return context.getResources().getString(mDescriptionId); } public int getDescriptionId() { return mDescriptionId; } public boolean isPrimary() { return mPrimary; } /** * Returns true if the volume is removable. * * @return is removable */ public boolean isRemovable() { return mRemovable; } /** * Returns true if the volume is emulated. * * @return is removable */ public boolean isEmulated() { return mEmulated; } /** * Returns the MTP storage ID for the volume. * this is also used for the storage_id column in the media provider. * * @return MTP storage ID */ public int getStorageId() { return mStorageId; } /** * Do not call this unless you are MountService */ public void setStorageId(int index) { // storage ID is 0x00010001 for primary storage, // then 0x00020001, 0x00030001, etc. for secondary storages mStorageId = ((index + 1) << 16) + 1; } /** * Number of megabytes of space to leave unallocated by MTP. * MTP will subtract this value from the free space it reports back * to the host via GetStorageInfo, and will not allow new files to * be added via MTP if there is less than this amount left free in the storage. * If MTP has dedicated storage this value should be zero, but if MTP is * sharing storage with the rest of the system, set this to a positive value * to ensure that MTP activity does not result in the storage being * too close to full. * * @return MTP reserve space */ public int getMtpReserveSpace() { return mMtpReserveSpace; } /** * Returns true if this volume can be shared via USB mass storage. * * @return whether mass storage is allowed */ public boolean allowMassStorage() { return mAllowMassStorage; } /** * Returns maximum file size for the volume, or zero if it is unbounded. * * @return maximum file size */ public long getMaxFileSize() { return mMaxFileSize; } public UserHandle getOwner() { return mOwner; } public void setUuid(String uuid) { mUuid = uuid; } public String getUuid() { return mUuid; } /** * Parse and return volume UUID as FAT volume ID, or return -1 if unable to * parse or UUID is unknown. */ public int getFatVolumeId() { if (mUuid == null || mUuid.length() != 9) { return -1; } try { return Integer.parseInt(mUuid.replace("-", ""), 16); } catch (NumberFormatException e) { return -1; } } public void setUserLabel(String userLabel) { mUserLabel = userLabel; } public String getUserLabel() { return mUserLabel; } public void setState(String state) { mState = state; } public String getState() { return mState; } @Override public boolean equals(Object obj) { if (obj instanceof StorageVolume && mPath != null) { StorageVolume volume = (StorageVolume)obj; return (mPath.equals(volume.mPath)); } return false; } @Override public int hashCode() { return mPath.hashCode(); } @Override public String toString() { final CharArrayWriter writer = new CharArrayWriter(); dump(new IndentingPrintWriter(writer, " ", 80)); return writer.toString(); } public void dump(IndentingPrintWriter pw) { pw.println("StorageVolume:"); pw.increaseIndent(); pw.printPair("mStorageId", mStorageId); pw.printPair("mPath", mPath); pw.printPair("mDescriptionId", mDescriptionId); pw.printPair("mPrimary", mPrimary); pw.printPair("mRemovable", mRemovable); pw.printPair("mEmulated", mEmulated); pw.printPair("mMtpReserveSpace", mMtpReserveSpace); pw.printPair("mAllowMassStorage", mAllowMassStorage); pw.printPair("mMaxFileSize", mMaxFileSize); pw.printPair("mOwner", mOwner); pw.printPair("mUuid", mUuid); pw.printPair("mUserLabel", mUserLabel); pw.printPair("mState", mState); pw.decreaseIndent(); } public static final Creator CREATOR = new Creator() { @Override public StorageVolume createFromParcel(Parcel in) { return new StorageVolume(in); } @Override public StorageVolume[] newArray(int size) { return new StorageVolume[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(mStorageId); parcel.writeString(mPath.toString()); parcel.writeInt(mDescriptionId); parcel.writeInt(mPrimary ? 1 : 0); parcel.writeInt(mRemovable ? 1 : 0); parcel.writeInt(mEmulated ? 1 : 0); parcel.writeInt(mMtpReserveSpace); parcel.writeInt(mAllowMassStorage ? 1 : 0); parcel.writeLong(mMaxFileSize); parcel.writeParcelable(mOwner, flags); parcel.writeString(mUuid); parcel.writeString(mUserLabel); parcel.writeString(mState); }}
更多相关文章
- Android获取WIFI状态下的IP地址以及MAC地址
- Android网络状态监听
- Android 判断程序前后台状态
- Android 判断网络状态实例详解
- Android 8.1 沉浸式状态栏
- Android状态栏通知
- android 检查网络状态
- Android 7.1 隐藏底部状态栏 和去掉默认锁屏功能
- Android获得屏幕高度和状态栏高度