Changeset View
Changeset View
Standalone View
Standalone View
src/org/kde/kdeconnect/Helpers/StorageHelper.java
Show All 14 Lines | |||||
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. | ||
16 | * | 16 | * | ||
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | package org.kde.kdeconnect.Helpers; | 21 | package org.kde.kdeconnect.Helpers; | ||
22 | 22 | | |||
23 | import android.annotation.TargetApi; | ||||
24 | import android.content.Context; | ||||
25 | import android.net.Uri; | ||||
26 | import android.os.Build; | ||||
23 | import android.os.Environment; | 27 | import android.os.Environment; | ||
28 | import android.provider.DocumentsContract; | ||||
24 | 29 | | |||
25 | import java.io.BufferedReader; | 30 | import java.io.BufferedReader; | ||
26 | import java.io.File; | 31 | import java.io.File; | ||
27 | import java.io.FileReader; | 32 | import java.io.FileReader; | ||
28 | import java.util.ArrayList; | 33 | import java.util.ArrayList; | ||
29 | import java.util.Arrays; | 34 | import java.util.Arrays; | ||
30 | import java.util.HashSet; | 35 | import java.util.HashSet; | ||
31 | import java.util.List; | 36 | import java.util.List; | ||
32 | import java.util.Scanner; | 37 | import java.util.Scanner; | ||
33 | import java.util.StringTokenizer; | 38 | import java.util.StringTokenizer; | ||
34 | 39 | | |||
40 | import androidx.annotation.NonNull; | ||||
41 | | ||||
35 | //Code from http://stackoverflow.com/questions/9340332/how-can-i-get-the-list-of-mounted-external-storage-of-android-device/19982338#19982338 | 42 | //Code from http://stackoverflow.com/questions/9340332/how-can-i-get-the-list-of-mounted-external-storage-of-android-device/19982338#19982338 | ||
36 | //modified to work on Lollipop and other devices | 43 | //modified to work on Lollipop and other devices | ||
37 | public class StorageHelper { | 44 | public class StorageHelper { | ||
38 | 45 | | |||
39 | public static class StorageInfo { | 46 | public static class StorageInfo { | ||
40 | 47 | | |||
41 | public final String path; | 48 | public final String path; | ||
42 | public final boolean readonly; | 49 | public final boolean readonly; | ||
43 | public final boolean removable; | 50 | public final boolean removable; | ||
44 | public final int number; | 51 | public final int number; | ||
45 | 52 | | |||
46 | StorageInfo(String path, boolean readonly, boolean removable, int number) { | 53 | public StorageInfo(String path, boolean readonly, boolean removable, int number) { | ||
47 | this.path = path; | 54 | this.path = path; | ||
48 | this.readonly = readonly; | 55 | this.readonly = readonly; | ||
49 | this.removable = removable; | 56 | this.removable = removable; | ||
50 | this.number = number; | 57 | this.number = number; | ||
51 | } | 58 | } | ||
52 | 59 | | |||
53 | } | 60 | } | ||
54 | 61 | | |||
Show All 17 Lines | 68 | public static List<StorageInfo> getStorageList() { | |||
72 | int cur_removable_number = 1; | 79 | int cur_removable_number = 1; | ||
73 | 80 | | |||
74 | if (def_path_available) { | 81 | if (def_path_available) { | ||
75 | paths.add(def_path); | 82 | paths.add(def_path); | ||
76 | list.add(0, new StorageInfo(def_path, def_path_readonly, def_path_removable, def_path_removable ? cur_removable_number++ : -1)); | 83 | list.add(0, new StorageInfo(def_path, def_path_readonly, def_path_removable, def_path_removable ? cur_removable_number++ : -1)); | ||
77 | } | 84 | } | ||
78 | 85 | | |||
79 | File storage = new File("/storage/"); | 86 | File storage = new File("/storage/"); | ||
80 | if (storage.exists() && storage.isDirectory()) { | 87 | if (storage.exists() && storage.isDirectory() && storage.canRead()) { | ||
81 | String mounts = null; | 88 | String mounts = null; | ||
82 | try (Scanner scanner = new Scanner(new File("/proc/mounts"))) { | 89 | try (Scanner scanner = new Scanner(new File("/proc/mounts"))) { | ||
83 | mounts = scanner.useDelimiter("\\A").next(); | 90 | mounts = scanner.useDelimiter("\\A").next(); | ||
84 | } catch (Exception e) { | 91 | } catch (Exception e) { | ||
85 | e.printStackTrace(); | 92 | e.printStackTrace(); | ||
86 | } | 93 | } | ||
87 | 94 | | |||
88 | File dirs[] = storage.listFiles(); | 95 | File dirs[] = storage.listFiles(); | ||
89 | for (File dir : dirs) { | 96 | for (File dir : dirs) { | ||
90 | //Log.e("getStorageList", "path: "+dir.getAbsolutePath()); | 97 | //Log.e("getStorageList", "path: "+dir.getAbsolutePath()); | ||
91 | if (dir.isDirectory() && dir.canRead() && dir.canExecute()) { | 98 | if (dir.isDirectory() && dir.canRead() && dir.canExecute()) { | ||
92 | String path, path2; | 99 | String path, path2; | ||
93 | path2 = dir.getAbsolutePath(); | 100 | path2 = dir.getAbsolutePath(); | ||
94 | try { | 101 | try { | ||
95 | //Log.e(dir.getAbsolutePath(), dir.getCanonicalPath()); | 102 | //Log.e(dir.getAbsolutePath(), dir.getCanonicalPath()); | ||
96 | path = dir.getCanonicalPath(); | 103 | path = dir.getCanonicalPath(); | ||
97 | } catch (Exception e) { | 104 | } catch (Exception e) { | ||
98 | path = path2; | 105 | path = path2; | ||
99 | } | 106 | } | ||
100 | if (!path.startsWith("/storage/emulated") || dirs.length == 1) { | 107 | if (!path.startsWith("/storage/emulated") || dirs.length == 1) { | ||
101 | if (!paths.contains(path) && !paths.contains(path2)) { | 108 | if (!paths.contains(path) && !paths.contains(path2)) { | ||
102 | if (mounts == null || mounts.contains(path) || mounts.contains(path2)) { | 109 | if (mounts == null || mounts.contains(path) || mounts.contains(path2)) { | ||
103 | list.add(0, new StorageInfo(path, false, true, cur_removable_number++)); | 110 | list.add(0, new StorageInfo(path, dir.canWrite(), true, cur_removable_number++)); | ||
104 | paths.add(path); | 111 | paths.add(path); | ||
105 | } | 112 | } | ||
106 | } | 113 | } | ||
107 | } | 114 | } | ||
108 | } | 115 | } | ||
109 | } | 116 | } | ||
110 | } else { | 117 | } else { | ||
111 | 118 | | |||
Show All 36 Lines | 135 | for (String line : entries) { | |||
148 | } | 155 | } | ||
149 | } | 156 | } | ||
150 | 157 | | |||
151 | } | 158 | } | ||
152 | 159 | | |||
153 | return list; | 160 | return list; | ||
154 | } | 161 | } | ||
155 | 162 | | |||
163 | /* treeUri documentId | ||||
164 | * ================================================================================================== | ||||
165 | * content://com.android.providers.downloads.documents/tree/downloads => downloads | ||||
166 | * content://com.android.externalstorage.documents/tree/1715-1D1F: => 1715-1D1F: | ||||
167 | * content://com.android.externalstorage.documents/tree/1715-1D1F:My%20Photos => 1715-1D1F:My Photos | ||||
168 | * content://com.android.externalstorage.documents/tree/primary: => primary: | ||||
169 | * content://com.android.externalstorage.documents/tree/primary:DCIM => primary:DCIM | ||||
170 | * content://com.android.externalstorage.documents/tree/primary:Download/bla => primary:Download/bla | ||||
171 | */ | ||||
172 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) | ||||
173 | public static String getDisplayName(@NonNull Context context, @NonNull Uri treeUri) { | ||||
174 | List<String> pathSegments = treeUri.getPathSegments(); | ||||
175 | | ||||
176 | if (!pathSegments.get(0).equals("tree")) { | ||||
177 | throw new IllegalArgumentException("treeUri is not valid"); | ||||
178 | } | ||||
179 | | ||||
180 | String documentId = DocumentsContract.getTreeDocumentId(treeUri); | ||||
181 | | ||||
182 | int colonIdx = pathSegments.get(1).indexOf(':'); | ||||
183 | | ||||
184 | if (colonIdx >= 0) { | ||||
185 | String tree = pathSegments.get(1).substring(0, colonIdx + 1); | ||||
186 | | ||||
187 | if (!documentId.equals(tree)) { | ||||
188 | return documentId.substring(tree.length()); | ||||
189 | } else { | ||||
190 | return documentId.substring(0, colonIdx); | ||||
191 | } | ||||
192 | } | ||||
193 | | ||||
194 | return documentId; | ||||
195 | } | ||||
156 | } | 196 | } |