11package com .blankj .utilcode .util ;
22
3- import android .annotation .TargetApi ;
4- import android .os .Build ;
5- import android .os .Environment ;
6- import android .os .StatFs ;
3+ import android .content .Context ;
4+ import android .os .storage .StorageManager ;
75
8- import java .io .BufferedInputStream ;
9- import java .io .BufferedReader ;
10- import java .io .File ;
11- import java .io .InputStreamReader ;
6+ import java .lang .reflect .Array ;
7+ import java .lang .reflect .InvocationTargetException ;
8+ import java .lang .reflect .Method ;
9+ import java .util .ArrayList ;
10+ import java .util .Arrays ;
11+ import java .util .List ;
1212
1313/**
1414 * <pre>
@@ -30,109 +30,69 @@ private SDCardUtils() {
3030 * @return true : 可用<br>false : 不可用
3131 */
3232 public static boolean isSDCardEnable () {
33- return Environment . MEDIA_MOUNTED . equals ( Environment . getExternalStorageState () );
33+ return ! getSDCardPaths (). isEmpty ( );
3434 }
3535
3636 /**
3737 * 获取SD卡路径
38- * <p>先用shell,shell失败再普通方法获取,一般是/storage/emulated/0/</p>
3938 *
39+ * @param removable true : 外置SD卡<br>false : 内置SD卡
4040 * @return SD卡路径
4141 */
42- public static String getSDCardPath () {
43- if (! isSDCardEnable ()) return null ;
44- String cmd = "cat /proc/mounts" ;
45- Runtime run = Runtime . getRuntime ();
46- BufferedReader bufferedReader = null ;
42+ @ SuppressWarnings ( "TryWithIdenticalCatches" )
43+ public static List < String > getSDCardPaths ( boolean removable ) {
44+ List < String > paths = new ArrayList <>() ;
45+ StorageManager mStorageManager = ( StorageManager ) Utils . getApp ()
46+ . getSystemService ( Context . STORAGE_SERVICE ) ;
4747 try {
48- Process p = run . exec ( cmd );
49- bufferedReader = new BufferedReader ( new InputStreamReader ( new BufferedInputStream ( p . getInputStream ())) );
50- String lineStr ;
51- while (( lineStr = bufferedReader . readLine ()) != null ) {
52- if ( lineStr . contains ( "sdcard" ) && lineStr . contains ( ".android_secure" )) {
53- String [] strArray = lineStr . split ( " " );
54- if ( strArray . length >= 5 ) {
55- return strArray [ 1 ]. replace ( "/.android_secure" , "" ) + File . separator ;
56- }
57- }
58- if (p . waitFor () != 0 && p . exitValue () == 1 ) {
59- break ;
48+ Class <?> storageVolumeClazz = Class . forName ( "android.os.storage.StorageVolume" );
49+ Method getVolumeList = StorageManager . class . getMethod ( "getVolumeList" );
50+ Method getPath = storageVolumeClazz . getMethod ( "getPath" ) ;
51+ Method isRemovable = storageVolumeClazz . getMethod ( "isRemovable" );
52+ Object result = getVolumeList . invoke ( mStorageManager );
53+ final int length = Array . getLength ( result );
54+ for ( int i = 0 ; i < length ; i ++ ) {
55+ Object storageVolumeElement = Array . get ( result , i ) ;
56+ String path = ( String ) getPath . invoke ( storageVolumeElement );
57+ boolean res = ( Boolean ) isRemovable . invoke ( storageVolumeElement );
58+ if (removable == res ) {
59+ paths . add ( path ) ;
6060 }
6161 }
62- } catch (Exception e ) {
62+ } catch (ClassNotFoundException e ) {
63+ e .printStackTrace ();
64+ } catch (InvocationTargetException e ) {
65+ e .printStackTrace ();
66+ } catch (NoSuchMethodException e ) {
67+ e .printStackTrace ();
68+ } catch (IllegalAccessException e ) {
6369 e .printStackTrace ();
64- } finally {
65- CloseUtils .closeIO (bufferedReader );
6670 }
67- return Environment .getExternalStorageDirectory ().getPath () + File .separator ;
68- }
69-
70- /**
71- * 获取SD卡data路径
72- *
73- * @return SD卡data路径
74- */
75- public static String getDataPath () {
76- if (!isSDCardEnable ()) return null ;
77- return Environment .getExternalStorageDirectory ().getPath () + File .separator + "data" + File .separator ;
71+ return paths ;
7872 }
7973
8074 /**
81- * 获取SD卡剩余空间
82- *
83- * @return SD卡剩余空间
84- */
85- @ TargetApi (Build .VERSION_CODES .JELLY_BEAN_MR2 )
86- public static String getFreeSpace () {
87- if (!isSDCardEnable ()) return null ;
88- StatFs stat = new StatFs (getSDCardPath ());
89- long blockSize , availableBlocks ;
90- availableBlocks = stat .getAvailableBlocksLong ();
91- blockSize = stat .getBlockSizeLong ();
92- return ConvertUtils .byte2FitMemorySize (availableBlocks * blockSize );
93- }
94-
95- /**
96- * 获取SD卡信息
75+ * 获取SD卡路径
9776 *
98- * @return SDCardInfo
77+ * @return SD卡路径
9978 */
100- @ TargetApi (Build .VERSION_CODES .JELLY_BEAN_MR2 )
101- public static String getSDCardInfo () {
102- if (!isSDCardEnable ()) return null ;
103- SDCardInfo sd = new SDCardInfo ();
104- sd .isExist = true ;
105- StatFs sf = new StatFs (Environment .getExternalStorageDirectory ().getPath ());
106- sd .totalBlocks = sf .getBlockCountLong ();
107- sd .blockByteSize = sf .getBlockSizeLong ();
108- sd .availableBlocks = sf .getAvailableBlocksLong ();
109- sd .availableBytes = sf .getAvailableBytes ();
110- sd .freeBlocks = sf .getFreeBlocksLong ();
111- sd .freeBytes = sf .getFreeBytes ();
112- sd .totalBytes = sf .getTotalBytes ();
113- return sd .toString ();
114- }
115-
116- public static class SDCardInfo {
117- boolean isExist ;
118- long totalBlocks ;
119- long freeBlocks ;
120- long availableBlocks ;
121- long blockByteSize ;
122- long totalBytes ;
123- long freeBytes ;
124- long availableBytes ;
125-
126- @ Override
127- public String toString () {
128- return "isExist=" + isExist +
129- "\n totalBlocks=" + totalBlocks +
130- "\n freeBlocks=" + freeBlocks +
131- "\n availableBlocks=" + availableBlocks +
132- "\n blockByteSize=" + blockByteSize +
133- "\n totalBytes=" + totalBytes +
134- "\n freeBytes=" + freeBytes +
135- "\n availableBytes=" + availableBytes ;
79+ @ SuppressWarnings ("TryWithIdenticalCatches" )
80+ public static List <String > getSDCardPaths () {
81+ StorageManager storageManager = (StorageManager ) Utils .getApp ()
82+ .getSystemService (Context .STORAGE_SERVICE );
83+ List <String > paths = new ArrayList <>();
84+ try {
85+ Method getVolumePathsMethod = StorageManager .class .getMethod ("getVolumePaths" );
86+ getVolumePathsMethod .setAccessible (true );
87+ Object invoke = getVolumePathsMethod .invoke (storageManager );
88+ paths = Arrays .asList ((String []) invoke );
89+ } catch (NoSuchMethodException e ) {
90+ e .printStackTrace ();
91+ } catch (IllegalAccessException e ) {
92+ e .printStackTrace ();
93+ } catch (InvocationTargetException e ) {
94+ e .printStackTrace ();
13695 }
96+ return paths ;
13797 }
13898}
0 commit comments