2017-04-19 116 views
3

我有一个应用程序允许选择与外部应用程序的照片。然后,我从uri中获取照片的路径,并将其用于内部操作。从谷歌照片应用程序从Uri获取路径

当用户使用Google照片选择一张照片时,如果图片在本地存储,那么下一个代码完美工作。但如果图片在云中,则的结果cursor.getString(index)为空。

我已经寻找一些信息,但不知道该解决方案

final String[] projection = { "_data" }; 
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null); 

if (cursor != null && cursor.moveToFirst()) { 
    final int index = cursor.getColumnIndexOrThrow("_data"); 
    return cursor.getString(index); 
} 

谢谢!

+0

看起来像这样重复? http://stackoverflow.com/questions/30527045/choosing-photo-using-new-google-photos-app-is-broken –

+0

@ user2765258我看到那篇文章。但不是一个好的解决方案。即使用户说接受它是因为解决了问题,但并不是他实施的完整解决方案。谢谢您 – adalPaRi

回答

3

最后,根据@CommonsWare的回答和关于这个问题的上一篇文章,我解决了从uri获取InputStream,应对一个新的临时文件并将路径传递给我需要使用的函数。

这里是simplificated代码:

public String getImagePathFromInputStreamUri(Uri uri) { 
    InputStream inputStream = null; 
    String filePath = null; 

    if (uri.getAuthority() != null) { 
     try { 
      inputStream = getContentResolver().openInputStream(uri); // context needed 
      File photoFile = createTemporalFileFrom(inputStream); 

      filePath = photoFile.getPath(); 

     } catch (FileNotFoundException e) { 
      // log 
     } catch (IOException e) { 
      // log 
     }finally { 
      try { 
       inputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    return filePath; 
} 

private File createTemporalFileFrom(InputStream inputStream) throws IOException { 
    File targetFile = null; 

    if (inputStream != null) { 
     int read; 
     byte[] buffer = new byte[8 * 1024]; 

     targetFile = createTemporalFile(); 
     OutputStream outputStream = new FileOutputStream(targetFile); 

     while ((read = inputStream.read(buffer)) != -1) { 
      outputStream.write(buffer, 0, read); 
     } 
     outputStream.flush(); 

     try { 
      outputStream.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    return targetFile; 
} 

private File createTemporalFile() { 
    return new File(getExternalCacheDir(), "tempFile.jpg"); // context needed 
} 
1

当用户使用Google照片选择一张照片时,如果图片在本地存储,那么下一个代码完美工作。

不一定。没有要求Uri_data列回应query()。不要求它返回的值对您有用(例如,您无法访问的内部存储或可移动存储上的文件)。

如果您需要将照片加载到ImageView,请将Uri转换为an image-loading library,如毕加索。

如果您需要照片的字节,请使用openInputStream()ContentResolver获取由Uri标识的内容的InputStream。请在后台线程上打开并从InputStream中读取。

+0

谢谢,但事实是,由于内部要求,我需要真正的路径。我不会显示或操纵图像,只需将路径传递给已实施的后端服务即可。 – adalPaRi

+2

@adalPaRi:没有“真正的路径”。如果您需要一个文件,欢迎您使用'openInputStream()'中的'InputStream'和一个'FileOutputStream'来创建一个文件,并将它复制到您控制的某个文件中。 – CommonsWare