Android 6.0之后获取sd卡信息的方法

package com.techson.lg1066.utils;


import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;


import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.storage.StorageManager;
import android.text.format.Formatter;
import android.util.Log;


/**
 * 
 * <p>
 * Email:771365380@qq.com
 * </p>
 * <p>
 * Mobile phone:15133350726
 * </p>
 */
public class MySDCard_2 {
private String tag = this.getClass().getName();
private Context context;
public static Object[] objArray;
public static String storageInfo;// sd卡和手机内存的信息
public static String path = null;// SD卡的路径
public static String TotalSize = null;// SD卡的大小
public static String AvailableSize = null;// SD卡的大小
public static Boolean isRemovable = false;// SD卡是否可移除
String getVolumeState = null;// SD卡的安装状态


/**
* 构造方法
*/
public MySDCard_2(Context context) {
this.context = context;
}


// ==========================================================================================
// http://www.open-open.com/code/view/1433585940578从这里看来获取手机SDCard路径的方法有三种,
// 现有的做法是通过反射调用系统的方法获取Storage列表。——实际上有的时候这会失败,所以我们在探寻一个“全能的”方法,也或者分版本分类治之


// /**
// * 遍历 "system/etc/vold.fstab” 文件,获取全部的Android的挂载点信息
// *
// * @return
// */
// private static ArrayList<String> getDevMountList() {
// String[] toSearch = FileUtils.readFile("/etc/vold.fstab").split(" ");
// ArrayList<String> out = new ArrayList<String>();
// for (int i = 0; i < toSearch.length; i++) {
// if (toSearch[i].contains("dev_mount")) {
// if (new File(toSearch[i + 2]).exists()) {
// out.add(toSearch[i + 2]);
// }
// }
// }
// return out;
// }


// region getSDCardPathsVersionNum()
public File[] getSDCardPaths() {
Log.i(tag, "当前手机系统版本号=" + Build.VERSION.SDK_INT);
switch (Build.VERSION.SDK_INT) {
case 23:// 23
return this.getSDCardPaths_23();
case 22:// 22
return this.getSDCardPaths_22();
case 21:
return this.getSDCardPaths_21();
case 20:
return this.getSDCardPaths_20();
case 19:
return this.getSDCardPaths_19();
case 18:
return this.getSDCardPaths_18();
case 17:
return this.getSDCardPaths_17();
case 16:
return this.getSDCardPaths_16();
case 15:
return this.getSDCardPaths_15();
case 14:
return this.getSDCardPaths_14();
// case 13:
// return this.getSDCardPaths_13();
// case 12:
// return this.getSDCardPaths_12();
// case 11:
// return this.getSDCardPaths_11();
// case 10:
// return this.getSDCardPaths_10();
// case 9:
// return this.getSDCardPaths_9();
// case 8:
// return this.getSDCardPaths_8();
}
Log.i(tag, "不支持这个版本,请查阅源码");
return null;
}


/**
* 通过使用Environment.getExternalStorageDirectory()所使用的方法得到本机中所有存储卡的位置
* <p/>
* 这个总体思路是对的,但是被一些具体的实现给卡住了
*/
@TargetApi(23)
// 这里反射的方法之后api23才有所以我们这个方法是针对这个版本的
public File[] getSDCardPaths_23() {
return getSDCardPaths_18();
}


/**
* 在真机对应版本上进行测试没有任何问题,
* 但是我还有一个问题,就是为什么在模拟器上就得不到这样一个结果,是因为模拟器的源码和真机的有不同,还是我创建真机的时候有异常?

* @return 获取到的存储设备
*/
@TargetApi(22)
public File[] getSDCardPaths_22() {
return getSDCardPaths_18();
}


/**
* 如果调用高版本的实现方式,说明这两个版本的我们用到的源码是相同的。

* @return 获取到的存储设备
*/
@TargetApi(21)
public File[] getSDCardPaths_21() {
return getSDCardPaths_18();
}


/**
* 如果调用高版本的实现方式,说明这两个版本的我们用到的源码是相同的。

* @return 获取到的存储设备
*/
@TargetApi(20)
public File[] getSDCardPaths_20() {
return getSDCardPaths_18();
}


/**
* 如果调用高版本的实现方式,说明这两个版本的我们用到的源码是相同的。

* @return 获取到的存储设备
*/
@TargetApi(19)
public File[] getSDCardPaths_19() {
return getSDCardPaths_18();
}


/**
* 如果调用高版本的实现方式,说明这两个版本的我们用到的源码是相同的。
* <p/>
* 借鉴:http://vjson .com/wordpress/%E8%
* 8E%B7%E5%8F%96android%E8%AE%BE%E5%A4%87%E6%8C%82%E8%BD%BD
* %E7%9A%84%E6%89%80%E6%9C%89%E5%AD%98%E5%82%A8%E5%99%A8.html

* @return 获取到的存储设备
*/
@TargetApi(18)
public File[] getSDCardPaths_18() {


try {
Log.i(tag, "getExternalStorageDirectory="
+ Environment.getExternalStorageDirectory().getPath());
Class class_StorageManager = StorageManager.class;
Method method_getVolumeList = class_StorageManager
.getMethod("getVolumeList");
Method method_getVolumeState = class_StorageManager.getMethod(
"getVolumeState", String.class);
StorageManager sm = (StorageManager) context
.getSystemService(Context.STORAGE_SERVICE);
Class class_StorageVolume = Class
.forName("android.os.storage.StorageVolume");
Method method_isRemovable = class_StorageVolume
.getMethod("isRemovable");
Method method_getPath = class_StorageVolume.getMethod("getPath");
Method method_getPathFile = class_StorageVolume
.getMethod("getPathFile");
objArray = (Object[]) method_getVolumeList.invoke(sm);


//objArray.length==2时说明插上了sd卡
Log.i(tag, "---objArray[].length=--->" + objArray.length
+ "---根据是否可以移除来判断是否为外置存储卡。");
List<File> fileList = new ArrayList<File>();
for (Object value : objArray) {
//sd卡的路径
path = (String) method_getPath.invoke(value);
//Log.i("aaaaa", "------path--" + path);
AvailableSize = getAvailableExternalMemorySize(context, path);
TotalSize = getTotalExternalMemorySize(context, path);


isRemovable = (Boolean) method_isRemovable.invoke(value);
getVolumeState = (String) method_getVolumeState
.invoke(sm, path);// 获取挂载状态。
fileList.add((File) method_getPathFile.invoke(value));
// if(isRemovable==true){
// storageInfo="TotalSize:"+TotalSize+","+
// "剩余空间:"+AvailableSize+
// "存储路径:" + path + "是否可移除:" + isRemovable +
// "安装状态:" + getVolumeState;
// }else{
// storageInfo="无SD卡";
// }
}


File[] files = new File[fileList.size()];
fileList.toArray(files);
return files;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}


/**
* 如果调用高版本的实现方式,说明这两个版本的我们用到的源码是相同的。

* @return 获取到的存储设备
*/
@TargetApi(17)
public File[] getSDCardPaths_17() {
return getSDCardPaths_18();
}


/**
* 如果调用高版本的实现方式,说明这两个版本的我们用到的源码是相同的。
* <p/>
* api16在StorageVolume方法中没有getPathFile

* @return 获取到的存储设备
*/
@TargetApi(16)
public File[] getSDCardPaths_16() {
try {
Log.i(tag, "getExternalStorageDirectory="
+ Environment.getExternalStorageDirectory().getPath());
Class class_StorageManager = StorageManager.class;
Method method_getVolumeList = class_StorageManager
.getMethod("getVolumeList");
Method method_getVolumeState = class_StorageManager.getMethod(
"getVolumeState", String.class);
StorageManager sm = (StorageManager) context
.getSystemService(Context.STORAGE_SERVICE);
Class class_StorageVolume = Class
.forName("android.os.storage.StorageVolume");
Method method_isRemovable = class_StorageVolume
.getMethod("isRemovable");
Method method_getPath = class_StorageVolume.getMethod("getPath");
Object[] objArray = (Object[]) method_getVolumeList.invoke(sm);


Log.i(tag, "objArray[].length=" + objArray.length
+ "---根据是否可以移除来判断是否为外置存储卡。");
List<File> fileList = new ArrayList<File>();
for (Object value : objArray) {
String path = (String) method_getPath.invoke(value);
Boolean isRemovable = (Boolean) method_isRemovable
.invoke(value);
String getVolumeState = (String) method_getVolumeState.invoke(
sm, path);// 获取挂载状态。
Log.d(tag, "存储路径:" + path + "---isRemovable:" + isRemovable
+ "----getVolumeState:" + getVolumeState);


fileList.add(new File((String) method_getPath.invoke(value)));
}
File[] files = new File[fileList.size()];
fileList.toArray(files);
return files;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}


/**
* 如果调用高版本的实现方式,说明这两个版本的我们用到的源码是相同的。

* @return 获取到的存储设备
*/
@TargetApi(15)
public File[] getSDCardPaths_15() {
return getSDCardPaths_16();
}


/**
* 如果调用高版本的实现方式,说明这两个版本的我们用到的源码是相同的。

* @return 获取到的存储设备
*/
@TargetApi(14)
public File[] getSDCardPaths_14() {
return getSDCardPaths_16();
}


// endregion


/**
* 获取SDCARD剩余存储空间 带单位

* @return
*/
public static String getAvailableExternalMemorySize(Context context,
String path1) {


// File path = Environment.getExternalStorageDirectory();
File path = new File(path1);
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return Formatter.formatFileSize(context, availableBlocks * blockSize);
}


/**
* 获取SDCARD总的存储空间 不带单位

* @return
*/
public static String getTotalExternalMemorySize(Context context,
String path2) {


// File path = Environment.getExternalStorageDirectory();
// LogManage.SetLog("获取SDCARD总的存储空间   不带单位-----" + path.getPath());
File path = new File(path2);
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return Formatter.formatFileSize(context, totalBlocks * blockSize);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值