Android-->检测内置/外置SD卡存储卡,枚举所有挂载点(通过反射实现),监听SD卡广播

直接上重点:

1:获取内置SD卡的路径, 但是判断是否有效(是否挂载), 需要用到下面检测挂载点的方法

    /**
     * 获取内置SD卡路径
     * 
     * @return
     */
    public String getInnerSDCardPath() {
        return Environment.getExternalStorageDirectory().getPath();
    }

2:枚举系统所有可用的挂载点,返回的都是绝对路径

    /** 枚举所有挂载点 */
    public static String[] getVolumePaths(Context context) {
        String[] paths = null;
        StorageManager mStorageManager;
        Method mMethodGetPaths = null;
        try {
            mStorageManager = (StorageManager) context
                    .getSystemService(Activity.STORAGE_SERVICE);
            mMethodGetPaths = mStorageManager.getClass().getMethod(
                    "getVolumePaths");
            paths = (String[]) mMethodGetPaths.invoke(mStorageManager);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return paths;
    }

我的运行结果如下:


这里写图片描述

(图中中文是检测挂载的方法log输出)

3:检测挂载点是否可用

    /**
     * 检查是否挂载
     */
    public static boolean checkMounted(Context context, String mountPoint) {
        if (mountPoint == null) {
            return false;
        }
        StorageManager storageManager = (StorageManager) context
                .getSystemService(Context.STORAGE_SERVICE);
        try {
            Method getVolumeState = storageManager.getClass().getMethod(
                    "getVolumeState", String.class);
            String state = (String) getVolumeState.invoke(storageManager,
                    mountPoint);
            return Environment.MEDIA_MOUNTED.equals(state);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

(截图如上,如果已挂载,返回true)


SD卡广播:

//在AndroidManifest.xml文件中,声明广播
<receiver android:name=".SDBroadCastReceiver" ><!--声明广播接收器-->
   <intent-filter android:priority="1000" ><!--接收广播的优先级,数值越大优先级越高,最大1000,目的:防止被其他程序拦截此广播-->
       <action android:name="android.intent.action.MEDIA_MOUNTED" /><!--接收已挂载广播-->
       <action android:name="android.intent.action.MEDIA_EJECT" /><!--接收拔插广播-->

       <data android:scheme="file" /><!--指定过滤资源类型-->
   </intent-filter>
</receiver>
public class SDBroadCastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
            Log.e(context.getClass().getSimpleName(), "SD卡已拔出");
        } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
            Log.e(context.getClass().getSimpleName(), "SD卡挂载");
        }
    }

}

补充说明, 这里测试环境是Android 4.2.2, API 17
/mnt/sdcard :这是内置SD卡的路径(也是挂载点);(不同Android版本,可能不一样)
/mnt/extsd :这是外置SD卡的路径(也是挂载点);

所以:
如果要检测内置/外置SD卡是否存在(可用),方法如下:

if (checkMounted(MainActivity.this, "/mnt/sdcard")) {
    Log.e(this.getLocalClassName(), "内置SD卡可用");
}
if (checkMounted(MainActivity.this, "/mnt/extsd")) {
    Log.e(this.getLocalClassName(), "外置SD卡可用");
}

简单介绍 Java反射的用法:

1:获取需要反射的对象(需要修改属性,或者需要调用非公隐藏方法的对象):

StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

2:得到对象需要调用的方法或者字段的名称

//得到 方法名称,这个方法必须是public声明的才能获取,如果要获取非公方法名,需要使用getDeclaredMethods方法
Method getVolumeState = storageManager.getClass().getMethod("getVolumeState", String.class);//第一个参数:方法的名称, 第二个参数:方法的参数

//得到 字段名,这里用了getDeclaredField方法,所以可以得到非公声明的字段
Field tag = storageManager.getClass().getDeclaredField("TAG");
tag.setAccessible(true);//因为可能字段是非公有,所以需要设置访问权限为公有
tag.set(storageManager, "New Tag");//修改字段的值

3:调用方法(字段赋值,前面已经说了)

String state = (String) getVolumeState.invoke(storageManager,mountPoint);
//storageManager :是需要修改的对象
//mountPoint     :方法需要的参数

至此: 文章就结束了,如有疑问: QQ群:274306954 欢迎您的加入.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android中的广播 广播接受器,可以比喻成收音机。而广播则可以看成电台。 Android系统内部相当于已经有一...
    sunhaiyu阅读 3,274评论 1 0
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,663评论 25 708
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。在进行视频的下载时,我们经常会面临存储路径的选择,选择一个好的...
    Corrine_Shao阅读 4,542评论 0 5
  • 文件存储和清理: 可以看到,当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir(...
    3Q竹林阅读 2,245评论 0 2
  • 第48期:未来脑世界 假说→多纬度推论→验证推论→丰富假说→行成理论 第205期:这一代人的学习 立场、观点和建议...
    随意咖啡阅读 233评论 0 0