3232import android .os .Environment ;
3333import android .provider .DocumentsContract ;
3434import android .provider .MediaStore ;
35+ import android .provider .OpenableColumns ;
36+ import android .support .annotation .NonNull ;
37+ import android .support .annotation .Nullable ;
3538import android .text .TextUtils ;
3639import android .util .Log ;
3740import android .webkit .MimeTypeMap ;
3841
42+ import java .io .BufferedOutputStream ;
3943import java .io .File ;
4044import java .io .FileFilter ;
45+ import java .io .FileOutputStream ;
46+ import java .io .IOException ;
47+ import java .io .InputStream ;
4148import java .text .DecimalFormat ;
4249import java .util .Comparator ;
4350
@@ -272,7 +279,6 @@ public static String getDataColumn(Context context, Uri uri, String selection,
272279 *
273280 * @param context The context.
274281 * @param uri The Uri to query.
275- * @see #isLocal(String)
276282 * @see #getFile(Context, Uri)
277283 * @author paulburke
278284 */
@@ -319,18 +325,42 @@ else if (isDownloadsDocument(uri)) {
319325 if (id .startsWith ("raw:" )) {
320326 return id .replaceFirst ("raw:" , "" );
321327 }
322- try {
323- final Uri contentUri = ContentUris .withAppendedId (
324- Uri .parse ("content://downloads/public_downloads" ), Long .valueOf (id ));
325- return getDataColumn (context , contentUri , null , null );
326- } catch (NumberFormatException e ) {
327- return null ;
328+ String [] contentUriPrefixesToTry = new String []{
329+ "content://downloads/public_downloads" ,
330+ "content://downloads/my_downloads" ,
331+ "content://downloads/all_downloads"
332+ };
333+
334+ for (String contentUriPrefix : contentUriPrefixesToTry ) {
335+ Uri contentUri = ContentUris .withAppendedId (Uri .parse (contentUriPrefix ), Long .valueOf (id ));
336+ try {
337+ String path = getDataColumn (context , contentUri , null , null );
338+ if (path != null ) {
339+ return path ;
340+ }
341+ } catch (Exception e ) {
342+ if (DEBUG ){
343+ e .printStackTrace ();
344+ }
345+ }
328346 }
347+ String path = getDataColumn (context , uri , null , null );
348+ if (path != null ) {
349+ return path ;
350+ }
351+
352+ // path could not be retrieved using ContentResolver, therefore copy file to accessible cache using streams
353+ String fileName = getFileName (context , uri );
354+ File cacheDir = getDocumentCacheDir (context );
355+ File file = generateFileName (fileName , cacheDir );
356+ String destinationPath = null ;
357+ if (file != null ) {
358+ destinationPath = file .getAbsolutePath ();
359+ saveFileFromUri (context , uri , destinationPath );
360+ }
361+
362+ return destinationPath ;
329363 }
330- // final Uri contentUri = ContentUris.withAppendedId(
331- // Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
332- //
333- // return getDataColumn(context, contentUri, null, null);
334364 }
335365 // MediaProvider
336366 else if (isMediaDocument (uri )) {
@@ -572,4 +602,121 @@ public static Intent createGetImageIntent() {
572602 intent .setType ("image/*" );
573603 return intent ;
574604 }
605+
606+ private static void saveFileFromUri (Context context , Uri uri , String destinationPath ) {
607+ InputStream is = null ;
608+ BufferedOutputStream bos = null ;
609+ try {
610+ is = context .getContentResolver ().openInputStream (uri );
611+ bos = new BufferedOutputStream (new FileOutputStream (destinationPath , false ));
612+ byte [] buf = new byte [1024 ];
613+ is .read (buf );
614+ do {
615+ bos .write (buf );
616+ } while (is .read (buf ) != -1 );
617+ } catch (IOException e ) {
618+ e .printStackTrace ();
619+ } finally {
620+ try {
621+ if (is != null ) is .close ();
622+ if (bos != null ) bos .close ();
623+ } catch (IOException e ) {
624+ e .printStackTrace ();
625+ }
626+ }
627+ }
628+
629+ public static String getFileName (@ NonNull Context context , Uri uri ) {
630+ String mimeType = context .getContentResolver ().getType (uri );
631+ String filename = null ;
632+
633+ if (mimeType == null && context != null ) {
634+ String path = getPath (context , uri );
635+ if (path == null ) {
636+ filename = getName (uri .toString ());
637+ } else {
638+ File file = new File (path );
639+ filename = file .getName ();
640+ }
641+ } else {
642+ Cursor returnCursor = context .getContentResolver ().query (uri , null ,
643+ null , null , null );
644+ if (returnCursor != null ) {
645+ int nameIndex = returnCursor .getColumnIndex (OpenableColumns .DISPLAY_NAME );
646+ returnCursor .moveToFirst ();
647+ filename = returnCursor .getString (nameIndex );
648+ returnCursor .close ();
649+ }
650+ }
651+
652+ return filename ;
653+ }
654+
655+ public static String getName (String filename ) {
656+ if (filename == null ) {
657+ return null ;
658+ }
659+ int index = filename .lastIndexOf ('/' );
660+ return filename .substring (index + 1 );
661+ }
662+
663+ public static File getDocumentCacheDir (@ NonNull Context context ) {
664+ File dir = new File (context .getCacheDir (), "documents" );
665+ if (!dir .exists ()) {
666+ dir .mkdirs ();
667+ }
668+ logDir (context .getCacheDir ());
669+ logDir (dir );
670+
671+ return dir ;
672+ }
673+
674+ private static void logDir (File dir ) {
675+ if (!DEBUG ) return ;
676+ Log .d (TAG , "Dir=" + dir );
677+ File [] files = dir .listFiles ();
678+ for (File file : files ) {
679+ Log .d (TAG , "File=" + file .getPath ());
680+ }
681+ }
682+
683+ @ Nullable
684+ public static File generateFileName (@ Nullable String name , File directory ) {
685+ if (name == null ) {
686+ return null ;
687+ }
688+
689+ File file = new File (directory , name );
690+
691+ if (file .exists ()) {
692+ String fileName = name ;
693+ String extension = "" ;
694+ int dotIndex = name .lastIndexOf ('.' );
695+ if (dotIndex > 0 ) {
696+ fileName = name .substring (0 , dotIndex );
697+ extension = name .substring (dotIndex );
698+ }
699+
700+ int index = 0 ;
701+
702+ while (file .exists ()) {
703+ index ++;
704+ name = fileName + '(' + index + ')' + extension ;
705+ file = new File (directory , name );
706+ }
707+ }
708+
709+ try {
710+ if (!file .createNewFile ()) {
711+ return null ;
712+ }
713+ } catch (IOException e ) {
714+ Log .w (TAG , e );
715+ return null ;
716+ }
717+
718+ logDir (directory );
719+
720+ return file ;
721+ }
575722}
0 commit comments