11// Main Class
22package org .coolreader ;
33
4+ import java .io .File ;
5+ import java .io .FileNotFoundException ;
6+ import java .io .InputStream ;
47import java .lang .reflect .Field ;
58import java .util .ArrayList ;
69import java .util .Date ;
4346
4447import android .Manifest ;
4548import android .content .BroadcastReceiver ;
49+ import android .content .ContentResolver ;
4650import android .content .Context ;
4751import android .content .DialogInterface ;
4852import android .content .Intent ;
@@ -275,16 +279,6 @@ public void setFullscreen(boolean fullscreen) {
275279 mReaderFrame .updateFullscreen (fullscreen );
276280 }
277281
278- private String extractFileName (Uri uri ) {
279- if (uri != null ) {
280- if (uri .equals (Uri .parse ("file:///" )))
281- return null ;
282- else
283- return uri .getPath ();
284- }
285- return null ;
286- }
287-
288282 @ Override
289283 protected void onNewIntent (Intent intent ) {
290284 log .i ("onNewIntent : " + intent );
@@ -300,63 +294,19 @@ private boolean processIntent(Intent intent) {
300294 if (intent == null )
301295 return false ;
302296 String fileToOpen = null ;
303- String scheme = null ;
304- String host = null ;
297+ Uri uri = null ;
305298 if (Intent .ACTION_VIEW .equals (intent .getAction ())) {
306- Uri uri = intent .getData ();
299+ uri = intent .getData ();
307300 intent .setData (null );
308301 if (uri != null ) {
309- scheme = uri .getScheme ();
310- host = uri .getHost ();
311- if (uri .getEncodedPath ().contains ("%00" ))
312- fileToOpen = uri .getEncodedPath ();
313- else
314- fileToOpen = uri .getPath ();
315- // if (fileToOpen.startsWith("file://"))
316- // fileToOpen = fileToOpen.substring("file://".length());
302+ fileToOpen = filePathFromUri (uri );
317303 }
318304 }
319305 if (fileToOpen == null && intent .getExtras () != null ) {
320306 log .d ("extras=" + intent .getExtras ());
321307 fileToOpen = intent .getExtras ().getString (OPEN_FILE_PARAM );
322308 }
323309 if (fileToOpen != null ) {
324- // parse uri from system filemanager
325- if (fileToOpen .contains ("%00" )) {
326- // splitter between archive file name and inner file.
327- fileToOpen = fileToOpen .replace ("%00" , "@/" );
328- fileToOpen = Uri .decode (fileToOpen );
329- }
330- if ("content" .equals (scheme )) {
331- if ("com.android.externalstorage.documents" .equals (host )) {
332- // application "Files" by Google, package="com.android.externalstorage.documents"
333- if (fileToOpen .matches ("^/document/.*:.*$" )) {
334- // decode special uri form: /document/primary:<somebody>
335- // /document/XXXX-XXXX:<somebody>
336- String shortcut = fileToOpen .replaceFirst ("^/document/(.*):.*$" , "$1" );
337- String mountRoot = Engine .getMountRootByShortcut (shortcut );
338- if (mountRoot != null )
339- fileToOpen = fileToOpen .replaceFirst ("^/document/.*:(.*)$" , mountRoot + "/$1" );
340- }
341- } else if ("com.google.android.apps.nbu.files.provider" .equals (host )) {
342- // application "Files" by Google, package="com.google.android.apps.nbu.files"
343- if (fileToOpen .startsWith ("/1////" )) {
344- // skip "/1///"
345- fileToOpen = fileToOpen .substring (5 );
346- fileToOpen = Uri .decode (fileToOpen );
347- } else if (fileToOpen .startsWith ("/1/file:///" )) {
348- // skip "/1/file://"
349- fileToOpen = fileToOpen .substring (10 );
350- fileToOpen = Uri .decode (fileToOpen );
351- }
352- }
353- }
354- }
355- if (fileToOpen != null ) {
356- // patch for opening of books from ReLaunch (under Nook Simple Touch)
357- while (fileToOpen .indexOf ("%2F" ) >= 0 ) {
358- fileToOpen = fileToOpen .replace ("%2F" , "/" );
359- }
360310 log .d ("FILE_TO_OPEN = " + fileToOpen );
361311 final String finalFileToOpen = fileToOpen ;
362312 loadDocument (fileToOpen , new Runnable () {
@@ -379,12 +329,105 @@ public void onDismiss(DialogInterface dialog) {
379329 }
380330 });
381331 return true ;
332+ } else if (null != uri ) {
333+ log .d ("URI_TO_OPEN = " + uri );
334+ final String uriString = uri .toString ();
335+ loadDocumentFromUri (uri , new Runnable () {
336+ @ Override
337+ public void run () {
338+ BackgroundThread .instance ().postGUI (new Runnable () {
339+ @ Override
340+ public void run () {
341+ // if document not loaded show error & then root window
342+ ErrorDialog errDialog = new ErrorDialog (CoolReader .this , CoolReader .this .getString (R .string .error ), CoolReader .this .getString (R .string .cant_open_file , uriString ));
343+ errDialog .setOnDismissListener (new DialogInterface .OnDismissListener () {
344+ @ Override
345+ public void onDismiss (DialogInterface dialog ) {
346+ showRootWindow ();
347+ }
348+ });
349+ errDialog .show ();
350+ }
351+ }, 500 );
352+ }
353+ });
354+ return true ;
382355 } else {
383356 log .d ("No file to open" );
384357 return false ;
385358 }
386359 }
387360
361+ private String filePathFromUri (Uri uri ) {
362+ if (null == uri )
363+ return null ;
364+ String filePath = null ;
365+ String scheme = uri .getScheme ();
366+ String host = uri .getHost ();
367+ if ("file" .equals (scheme )) {
368+ filePath = uri .getPath ();
369+ // patch for opening of books from ReLaunch (under Nook Simple Touch)
370+ if (null != filePath ) {
371+ if (filePath .contains ("%2F" ))
372+ filePath = filePath .replace ("%2F" , "/" );
373+ }
374+ } else if ("content" .equals (scheme )) {
375+ if (uri .getEncodedPath ().contains ("%00" ))
376+ filePath = uri .getEncodedPath ();
377+ else
378+ filePath = uri .getPath ();
379+ if (null != filePath ) {
380+ // parse uri from system filemanager
381+ if (filePath .contains ("%00" )) {
382+ // splitter between archive file name and inner file.
383+ filePath = filePath .replace ("%00" , "@/" );
384+ filePath = Uri .decode (filePath );
385+ }
386+ if ("com.android.externalstorage.documents" .equals (host )) {
387+ // application "Files" by Google, package="com.android.externalstorage.documents"
388+ if (filePath .matches ("^/document/.*:.*$" )) {
389+ // decode special uri form: /document/primary:<somebody>
390+ // /document/XXXX-XXXX:<somebody>
391+ String shortcut = filePath .replaceFirst ("^/document/(.*):.*$" , "$1" );
392+ String mountRoot = Engine .getMountRootByShortcut (shortcut );
393+ if (mountRoot != null ) {
394+ filePath = filePath .replaceFirst ("^/document/.*:(.*)$" , mountRoot + "/$1" );
395+ }
396+ }
397+ } else if ("com.google.android.apps.nbu.files.provider" .equals (host )) {
398+ // application "Files" by Google, package="com.google.android.apps.nbu.files"
399+ if (filePath .startsWith ("/1////" )) {
400+ // skip "/1///"
401+ filePath = filePath .substring (5 );
402+ filePath = Uri .decode (filePath );
403+ } else if (filePath .startsWith ("/1/file:///" )) {
404+ // skip "/1/file://"
405+ filePath = filePath .substring (10 );
406+ filePath = Uri .decode (filePath );
407+ }
408+ } else {
409+ // Try some common conversions...
410+ if (filePath .startsWith ("/file%3A%2F%2F" )) {
411+ filePath = filePath .substring (14 );
412+ filePath = Uri .decode (filePath );
413+ if (filePath .contains ("%20" )) {
414+ filePath = filePath .replace ("%20" , " " );
415+ }
416+ }
417+ }
418+ }
419+ }
420+ File file ;
421+ int pos = filePath .indexOf ("@/" );
422+ if (pos > 0 )
423+ file = new File (filePath .substring (0 , pos ));
424+ else
425+ file = new File (filePath );
426+ if (!file .exists ())
427+ filePath = null ;
428+ return filePath ;
429+ }
430+
388431 @ Override
389432 protected void onPause () {
390433 super .onPause ();
@@ -915,6 +958,22 @@ public void run() {
915958 });
916959 }
917960
961+ public void loadDocumentFromUri (final Uri uri , final Runnable callback ) {
962+ runInReader (new Runnable () {
963+ @ Override
964+ public void run () {
965+ ContentResolver contentResolver = getContentResolver ();
966+ InputStream inputStream = null ;
967+ try {
968+ inputStream = contentResolver .openInputStream (uri );
969+ mReaderView .loadDocumentFromStream (inputStream , uri .getPath (), callback );
970+ } catch (FileNotFoundException e ) {
971+ callback .run ();
972+ }
973+ }
974+ });
975+ }
976+
918977 public void loadDocument (FileInfo item ) {
919978 loadDocument (item , null );
920979 }
0 commit comments