2014-11-17 8 views
8

У меня есть файл для файла Uri.Получить путь к файлу из URI

Я использую этот код получает путь к файлу от Uri:

public String getRealPathFromURI(Uri contentUri) { 
    Cursor cursor = null; 
    try { 
     String[] proj = { MediaStore.Images.Media.DATA }; 
     cursor = mContext.getContentResolver().query(contentUri, proj, null, null, null); 
     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
     cursor.moveToFirst(); 
     return cursor.getString(column_index); 
    } catch (Exception e) { 
     Log.message(e.getMessage()); 
    } finally { 
     if (cursor != null) { 
      cursor.close(); 
     } 
    } 
    return null; 
} 

Если я выбираю изображение из приложения Галерея (Android 4.4.2, вооружить-эму),

uri.getPath = /external/images/media/16 and it work's fine (My file path: /storage/sdcard/Download/0_cf15a_7800a7e5_orig.jpg) 

Если я выбираю изображение из документов приложений (Android 4.4.2, руки-эму),

I have uri.getPath = /document/image:16 and function getRealPathFromURI returns null. 

Как вернуть правильный путь к файлу для Boths действия?

Мой код: -

@Override 
    public void onClick(View v) { 
     final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "Photohunt" + File.separator); 
     root.mkdirs(); 
     final String fname = Common.getUniqueImageFilename(); 
     final File sdImageMainDirectory = new File(root, fname); 
     outputFileUri = Uri.fromFile(sdImageMainDirectory); 
      // Camera. 
      final List<Intent> cameraIntents = new ArrayList<Intent>(); 
      final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
      final PackageManager packageManager = mContext.getPackageManager(); 
      final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0); 
      for(ResolveInfo res : listCam) { 
       final String packageName = res.activityInfo.packageName; 
       final Intent intent = new Intent(captureIntent); 
       intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); 
       intent.setPackage(packageName); 
      intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
       cameraIntents.add(intent); 
      } 

      // Filesystem. 
      final Intent galleryIntent = new Intent(); 
      galleryIntent.setType("image/*"); 
      galleryIntent.setAction(Intent.ACTION_GET_CONTENT); 

      // Chooser of filesystem options. 
      final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source"); 

      // Add the camera options. 
      chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{})); 

      startActivityForResult(chooserIntent, PICTURE_REQUEST_CODE); 
    } 

Handle результат деятельности:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) 
{ 
    if(resultCode == Activity.RESULT_OK) 
    { 
     if(requestCode == PICTURE_REQUEST_CODE) 
     { 
      final boolean isCamera; 
      if(data == null) 
      { 
       isCamera = true; 
      } 
      else 
      { 
       final String action = data.getAction(); 
       if(action == null) 
       { 
        isCamera = false; 
       } 
       else 
       { 
        isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
       } 
      } 

      Uri selectedImageUri; 
      if(isCamera) 
      { 
       selectedImageUri = outputFileUri; 
      } 
      else 
      { 
       selectedImageUri = data == null ? null : data.getData(); 
      } 

      Log.variable("uri", selectedImageUri.getPath()); 
      ConfirmImageFragment fragment = new ConfirmImageFragment(selectedImageUri, mContestId); 
      FragmentTransaction transaction = getSherlockActivity().getSupportFragmentManager().beginTransaction(); 
      transaction.replace(R.id.main_container, fragment); 
      transaction.addToBackStack(null); 
      transaction.commit(); 
     } 
    } 

    super.onActivityResult(requestCode, resultCode, data); 
} 

Загрузка выбранного файла в ImageView прекрасно работает как для государства:

private void loadImage() { 
    try { 
     Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), mUri); 
     mImage.setImageBitmap(bitmap); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

ответ

18

Решение:

public class RealPathUtil { 

    @SuppressLint("NewApi") 
    public static String getRealPathFromURI_API19(Context context, Uri uri){ 
     String filePath = ""; 
     String wholeID = DocumentsContract.getDocumentId(uri); 

     // Split at colon, use second item in the array 
     String id = wholeID.split(":")[1]; 

     String[] column = { MediaStore.Images.Media.DATA };  

     // where id is equal to    
     String sel = MediaStore.Images.Media._ID + "=?"; 

     Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
            column, sel, new String[]{ id }, null); 

