zoukankan      html  css  js  c++  java
  • android6.0 外部存储设备插拔广播以及获取路径(U盘)【转】

    本文转载自:https://blog.csdn.net/zhouchengxi/article/details/53982222

    这里我将U盘作为例子来说明解析。

    android4.1版本时U盘插拔时的广播

    在android4.1时我们可以用以下的BroadcastReceiver接收U盘广播。

    <intent-filter>
        <action android:name="android.intent.action.MEDIA_MOUNTED" />
        <action android:name="android.intent.action.MEDIA_CHECKING" />
        <action android:name="android.intent.action.MEDIA_EJECT" />
        <action android:name="android.intent.action.MEDIA_REMOVED" />
    
        <data android:scheme="file" />
    </intent-filter>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    android6.0版本时U盘插拔时的广播

    但是由于业务需求,当换成6.0的安卓系统后,会发现接收不到U盘插拔的广播。 
    在此之前我尝试了使用USBManager

            intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
            intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
    • 1
    • 2

    但是我发现U盘一插进去就发出这个广播,而不是等到U盘加载好后发出这个广播,于是我又去研究其他的方法。 
    在查询安卓6.0的源码发现了VolumeInfo这个类,记录存储设备的状态信息。 
    VolumeInfo类下面有几个常量表示当前的存储设备的状态。

    public static final int STATE_UNMOUNTED = 0;
    public static final int STATE_CHECKING = 1;
    public static final int STATE_MOUNTED = 2;
    public static final int STATE_MOUNTED_READ_ONLY = 3;
    public static final int STATE_FORMATTING = 4;
    public static final int STATE_EJECTING = 5;
    public static final int STATE_UNMOUNTABLE = 6;
    public static final int STATE_REMOVED = 7;
    public static final int STATE_BAD_REMOVAL = 8;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    以及广播的Action以及接受广播的key

    public static final String ACTION_VOLUME_STATE_CHANGED =
            "android.os.storage.action.VOLUME_STATE_CHANGED";
    public static final String EXTRA_VOLUME_ID =
            "android.os.storage.extra.VOLUME_ID";
    public static final String EXTRA_VOLUME_STATE =
            "android.os.storage.extra.VOLUME_STATE";
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这里我做了一个简单的程序用来检验对U盘插拔的状态进行检测。

    if(action.equals("android.os.storage.action.VOLUME_STATE_CHANGED")){
        int i = intent.getIntExtra(VolumeInfo.EXTRA_VOLUME_STATE,VolumeInfo.STATE_UNMOUNTED);
        Log.d("zcx","action="+action+"    state="+i);
    }
    • 1
    • 2
    • 3
    • 4

    当插入U盘后显示的Logcat如下所示: 
    插入U盘的Logcat 
    U盘的state从STATE_UNMOUNTED→STATE_MOUNTED 
    当拔出U盘后显示的Logcat如下所示: 
    拔出U盘的Logcat 
    U盘的state从STATE_EJECTING →STATE_UNMOUNTED→STATE_BAD_REMOVAL。

    android6.0版本获取U盘路径

    由于6.0版本会根据U盘的型号来划分各自的路径,我的方法是通过StorageManager的getVolumes()就能取得外部设备的状态信息,从而获取到U盘路径。 
    VolumeInfo中包含Type以及DiskInfo信息。

        public static final int TYPE_PUBLIC = 0;
        public static final int TYPE_PRIVATE = 1;
        public static final int TYPE_EMULATED = 2;
        public static final int TYPE_ASEC = 3;
        public static final int TYPE_OBB = 4;
    • 1
    • 2
    • 3
    • 4
    • 5

    U盘的Type是TYPE_PUBLIC,然后再通过DiskInfo的isUsb()方法即可判断当前是否为U盘。

    List<VolumeInfo> list = mStorageManager.getVolumes();
                for (VolumeInfo volumeInfo : list) {
                    if (volumeInfo.getType() == 0) {
                        DiskInfo diskInfo = volumeInfo.getDisk();
                        if (diskInfo != null && (diskInfo.isUsb())) {
                            int i = volumeInfo.getState();
                            //volumeInfo.getPath()通过这个方法就能取得路径
                           //这里的Volume就是U盘的信息了
                         }
                    }
                }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    接触C# 反射
    未能找出类型或命名空间名称“T” 问题的解决方案
    Win7 文件加密存储操作后,如何在事后备份证书、秘钥
    [转] SQL SERVER 2008 R2 安装中的账户设置问题
    centos6.5+Django+mysql+nginx+uwsgi
    JAVA解决大数
    STL algorithm算法min,min_element(35)
    Java中间MD5加密算法完整版
    IP地址和子网掩码
    加州理工大学公开课:机器学习与数据挖掘_线性模型 II(第IX类)
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/9131936.html
Copyright © 2011-2022 走看看