如何获取Android设备挂载的所有存储器
android系统提供了environment.getexternalstoragedirectory()接口获得存储器的路径,但是这个接口往往给的结果并不是我们想要的,在某些设备上它返回的是手机内部存储,某些设备它返回的手机外部存储。还有就是某些android设备支持扩展多个sdcard,这个时候想要获得所有存储器的挂载路径,这个接口是没有办法办到的。
怎么获取android设备所有存储器的位置呢?或者说获得所有的挂载点
系统提供了一个storagemanager,它有一个方法叫getvolumelist,这个方法的返回值是一个storagevolume数组,storagevolume类中封装了挂载路径,挂载状态,以及是否可以移除等等信息。但是很可惜,这个方法是隐藏的api,所以我们只能通过反射来调用这个方法了,下面是这个方法的源码。
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; } }
通过反射,获取到android设备所有存储器。
public class storageinfo { public string path; public string state; public boolean isremoveable; public storageinfo(string path) { this.path = path; } public boolean ismounted() { return "mounted".equals(state); } }
public static list listavaliablestorage(context context) { arraylist storagges = new arraylist(); storagemanager storagemanager = (storagemanager) context.getsystemservice(context.storage_service); try { class<?>[] paramclasses = {}; method getvolumelist = storagemanager.class.getmethod("getvolumelist", paramclasses); getvolumelist.setaccessible(true); object[] params = {}; object[] invokes = (object[]) getvolumelist.invoke(storagemanager, params); if (invokes != null) { storageinfo info = null; 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 storageinfo(path); file file = new file(info.path); if ((file.exists()) && (file.isdirectory()) && (file.canwrite())) { method isremovable = obj.getclass().getmethod("isremovable", new class[0]); string state = null; try { method getvolumestate = storagemanager.class.getmethod("getvolumestate", string.class); state = (string) getvolumestate.invoke(storagemanager, info.path); info.state = state; } catch (exception e) { e.printstacktrace(); } if (info.ismounted()) { info.isremoveable = ((boolean) isremovable.invoke(obj, new object[0])).booleanvalue(); storagges.add(info); } } } } } catch (nosuchmethodexception e1) { e1.printstacktrace(); } catch (illegalargumentexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } catch (invocationtargetexception e) { e.printstacktrace(); } storagges.trimtosize(); return storagges; }
如何判断存储器是内置存储还是外置存储呢?
storagevolume这个类中提供了一个isremovable()接口,通过反射调用它就可以知道存储器是否可以移除。把可以移除的存储器认定为外置sdcard,不可移除的存储器认定为内置存储器。
method isremovable = obj.getclass().getmethod("isremovable", new class[0]);
如何判断存储器的挂载状态呢?
同上面一样,需要反射系统接口才可以获取到挂载状态。下面是代码片段
method getvolumestate = storagemanager.class.getmethod("getvolumestate", string.class); state = (string) getvolumestate.invoke(storagemanager, info.path); info.state = state;
总结
通过反射系统的storagemanager以及storagevolume类提供的接口,就可以拿到android设备挂载的所有存储器路径,以及存储器类型(内置存储还是外置存储),还有存储器的挂载状态等信息。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 三国曹魏名臣,揭秘赵俨的一生是怎样的