     int columnIndex = cursor.getColumnIndex(column[0]); 

     if (cursor.moveToFirst()) { 
      filePath = cursor.getString(columnIndex); 
     } 
     cursor.close(); 
     return filePath; 
    } 


    @SuppressLint("NewApi") 
    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) { 
      String[] proj = { MediaStore.Images.Media.DATA }; 
      String result = null; 

      CursorLoader cursorLoader = new CursorLoader(
        context, 
      contentUri, proj, null, null, null);   
      Cursor cursor = cursorLoader.loadInBackground(); 

      if(cursor != null){ 
      int column_index = 
      cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
      cursor.moveToFirst(); 
      result = cursor.getString(column_index); 
      } 
      return result; 
    } 

    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){ 
       String[] proj = { MediaStore.Images.Media.DATA }; 
       Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); 
       int column_index 
      = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
       cursor.moveToFirst(); 
       return cursor.getString(column_index); 
    } 
} 

http://hmkcode.com/android-display-selected-image-and-its-real-path/

+0

спасибо! Ты спасешь мой день;). – leegor

+0

DocumentsContract.getDocumentId (uri); его не удалось решить, как организовать импорт DocumentContract – Madhu

+0

@Madhu см. ссылку после кода – Artem

0

Я думаю, что это должно сработать. Обобщенный код для получения URI из пути:

String path = yourAndroidURI.uri.getPath() 
File file = new File(new URI(path)); 
+2

Исключение: URI не является абсолютным:/document/image: 16 – Artem

2

Более простой вариант принятого ответа, который определит уровень API и использовать правильный метод:

@TargetApi(Build.VERSION_CODES.KITKAT) 
public static String getFilePath(Context context, Uri uri) 
{ 
    int currentApiVersion; 
    try 
    { 
     currentApiVersion = android.os.Build.VERSION.SDK_INT; 
    } 
    catch(NumberFormatException e) 
    { 
     //API 3 will crash if SDK_INT is called 
     currentApiVersion = 3; 
    } 
    if (currentApiVersion >= Build.VERSION_CODES.KITKAT) 
    { 
     String filePath = ""; 
     String wholeID = DocumentsContract.getDocumentId(uri); 

     // Split at colon, use second item in the array 
     String id = wholeID.split(":")[1]; 

     String[] column = {MediaStore.Images.Media.DATA}; 

     // where id is equal to 
     String sel = MediaStore.Images.Media._ID + "=?"; 

     Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
       column, sel, new String[]{id}, null); 

     int columnIndex = cursor.getColumnIndex(column[0]); 

     if (cursor.moveToFirst()) 
     { 
      filePath = cursor.getString(columnIndex); 
     } 
     cursor.close(); 
     return filePath; 
    } 
    else if (currentApiVersion <= Build.VERSION_CODES.HONEYCOMB_MR2 && currentApiVersion >= Build.VERSION_CODES.HONEYCOMB) 

    { 
     String[] proj = {MediaStore.Images.Media.DATA}; 
     String result = null; 

     CursorLoader cursorLoader = new CursorLoader(
       context, 
       uri, proj, null, null, null); 
     Cursor cursor = cursorLoader.loadInBackground(); 

     if (cursor != null) 
     { 
      int column_index = 
        cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
      cursor.moveToFirst(); 
      result = cursor.getString(column_index); 
     } 
     return result; 
    } 
    else 
    { 

     String[] proj = {MediaStore.Images.Media.DATA}; 
     Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); 
     int column_index 
       = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
     cursor.moveToFirst(); 
     return cursor.getString(column_index); 
    } 
} 
+2

Как вы реализуете это для файлов без изображений? –

0

Так что я попытался в основном когда-либо отвечать на стек, но это был единственный, который работал на меня. Важно подумать об ури как о «обещании», что образ живет там, где он указывает. Это не значит, что в этом месте есть файл, но если вы спросите правильно, вы получите изображение. attachementPath - путь к изображению (может использоваться как обычный файл). См. Ниже:

