Rah*_*602 15 java android sd-card android-sdcard usb-otg
我想获取连接到Android设备的所有存储设备的列表.
例如 - 内部存储(存储所有文件夹,如下载,DCIM等),SD卡和OTG设备.
我知道有很多StackOverflow帖子讨论了这个主题,但没有一个可以满足我的目的,如上所述.
我可以通过调用Environment.getExternalStorageDirectory().getPath()返回内部存储的路径来获取内部存储.
对此的任何帮助都将非常感激,因为没有标准的AFAIK可以使用它来检索所有连接的存储设备的列表.
此外,许多解决方案不适用于不同的设备和Android版本.
您可以创建一个类EnvironmentSDCardCheck
\n\npackage com.example.storagecheck;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.IntentFilter;\nimport android.os.Build;\nimport android.os.Environment;\nimport android.os.storage.StorageManager;\nimport android.support.v4.content.ContextCompat;\nimport android.support.v4.os.EnvironmentCompat;\nimport android.util.Log;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\n\npublic class EnvironmentSDCardCheck {\n private static final String TAG = "EnvironmentSDCardCheck";\n\n public final static String TYPE_PRIMARY = "prim\xc3\xa4r";\n public final static String TYPE_INTERNAL = "intern";\n public final static String TYPE_SD = "MicroSD";\n public final static String TYPE_USB = "USB";\n public final static String TYPE_UNKNOWN = "unbekannt";\n\n public final static String WRITE_NONE = "none";\n public final static String WRITE_READONLY = "readonly";\n public final static String WRITE_APPONLY = "apponly";\n public final static String WRITE_FULL = "readwrite";\n\n private static Device[] devices, externalstorage, storage;\n private static BroadcastReceiver receiver;\n private static boolean useReceiver = true;\n private static String userDir;\n\n public static Device[] getDevices(Context context) {\n if (devices == null) initDevices(context);\n return devices;\n }\n\n public static Device[] getExternalStorage(Context context) {\n if (devices == null) initDevices(context);\n return externalstorage;\n }\n\n public static Device[] getStorage(Context context) {\n if (devices == null) initDevices(context);\n return storage;\n }\n\n public static IntentFilter getRescanIntentFilter() {\n IntentFilter filter = new IntentFilter();\n filter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL); \n filter.addAction(Intent.ACTION_MEDIA_MOUNTED); \n filter.addAction(Intent.ACTION_MEDIA_REMOVED); \n filter.addAction(Intent.ACTION_MEDIA_SHARED); \n filter.addDataScheme("file");\n return filter;\n }\n\n public static void setUseReceiver(Context context, boolean use) {\n if (use && receiver == null) {\n receiver = new BroadcastReceiver() {\n @Override\n public void onReceive(Context context, Intent intent) {\n Log.i(TAG, "Storage " + intent.getAction() + "-" + intent.getData());\n initDevices(context);\n }\n };\n context.registerReceiver(receiver, getRescanIntentFilter());\n } else if (!use && receiver != null) {\n context.unregisterReceiver(receiver);\n receiver = null;\n }\n useReceiver = use;\n }\n\n public static void initDevices(Context context) {\n if (userDir == null) userDir = "/Android/data/" + context.getPackageName();\n setUseReceiver(context, useReceiver);\n StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);\n Class c = sm.getClass();\n Object[] vols;\n try {\n Method m = c.getMethod("getVolumeList", null);\n vols = (Object[]) m.invoke(sm, null); // android.os.Storage.StorageVolume\n Device[] temp = new Device[vols.length];\n for (int i = 0; i < vols.length; i++) temp[i] = new Device(vols[i]);\n Device primary = null;\n for (Device d : temp) if (d.mPrimary) primary = d;\n if (primary == null) for (Device d : temp)\n if (!d.mRemovable) {\n d.mPrimary = true;\n primary = d;\n break;\n }\n if (primary == null) {\n primary = temp[0];\n primary.mPrimary = true;\n }\n\n File[] files = ContextCompat.getExternalFilesDirs(context, null);\n File[] caches = ContextCompat.getExternalCacheDirs(context);\n for (Device d : temp) {\n if (files != null) for (File f : files)\n if (f != null && f.getAbsolutePath().startsWith(d.getAbsolutePath()))\n d.mFiles = f;\n if (caches != null) for (File f : caches)\n if (f != null && f.getAbsolutePath().startsWith(d.getAbsolutePath()))\n d.mCache = f;\n }\n\n ArrayList<Device> tempDev = new ArrayList<Device>(10);\n ArrayList<Device> tempStor = new ArrayList<Device>(10);\n ArrayList<Device> tempExt = new ArrayList<Device>(10);\n for (Device d : temp) {\n tempDev.add(d);\n if (d.isAvailable()) {\n tempExt.add(d);\n tempStor.add(d);\n }\n }\n\n Device internal = new Device(context);\n tempStor.add(0, internal); // bei Storage-Alternativen immer\n if (!primary.mEmulated) tempDev.add(0, internal); // bei Devices nur wenn zus\xc3\xa4tzlich\n\n devices = tempDev.toArray(new Device[tempDev.size()]);\n storage = tempStor.toArray(new Device[tempStor.size()]);\n externalstorage = tempExt.toArray(new Device[tempExt.size()]);\n } catch (Exception e) {\n // Fallback auf normale Android-Funktionen\n }\n\n }\n\n public static class Device extends File {\n String mUserLabel, mUuid, mState, mWriteState, mType;\n boolean mPrimary, mRemovable, mEmulated, mAllowMassStorage;\n long mMaxFileSize;\n File mFiles, mCache;\n\n Device(Context context) {\n super(Environment.getDataDirectory().getAbsolutePath());\n mState = Environment.MEDIA_MOUNTED;\n mFiles = context.getFilesDir();\n mCache = context.getCacheDir();\n mType = TYPE_INTERNAL;\n mWriteState = WRITE_APPONLY;\n }\n\n @SuppressWarnings("NullArgumentToVariableArgMethod")\n Device(Object storage) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {\n super((String) storage.getClass().getMethod("getPath", null).invoke(storage, null));\n for (Method m : storage.getClass().getMethods()) {\n if (m.getName().equals("getUserLabel") && m.getParameterTypes().length == 0 && m.getReturnType() == String.class)\n mUserLabel = (String) m.invoke(storage, null); // ab Android 4.4\n if (m.getName().equals("getUuid") && m.getParameterTypes().length == 0 && m.getReturnType() == String.class)\n mUuid = (String) m.invoke(storage, null); // ab Android 4.4\n if (m.getName().equals("getState") && m.getParameterTypes().length == 0 && m.getReturnType() == String.class)\n mState = (String) m.invoke(storage, null); // ab Android 4.4\n if (m.getName().equals("isRemovable") && m.getParameterTypes().length == 0 && m.getReturnType() == boolean.class)\n mRemovable = (Boolean) m.invoke(storage, null); // ab Android 4.0\n if (m.getName().equals("isPrimary") && m.getParameterTypes().length == 0 && m.getReturnType() == boolean.class)\n mPrimary = (Boolean) m.invoke(storage, null); // ab Android 4.2\n if (m.getName().equals("isEmulated") && m.getParameterTypes().length == 0 && m.getReturnType() == boolean.class)\n mEmulated = (Boolean) m.invoke(storage, null); // ab Android 4.0\n if (m.getName().equals("allowMassStorage") && m.getParameterTypes().length == 0 && m.getReturnType() == boolean.class)\n mAllowMassStorage = (Boolean) m.invoke(storage, null); // ab Android 4.0\n if (m.getName().equals("getMaxFileSize") && m.getParameterTypes().length == 0 && m.getReturnType() == long.class)\n mMaxFileSize = (Long) m.invoke(storage, null); // ab Android 4.0\n // getDescription (ab 4.1 mit context) liefert keine sinnvollen Werte\n // getPathFile (ab 4.2) liefert keine sinnvollen Werte\n // getMtpReserveSpace (ab 4.0) f\xc3\xbcr diese Zwecke unwichtig\n // getStorageId (ab 4.0) f\xc3\xbcr diese Zwecke unwichtig\n }\n if (mState == null) mState = getState();\n\n if (mPrimary)\n mType = TYPE_PRIMARY;\n else {\n String n = getAbsolutePath().toLowerCase();\n if (n.indexOf("sd") > 0)\n mType = TYPE_SD;\n else if (n.indexOf("usb") > 0)\n mType = TYPE_USB;\n else\n mType = TYPE_UNKNOWN + " " + getAbsolutePath();\n }\n }\n\n public String getType() {\n return mType;\n }\n\n public String getAccess() {\n if (mWriteState == null) {\n try {\n mWriteState = WRITE_NONE;\n File[] root = listFiles();\n if (root == null || root.length == 0)\n throw new IOException("root empty/unreadable");\n mWriteState = WRITE_READONLY;\n File t = File.createTempFile("jow", null, getFilesDir());\n //noinspection ResultOfMethodCallIgnored\n t.delete();\n mWriteState = WRITE_APPONLY;\n t = File.createTempFile("jow", null, this);\n //noinspection ResultOfMethodCallIgnored\n t.delete();\n mWriteState = WRITE_FULL;\n } catch (IOException ignore) {\n Log.v(TAG, "test " + getAbsolutePath() + " ->" + mWriteState + "<- " + ignore.getMessage());\n }\n }\n return mWriteState;\n }\n\n public boolean isAvailable() {\n String s = getState();\n return (\n Environment.MEDIA_MOUNTED.equals(s) ||\n Environment.MEDIA_MOUNTED_READ_ONLY.equals(s)\n );\n // MEDIA_SHARED: als USB freigegeben; bitte Handy auf MTP umstellen\n }\n\n public String getState() {\n if (mRemovable || mState == null) {\n if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)\n // Android 5.0? Da gibts was neues\n mState = Environment.getExternalStorageState(this);\n else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)\n // Android 4.4? Dann dort nachfragen\n mState = Environment.getStorageState(this);\n else if (canRead() && getTotalSpace() > 0)\n // lesbar und Gr\xc3\xb6\xc3\x9fe vorhanden => gibt es\n mState = Environment.MEDIA_MOUNTED;\n else if (mState == null || Environment.MEDIA_MOUNTED.equals(mState))\n // nicht lesbar, keine Gr\xc3\xb6\xc3\x9fe aber noch MOUNTED || oder ungesetzt => UNKNOWN\n mState = EnvironmentCompat.MEDIA_UNKNOWN;\n }\n return mState;\n }\n\n public File getFilesDir() {\n if (mFiles == null) {\n mFiles = new File(this, userDir + "/files");\n if (!mFiles.isDirectory())\n //noinspection ResultOfMethodCallIgnored\n mFiles.mkdirs();\n }\n return mFiles;\n }\n\n public File getCacheDir() {\n if (mCache == null) {\n mCache = new File(this, userDir + "/cache");\n if (!mCache.isDirectory())\n //noinspection ResultOfMethodCallIgnored\n mCache.mkdirs();\n }\n return mCache;\n }\n\n public boolean isPrimary() {\n return mPrimary;\n }\n\n public boolean isRemovable() {\n return mRemovable;\n }\n public boolean isEmulated() {\n return mEmulated;\n }\n\n public boolean isAllowMassStorage() {\n return mAllowMassStorage;\n }\n\n public long getMaxFileSize() {\n return mMaxFileSize;\n }\n\n public String getUserLabel() {\n return mUserLabel;\n }\n\n public String getUuid() {\n return mUuid;\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然后您可以用它来检查 SD 卡或 USB 或未知当前是否与设备连接
\n\n\n\n\n这样你就可以获得连接的sd卡、usb等。
\n
private boolean checkSdCardPermission() {\n boolean flag = false;\n try {\n EnvironmentSDCard.Device[] devices = EnvironmentSDCard.getExternalStorage(MainActivity.this);\n for (EnvironmentSDCard.Device d : devices) {\n if (d.getType().equals(EnvironmentSDCard.TYPE_SD) || d.getType().contains(EnvironmentSDCard.TYPE_UNKNOWN) || d.getType().contains(EnvironmentSDCard.TYPE_USB)) {\n flag = d.isAvailable();\n if (flag)\n break;\n }\n }\n } catch (Exception e) {\n }\n return flag;\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1794 次 |
| 最近记录: |