欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

Android设备挂载的所有存储器 手机存储 ,sd卡

来源: 开发者 投稿于  被查看 37842 次 评论:34

Android设备挂载的所有存储器 手机存储 ,sd卡


获取Android设备挂载的所有存储器


android系统提供了Environment.getExternalStorageDirectory()接口获得存储器的路径,但是这个接口往往给的结果并不是我们想要的,在某些设备上它返回的是手机内部存储,某些设备它返回的手机外部存储。还有就是某些Android设备支持扩展多个sdcard,这个时候想要获得所有存储器的挂载路径,这个接口是没有办法办到的。

  • 怎么获取Android设备所有存储器的位置呢?或者说获得所有的挂载点系统提供了一个StorageManager,它有一个方法叫getVolumeList,这个方法的返回值是一个StorageVolume数组,StorageVolume类中封装了挂载路径,挂载状态,以及是否可以移除等等信息。但是很可惜,这个方法是隐藏的api,所以我们只能通过反射来调用这个方法了,下面是这个方法。

     

    只返回手机存储目录调用这个方法 实测可用
    public File getStorage(){
    		StorageManager manager =(StorageManager) getSystemService(STORAGE_SERVICE);
    		try {
    		Class[] paramClasses = {};
               Method getVolumeList;
    	
    			getVolumeList = StorageManager.class.getMethod("getVolumeList", paramClasses);
    			  getVolumeList.setAccessible(true);
    			  Object[] params = {};
    			  Object[] invokes = (Object[]) getVolumeList.invoke(manager, params);
    			  if (invokes != 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]);
    	                    File file = new File(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(manager, path);
    	                          
    	                        } catch (Exception e) {
    	                            e.printStackTrace();
    	                        }
    	                    boolean canRemovable =    ((Boolean) isRemovable.invoke(obj, new Object[0])).booleanValue();
    	                    //不可删除的并且挂载的是手机存储
    	                    if (!canRemovable&&state.equals(Environment.MEDIA_MOUNTED)) {
    							return file ;
    						}
    	                   
    	                    }
    	                  
    				  }  
    			  }
    		} catch (NoSuchMethodException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (InvocationTargetException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return null ;
             
    	}



    12345678910111213141516 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设备所有存储器。

  •  

    1 2 3 4 5 6 7 8 9 10 11 12 13 publicclassStorageInfo{ publicStringpath; publicStringstate; publicbooleanisRemoveable; publicStorageInfo(Stringpath){ this.path=path; } publicbooleanisMounted(){ 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,不可移除的存储器认定为内置存储器。

     

    1 MethodisRemovable=obj.getClass().getMethod("isRemovable",newClass[0]);

     

     

  • 如何判断存储器的挂载状态呢?同上面一样,需要反射系统接口才可以获取到挂载状态。下面是代码片段

     

    1 2 3 MethodgetVolumeState=StorageManager.class.getMethod("getVolumeState",String.class); state=(String)getVolumeState.invoke(storageManager,info.path); info.state=state;

     

  • 总结通过反射系统的StorageManager以及StorageVolume类提供的接口,就可以拿到Android设备挂载的所有存储器路径,以及存储器类型(内置存储还是外置存储),还有存储器的挂载状态等信息。
  •  

用户评论