Skip to content

Commit 6822d1b

Browse files
committed
Improved compatibility with file managers "Files" (com.android.externalstorage.documents)
and "Files" (com.google.android.apps.nbu.files).
1 parent dd51509 commit 6822d1b

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

android/src/org/coolreader/CoolReader.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Main Class
22
package org.coolreader;
33

4-
import java.io.File;
54
import java.lang.reflect.Field;
65
import java.util.ArrayList;
76
import java.util.Date;
@@ -44,6 +43,7 @@
4443

4544
import android.Manifest;
4645
import android.content.BroadcastReceiver;
46+
import android.content.ContentResolver;
4747
import android.content.Context;
4848
import android.content.DialogInterface;
4949
import android.content.Intent;
@@ -301,10 +301,14 @@ private boolean processIntent(Intent intent) {
301301
if (intent == null)
302302
return false;
303303
String fileToOpen = null;
304+
String scheme = null;
305+
String host = null;
304306
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
305307
Uri uri = intent.getData();
306308
intent.setData(null);
307309
if (uri != null) {
310+
scheme = uri.getScheme();
311+
host = uri.getHost();
308312
if (uri.getEncodedPath().contains("%00"))
309313
fileToOpen = uri.getEncodedPath();
310314
else
@@ -324,18 +328,29 @@ private boolean processIntent(Intent intent) {
324328
fileToOpen = fileToOpen.replace("%00", "@/");
325329
fileToOpen = Uri.decode(fileToOpen);
326330
}
327-
if (fileToOpen.startsWith("/document/primary:")) {
328-
// scheme="content", host="com.android.externalstorage.documents"
329-
// decode special uri form: /document/primary:<somebody>
330-
File[] dataDirs = Engine.getStorageDirectories(false);
331-
if (dataDirs != null && dataDirs.length > 0) {
332-
fileToOpen = fileToOpen.replace("/document/primary:", dataDirs[0].getAbsolutePath() + "/");
331+
if ("content".equals(scheme)) {
332+
if ("com.android.externalstorage.documents".equals(host)) {
333+
// application "Files" by Google, package="com.android.externalstorage.documents"
334+
if (fileToOpen.matches("^/document/.*:.*$")) {
335+
// decode special uri form: /document/primary:<somebody>
336+
// /document/XXXX-XXXX:<somebody>
337+
String shortcut = fileToOpen.replaceFirst("^/document/(.*):.*$", "$1");
338+
String mountRoot = Engine.getMountRootByShortcut(shortcut);
339+
if (mountRoot != null)
340+
fileToOpen = fileToOpen.replaceFirst("^/document/.*:(.*)$", mountRoot + "/$1");
341+
}
342+
} else if ("com.google.android.apps.nbu.files.provider".equals(host)) {
343+
// application "Files" by Google, package="com.google.android.apps.nbu.files"
344+
if (fileToOpen.startsWith("/1////")) {
345+
// skip "/1///"
346+
fileToOpen = fileToOpen.substring(5);
347+
fileToOpen = Uri.decode(fileToOpen);
348+
} else if (fileToOpen.startsWith("/1/file:///")) {
349+
// skip "/1/file://"
350+
fileToOpen = fileToOpen.substring(10);
351+
fileToOpen = Uri.decode(fileToOpen);
352+
}
333353
}
334-
} else if (fileToOpen.startsWith("/1////")) {
335-
// scheme="content", host="com.google.android.apps.nbu.files.provider"
336-
// caused by "Google Files", package="com.google.android.apps.nbu.files"
337-
// skip "/1///"
338-
fileToOpen = fileToOpen.substring(5);
339354
}
340355
}
341356
if (fileToOpen != null) {

android/src/org/coolreader/crengine/Engine.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,36 @@ public static Map<String, String> getMountedRootsMap() {
6868
return mountedRootsMap;
6969
}
7070

71+
/**
72+
* @param shortcut File system shortcut that return application "Files" by Google (package="com.android.externalstorage.documents")
73+
* "primary" for internal storage,
74+
* "XXXX-XXXX" (file system serial number) for any external storage like sdcard, usb disk, etc.
75+
* @return path to mount root for given file system.
76+
*/
77+
public static String getMountRootByShortcut(String shortcut) {
78+
String mountRoot = null;
79+
if ("primary".equals(shortcut)) {
80+
// "/document/primary:/.*"
81+
for (Map.Entry<String, String> entry : mountedRootsMap.entrySet()) {
82+
if ("SD".equals(entry.getValue())) {
83+
mountRoot = entry.getKey();
84+
break;
85+
}
86+
}
87+
} else {
88+
// "/document/XXXX-XXXX/.*"
89+
String pattern = "/storage/" + shortcut;
90+
for (Map.Entry<String, String> entry : mountedRootsMap.entrySet()) {
91+
// Android 6 ext storage, @see addMountRoot()
92+
if ("EXT SD".equals(entry.getValue()) && entry.getKey().startsWith(pattern)) {
93+
mountRoot = entry.getKey();
94+
break;
95+
}
96+
}
97+
}
98+
return mountRoot;
99+
}
100+
71101
public boolean isRootsMountPoint(String path) {
72102
if (mountedRootsMap == null)
73103
return false;

0 commit comments

Comments
 (0)