我希望在设备上获得外部SdCard路径(如果可用)。通过使用Environment.getExternalStorageDirectory()。getAbsolutePath()我可以获得内部存储的路径。所以我使用下面的类来检测外部存储。
public class ExternalStorage {
public static final String SD_CARD = "sdCard";
public static final String EXTERNAL_SD_CARD = "externalSdCard";
/**
* @return True if the external storage is available. False otherwise.
*/
public static boolean isAvailable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
public static String getSdCardPath() {
return Environment.getExternalStorageDirectory().getPath() + "/";
}
/**
* @return True if the external storage is writable. False otherwise.
*/
public static boolean isWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/**
* @return A map of all storage locations available
*/
public static Map<String, File> getAllStorageLocations() {
Map<String, File> map = new HashMap<String, File>(10);
List<String> mMounts = new ArrayList<String>(10);
List<String> mVold = new ArrayList<String>(10);
mMounts.add("/mnt/sdcard");
mVold.add("/mnt/sdcard");
try {
File mountFile = new File("/proc/mounts");
if(mountFile.exists()){
Scanner scanner = new Scanner(mountFile);
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("/dev/block/vold/")) {
String[] lineElements = line.split(" ");
String element = lineElements[1];
// don't add the default mount path
// it's already in the list.
if (!element.equals("/mnt/sdcard"))
mMounts.add(element);
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
try {
File voldFile = new File("/system/etc/vold.fstab");
if(voldFile.exists()){
Scanner scanner = new Scanner(voldFile);
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("dev_mount")) {
String[] lineElements = line.split(" ");
String element = lineElements[2];
if (element.contains(":"))
element = element.substring(0, element.indexOf(":"));
if (!element.equals("/mnt/sdcard"))
mVold.add(element);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < mMounts.size(); i++) {
String mount = mMounts.get(i);
if (!mVold.contains(mount))
mMounts.remove(i--);
}
mVold.clear();
List<String> mountHash = new ArrayList<String>(10);
for(String mount : mMounts){
File root = new File(mount);
if (root.exists() && root.isDirectory() && root.canWrite()) {
File[] list = root.listFiles();
String hash = "[";
if(list!=null){
for(File f : list){
hash += f.getName().hashCode()+":"+f.length()+", ";
}
}
hash += "]";
if(!mountHash.contains(hash)){
String key = SD_CARD + "_" + map.size();
if (map.size() == 0) {
key = SD_CARD;
} else if (map.size() == 1) {
key = EXTERNAL_SD_CARD;
}
mountHash.add(hash);
map.put(key, root);
}
}
}
mMounts.clear();
if(map.isEmpty()){
map.put(SD_CARD, Environment.getExternalStorageDirectory());
}
return map;
}
使用示例
Map <String, File> externalLocations = ExternalStorage.getAllStorageLocations();
File sdCard = externalLocations.get(ExternalStorage.SD_CARD);
File externalSdCard=externalLocations.get(ExternalStorage.EXTERNAL_SD_CARD);
在某些设备上,如三星Galaxy S3,它正确检测外部SdCard并返回/ storage / extSdCard以获取外部SdCard的路径,但在Sony Experia Z1和Z2等其他设备上,它无法检测外部Sdcard并给我路径内部存储。我该如何解决这个问题?
答案 0 :(得分:2)
使用以下代码获取SD卡路径
public class DiskHelper
{
public static final int MODE_INTERNAL = 0;
public static final int MODE_EXTERNAL = 1;
public static final int MODE_EXTERNAL_SD = 2;
private StatFs statFs;
protected String path;
public DiskHelper(int mode)
{
try
{
if(mode == 0)
{
path = Environment.getRootDirectory().getAbsolutePath();
statFs = new StatFs(path);
statFs.restat(path);
}
else if(mode == 1)
{
path = Environment.getExternalStorageDirectory().getAbsolutePath();
statFs = new StatFs(path);
statFs.restat(path);
}
else
{
for(String str : getExternalMounts())
{
path = str;
statFs = new StatFs(str);
statFs.restat(str);
break;
}
}
}
catch(Exception e)
{
KLog.error(e);
}
}
public String getPath()
{
return path;
}
public long getTotalMemory()
{
if(statFs == null)
{
return 0;
}
long total = ((long)statFs.getBlockCount() * (long)statFs.getBlockSize());
return total;
}
public long getFreeMemory()
{
if(statFs == null)
{
return 0;
}
long free = ((long)statFs.getAvailableBlocks() * (long)statFs.getBlockSize());
return free;
}
public long getBusyMemory()
{
if(statFs == null)
{
return 0;
}
long total = getTotalMemory();
long free = getFreeMemory();
long busy = total - free;
return busy;
}
public static HashSet<String> getExternalMounts()
{
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try
{
final Process process = new ProcessBuilder().command("mount").redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while(is.read(buffer) != -1)
{
s = s + new String(buffer);
}
is.close();
}
catch(Exception e)
{
KLog.error(e);
}
final String[] lines = s.split("\n");
for (String line : lines)
{
if(!line.toLowerCase(Locale.US).contains("asec"))
{
if(line.matches(reg))
{
String[] parts = line.split(" ");
for(String part : parts)
{
if(part.startsWith("/"))
{
if(!part.toLowerCase(Locale.US).contains("vold"))
{
out.add(part);
}
}
}
}
}
}
return out;
}
private static final long MEGABYTE = 1024L * 1024L;
public static String humanReadableByteCount(long bytes, boolean si)
{
if(true)
{
long ret = bytes / MEGABYTE;
return ret + " MB";
}
int unit = si ? 1000 : 1024;
if (bytes < unit) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
}
然后
final DiskHelper sdDiskHelper = new DiskHelper(DiskHelper.MODE_EXTERNAL_SD);
path = sdDiskHelper.getPath();
您可以自定义此课程。
答案 1 :(得分:0)
String secStore = System.getenv(&#34; SECONDARY_STORAGE&#34;);
文件externalsdpath =新文件(secStore);
这将获得外部sd二级存储的路径。