try { 
      InputStream input = getActivity().getContentResolver().openInputStream(imageUri); 
      File file = new File(getActivity().getCacheDir(), "cacheFileAppeal.png"); 
      try { 

       OutputStream output = new FileOutputStream(file); 
       try { 
        try { 
         byte[] buffer = new byte[4 * 1024]; // or other buffer size 
         int read; 

         if (input != null) { 
          while ((read = input.read(buffer)) != -1) { 
           output.write(buffer, 0, read); 
          } 
         } 
         output.flush(); 
        } finally { 
         output.close(); 
         attachmentPath = file.getAbsolutePath(); 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); // handle exception, define IOException and others 
       } 

      } finally { 
       try { 
        if (input != null) { 
         input.close(); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
1

Убедитесь, что вы даете разрешение в манифесте. Wasted 2 часа пытаются различные методы, не давая разрешений:./

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
0

публичные статические Int getIdFromUri (Uri Uri, String constantId) { Cursor с = ContentMaster.getContentResolver() запрос (Ури новый String [] {constantId}, null, null, null);

int res = -1; 
    if(c != null && c.getCount() > 0) 
    { 
     c.moveToFirst(); 
     res = c.getInt(0); 
     c.close(); 
    } 
    return res; 
} 
public static Uri getUriWithId(Uri baseUri,int contactId) 
{ 
    Uri u = ContentUris.withAppendedId(baseUri, contactId); 

    if(u != null) 
     return u; 

    return Uri.EMPTY; 
} 
public static String getRealPathFromURI(Uri uri) 
{ 
    if(uri == null) 
     return ""; 

    if ("file".equalsIgnoreCase(uri.getScheme())) 
     return uri.getPath(); 


    String[] pro = { MediaStore.Images.Media.DATA }; 
    String result = null; 
    Cursor cursor; 

    if(VERSION.SDK_INT > 18) 
    { 
     //String wholeID = DocumentsContract.getDocumentId(uri); 
     //String id = wholeID.split(":")[1]; 
     String id = String.valueOf(getIdFromUri(uri, Images.Media._ID)); 
     String[] column = { MediaStore.Images.Media.DATA }; 
     String where = MediaStore.Images.Media._ID + "=?"; 
     Uri u = uri; 

     if(isMediaDocument(uri)) 
     { 
      if (getUriMediaDocumentType(uri).equals("image")) 
      { 
       if(isExternalStorageDocument(uri)) 
        u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 
       else 
        u = MediaStore.Images.Media.INTERNAL_CONTENT_URI; 
      } 
      else if (getUriMediaDocumentType(uri).equals("video")) 
      { 
       if(isExternalStorageDocument(uri)) 
        u = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 
       else 
        u = MediaStore.Video.Media.INTERNAL_CONTENT_URI; 
      } 
      else if (getUriMediaDocumentType(uri).equals("audio")) 
      { 
       if(isExternalStorageDocument(uri)) 
        u = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
       else 
        u = MediaStore.Audio.Media.INTERNAL_CONTENT_URI; 
      } 
     } 
     else if(isDownloadsDocument(uri)) 
     { 
      u = getUriWithId(Uri.parse("content://downloads/public_downloads"), Integer.getInteger(id)); 
     } 

     cursor = getContentResolver().query(u, column, where, new String[]{id}, null); 
    } 
    else if(VERSION.SDK_INT > 10) 
    { 
     CursorLoader cursorLoader = new CursorLoader(SystemMaster.getContext(), uri, pro, null, null, null); 
     cursor = cursorLoader.loadInBackground(); 
    } 
    else 
    { 
     cursor = SystemMaster.getContext().getContentResolver().query(uri, pro, null, null, null); 
    } 


    if(cursor != null && cursor.getCount() > 0) 
    { 
     cursor.moveToFirst(); 
     result = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); 
     cursor.close(); 
    } 

    return result; 
} 

public static boolean isExternalStorageDocument(Uri uri) 
{ 
    return "com.android.externalstorage.documents".equals(uri.getAuthority()); 
} 

public static boolean isDownloadsDocument(Uri uri) 
{ 
    return "com.android.providers.downloads.documents".equals(uri.getAuthority()); 
} 

public static boolean isMediaDocument(Uri uri) 
{ 
    return "com.android.providers.media.documents".equals(uri.getAuthority()); 
} 

public static String getUriMediaDocumentType(Uri uri) 
{ 
    if(isMediaDocument(uri)) 
    { 
     //TODO 
     return "image"; 
    } 

    return ""; 
} 
Смежные вопросы