注: 作者原创,转载请标明出处。
谷歌原生没有提供有效的获取内部存储、SD卡、OTG设备文件区分,那么,怎样有效获取?
一般情况:
1. 通过反射调用:
StorageManager.getVolumeList();
2. 通过调用得到StorageVolume 列表,但是我们不能有效的区分哪一个是sd,otg,内部存储,怎么办?
一般内部存储的文件path以"/storage/emulated"开头,通过该标志可判断内部存储
关于sd卡和otg怎么判断?
根据前面获取到的列表数据:
DiskInfo di= mStorageManager.findVolumeByUuid(sv.getUuid()).getDisk();
di对象有isSd()、isUsb()方法,至此可以区分开来。
具体可参考如下:
package com.fileexplorer.service;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.os.storage.StorageManager;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageVolume;
import android.os.storage.DiskInfo;
import android.util.Log;
import com.fileexplorer.service.FileManageService;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by Xuehao.Jiang on 2017/6/27.
*/
public class FileManageService extends Service {
private static final String TAG = FileManageService.class.getSimpleName();
private StorageManager mStorageManager;
private StorageVolume[] storageVolumes = null;
private static List
storageVolumeAll = new ArrayList
();
private List
sListeners = new ArrayList
();
private static final int PHONE_ROOT = 0;
private static final int SD_ROOT = 1;
private static final int OTG_ROOT = 2;
private static final int NONE_ROOT = -1;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG," onCreate .... ");
mStorageManager = (StorageManager) getSystemService(STORAGE_SERVICE);
mStorageManager.registerListener(mStorageListener);
init();
}
@Override
public void onDestroy() {
super.onDestroy();
mStorageManager.unregisterListener(mStorageListener);
Log.d(TAG," onDestroy .... ");
}
private final StorageEventListener mStorageListener = new StorageEventListener() {
@Override
public void onStorageStateChanged(String path, String oldState, String newState) {
refresh();
notifyStorageChanged(path,oldState,newState);
}
};
public void init(){
Log.d(TAG," init .... ");
refresh();
}
private void refresh(){
storageVolumeAll.clear();
storageVolumes = mStorageManager.getVolumeList();
if(storageVolumes != null && storageVolumes.length>0){
for(int i=0; i< storageVolumes.length ; i++){
StorageVolume sv = storageVolumes[i];
Log.d(TAG," ....storageVolumes[ "+i+"] = "+sv +" mfsUuid="+ sv.getUuid()+" path="+ sv.getPath() +" label="+ sv.getDescription(this));
File f =sv.getPathFile();
if( f.exists()&& f.isDirectory() && f.canWrite()){
if(Environment.MEDIA_MOUNTED.equals(sv.getState())){
storageVolumeAll.add(sv);
}
}
}
Log.d(TAG," storageVolumeAll size="+ storageVolumeAll.size());
}
}
public static List
getStorageVolumes(){ return storageVolumeAll; } public static int getRootPath(String path){ if(storageVolumeAll.size()>0){ for(StorageVolume sv: storageVolumeAll){ String mPath = sv.getPath(); if(path!=null && path.equals(mPath)){ if(path.startsWith("/storage/emulated")){ return PHONE_ROOT; }else { DiskInfo di= mStorageManager.findVolumeByUuid(sv.getUuid()).getDisk(); if(di.isSd()){ return SD_ROOT; }else if(di.isUsb()){ return OTG_ROOT; } } } } } return NONE_ROOT; } public interface CallBackListener{ public void notifyStorageChanged(String path, String oldState, String newState); } private final Object sLock = new Object(); public void addCallBackListener(CallBackListener scl) { synchronized (sLock) { sListeners.add(scl); } } public void removeCallBackListener(CallBackListener scl) { synchronized (sLock) { sListeners.remove(scl); } } public void notifyStorageChanged(String path, String oldState, String newState) { synchronized (sLock) { for (CallBackListener l : sListeners) { l.notifyStorageChanged(path, oldState, newState); } } } }