|
@@ -7,7 +7,41 @@ import com.kdanmobile.reader.utils.UriToPathUtil
|
|
|
import java.io.File
|
|
|
import java.io.FileNotFoundException
|
|
|
import java.net.URLEncoder
|
|
|
-import java.util.regex.Pattern
|
|
|
+
|
|
|
+/**
|
|
|
+ * When PDF Reader opens a file which is not in the 'KdanPDFReader' folder,
|
|
|
+ * the target file would be copied into that folder.
|
|
|
+ *
|
|
|
+ * In order to determine the file is in the 'KdanPDFReader' folder or not,
|
|
|
+ * we need to know its absolute path.
|
|
|
+ *
|
|
|
+ * If a user launches PDF Reader by a third-party application,
|
|
|
+ * that application would send PDF Reader a uri packaged in intent.
|
|
|
+ *
|
|
|
+ * The uri is generated by the content provider of that application,
|
|
|
+ * and only its content resolver knows how to resolve it.
|
|
|
+ *
|
|
|
+ * The uri may be encoded or even may look like a random string,
|
|
|
+ * and there is no common specification among different applications.
|
|
|
+ *
|
|
|
+ * We use the function CopyFileInfoFactory::getFilePathFromUri (actually UriToPathUtil::getPath in most case) to get absolute file path through uri.
|
|
|
+ *
|
|
|
+ * However, sometimes the UriToPathUtil::getPath function may not work well (due to the wrong implementation of content provider of third-party applications),
|
|
|
+ *
|
|
|
+ * In that case, we would try to use a workaround to fix it.
|
|
|
+ *
|
|
|
+ * The workaround: we try to find whether a file name '.../KdanPDFReader/${filename of decoded uri}' or '.../KdanPDFReader/${filename of raw uri} exists of not,
|
|
|
+ * and we consider the file as the target if the file exists.
|
|
|
+ *
|
|
|
+ * If finally the workaround still fails, we cannot get the correct file path.
|
|
|
+ *
|
|
|
+ * We always copy files when we do not know those files are in the 'KdanPDFReader' folder or not.
|
|
|
+ *
|
|
|
+ * Note: uri.path / uri.pathSegments / uri.lastPathSegment /... is automatically decoded even if the raw uri is not encoded,
|
|
|
+ * and it would cause some problems if the raw file path contains '%' characters.
|
|
|
+ *
|
|
|
+ * To avoid those problems, we need to additionally encode each segment of the raw uri in the above case.
|
|
|
+ */
|
|
|
|
|
|
class CopyFileInfoFactory {
|
|
|
fun createInfo(applicationContext: Context, intent: Intent, kdanPdfReaderFolder: File): CopyFileInfo {
|
|
@@ -26,17 +60,26 @@ class CopyFileInfoFactory {
|
|
|
if (null == uri) return null
|
|
|
var filePath = UriToPathUtil.getInstance().getPath(applicationContext, uri)
|
|
|
// workaround
|
|
|
- if (filePath.isNullOrEmpty() && null != uri.path) {
|
|
|
- val folderName = kdanPdfReaderFolder.name
|
|
|
- val pattern = Pattern.compile("$folderName/.*\\.(([Pp][Dd][Ff])|([Ee][Pp][Uu][Bb]))")
|
|
|
- val matcher = pattern.matcher(uri.path)
|
|
|
- if (matcher.find()) {
|
|
|
- val path = "${kdanPdfReaderFolder.absolutePath}/${matcher.group().substring(folderName.length)}"
|
|
|
- val file = File(path)
|
|
|
- if (file.exists()) {
|
|
|
- filePath = file.absolutePath
|
|
|
+ if (filePath.isNullOrEmpty()) {
|
|
|
+ val folderName = if (kdanPdfReaderFolder.name.last() == File.separatorChar) kdanPdfReaderFolder.name else (kdanPdfReaderFolder.name + File.separatorChar)
|
|
|
+
|
|
|
+ fun fixFilePath(path: String) {
|
|
|
+ val index = path.indexOf(folderName)
|
|
|
+ if (index != -1) {
|
|
|
+ val filename = path.substring(index + folderName.length)
|
|
|
+ val file = File("${kdanPdfReaderFolder.absolutePath}/$filename")
|
|
|
+ if (file.exists()) {
|
|
|
+ filePath = file.absolutePath
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ uri.path?.also {
|
|
|
+ fixFilePath(it)
|
|
|
+ }
|
|
|
+ if (null == filePath) {
|
|
|
+ fixFilePath(uri.toString())
|
|
|
+ }
|
|
|
}
|
|
|
if (null != filePath && !File(filePath).exists()) {
|
|
|
filePath = Uri.decode(filePath)
|