11
11
import android .net .Uri ;
12
12
import android .os .Build ;
13
13
import android .os .Environment ;
14
+ import android .os .storage .StorageManager ;
15
+ import android .os .storage .StorageVolume ;
14
16
import android .provider .DocumentsContract ;
15
17
import android .util .Log ;
16
18
import android .webkit .MimeTypeMap ;
20
22
import java .io .FileOutputStream ;
21
23
import java .io .InputStream ;
22
24
import java .io .OutputStream ;
25
+ import java .lang .reflect .Method ;
23
26
import java .util .ArrayList ;
24
27
import java .util .Comparator ;
28
+ import java .util .HashSet ;
25
29
import java .util .List ;
26
30
import java .util .Locale ;
27
31
@@ -48,14 +52,24 @@ public int compare( UriPermission a, UriPermission b )
48
52
49
53
private static final StringBuilder stringBuilder = new StringBuilder ();
50
54
51
- public static String GetExternalDrives ()
55
+ public static String GetExternalDrives ( Context context )
52
56
{
53
57
File primary = Environment .getExternalStorageDirectory ();
54
58
String primaryPath = primary .getAbsolutePath ();
59
+ String primaryCanonicalPath = primaryPath ;
60
+ try
61
+ {
62
+ primaryCanonicalPath = primary .getCanonicalPath ();
63
+ }
64
+ catch ( Exception e )
65
+ {
66
+ }
55
67
56
68
stringBuilder .setLength ( 0 );
57
69
stringBuilder .append ( primaryPath ).append ( ":" );
58
70
71
+ HashSet <String > potentialDrives = new HashSet <String >( 16 );
72
+
59
73
// Try paths saved at system environments
60
74
// Credit: https://stackoverflow.com/a/32088396/2373034
61
75
String strSDCardPath = System .getenv ( "SECONDARY_STORAGE" );
@@ -69,25 +83,7 @@ public static String GetExternalDrives()
69
83
{
70
84
String path = externalPaths [i ];
71
85
if ( path != null && path .length () > 0 )
72
- {
73
- File file = new File ( path );
74
- if ( file .exists () && file .isDirectory () && file .canRead () && !file .getAbsolutePath ().equalsIgnoreCase ( primaryPath ) )
75
- {
76
- String absolutePath = file .getAbsolutePath () + File .separator + "Android" ;
77
- if ( new File ( absolutePath ).exists () )
78
- {
79
- try
80
- {
81
- // Check if two paths lead to same storage (aliases)
82
- if ( !primary .getCanonicalPath ().equals ( file .getCanonicalPath () ) )
83
- stringBuilder .append ( file .getAbsolutePath () ).append ( ":" );
84
- }
85
- catch ( Exception e )
86
- {
87
- }
88
- }
89
- }
90
- }
86
+ potentialDrives .add ( path );
91
87
}
92
88
}
93
89
@@ -102,29 +98,51 @@ public static String GetExternalDrives()
102
98
File [] fileList = new File ( root ).listFiles ();
103
99
for ( File file : fileList )
104
100
{
105
- if ( file .exists () && file .isDirectory () && file .canRead () && !file .getAbsolutePath ().equalsIgnoreCase ( primaryPath ) )
106
- {
107
- String absolutePath = file .getAbsolutePath () + File .separator + "Android" ;
108
- if ( new File ( absolutePath ).exists () )
109
- {
110
- try
111
- {
112
- // Check if two paths lead to same storage (aliases)
113
- if ( !primary .getCanonicalPath ().equals ( file .getCanonicalPath () ) )
114
- stringBuilder .append ( file .getAbsolutePath () ).append ( ":" );
115
- }
116
- catch ( Exception ex )
117
- {
118
- }
119
- }
120
- }
101
+ if ( file .exists () && file .isDirectory () && file .canRead () )
102
+ potentialDrives .add ( file .getAbsolutePath () );
121
103
}
122
104
}
123
105
catch ( Exception e )
124
106
{
125
107
}
126
108
}
127
109
110
+ // This is the only working method on some Android 11+ devices (when Storage Access Framework isn't used)
111
+ if ( android .os .Build .VERSION .SDK_INT >= android .os .Build .VERSION_CODES .N )
112
+ {
113
+ try
114
+ {
115
+ Method getPath = StorageVolume .class .getMethod ( "getPath" );
116
+ StorageManager storageManager = (StorageManager ) context .getSystemService ( Context .STORAGE_SERVICE );
117
+ for ( StorageVolume volume : storageManager .getStorageVolumes () )
118
+ potentialDrives .add ( (String ) getPath .invoke ( volume ) );
119
+ }
120
+ catch ( Exception e )
121
+ {
122
+ }
123
+ }
124
+
125
+ for ( String potentialDrive : potentialDrives )
126
+ {
127
+ File file = new File ( potentialDrive );
128
+ if ( file .exists () && file .isDirectory () && file .canRead () && !file .getAbsolutePath ().equalsIgnoreCase ( primaryPath ) )
129
+ {
130
+ String absolutePath = file .getAbsolutePath () + File .separator + "Android" ;
131
+ if ( new File ( absolutePath ).exists () )
132
+ {
133
+ try
134
+ {
135
+ // Check if two paths lead to same storage (aliases)
136
+ if ( !primaryCanonicalPath .equals ( file .getCanonicalPath () ) )
137
+ stringBuilder .append ( file .getAbsolutePath () ).append ( ":" );
138
+ }
139
+ catch ( Exception ex )
140
+ {
141
+ }
142
+ }
143
+ }
144
+ }
145
+
128
146
return stringBuilder .toString ();
129
147
}
130
148
0 commit comments