Получить путь к файлу и имя выбранного изображения галереи в Android

Я создаю приложение, которое загружает выбранное изображение из галереи и загружает его в веб-службу. Вебсервису требуется имя файла выбранного изображения плюс базовая кодировка содержимого файла. Мне удалось добиться этого с помощью жестко заданного пути к файлу. Тем не менее, я изо всех сил пытаюсь получить реальный путь к файлу изображения. Я читал по сети и имею этот код, но для меня это не работает:

public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { Uri selectedImageUri = data.getData(); String[] projection = {MediaStore.Images.Media.DATA}; try { Cursor cursor = getContentResolver().query(selectedImageUri, projection, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(projection[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); Log.d("Picture Path", picturePath); } catch(Exception e) { Log.e("Path Error", e.toString()); } } } 

Я получаю эту ошибку:

 java.lang.NullPointerException 

РЕДАКТИРОВАТЬ

Забыл упомянуть, что я использую Kitkat. Похоже, моя проблема связана с KitKat. Я нашел это (см. Ниже), что помогло мне заставить мое приложение работать:

Галерея Android на KitKat возвращает разные Uri для Intent.ACTION_GET_CONTENT

Solutions Collecting From Web of "Получить путь к файлу и имя выбранного изображения галереи в Android"

Используйте ниже код,

 public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { Uri selectedImageUri = data.getData(); String s = getRealPathFromURI(selectedImageUri); editText1.setText(s); } } 

И ниже – ваша функция getRealPathFromURI,

 public String getRealPathFromURI(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; @SuppressWarnings("deprecation") Cursor cursor = managedQuery(uri, projection, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } 

Добавьте этот класс в свой проект

ImageFilePath.java

 import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; //import android.provider.<span id="IL_AD11" class="IL_AD">MediaStore</span>; @SuppressLint("NewApi") @TargetApi(Build.VERSION_CODES.KITKAT) public class ImageFilePath { /** * Method for return file path of Gallery image * * @param context * @param uri * @return path of the selected image file from gallery */ static String nopath = "Select Video Only"; @TargetApi(Build.VERSION_CODES.KITKAT) @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) { // check here to KITKAT or new version final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return nopath; } /** * Get the value of the data column for this Uri. This is <span id="IL_AD2" * class="IL_AD">useful</span> for MediaStore Uris, and other file-based * ContentProviders. * * @param context * The context. * @param uri * The Uri to query. * @param selection * (Optional) Filter used in the query. * @param selectionArgs * (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return nopath; } /** * @param uri * The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri .getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri .getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri .getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri .getAuthority()); } } 

В вашем onActivityResult

  @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) { Uri uri = data.getData(); realPath = ImageFilePath.getPath(SignupActivity.this, data.getData()); // realPath = RealPathUtil.getRealPathFromURI_API19(this, data.getData()); Log.i(TAG, "onActivityResult: file path : " + realPath); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); // Log.d(TAG, String.valueOf(bitmap)); ImageView imageView = (ImageView) findViewById(R.id.img_profile); imageView.setImageBitmap(bitmap); imageView.setVisibility(View.VISIBLE); } catch (IOException e) { e.printStackTrace(); } } else { Toast.makeText(this, "Something Went Wrong", Toast.LENGTH_SHORT).show(); } } 

Немного поздно вечеринке, но вот мой код, надеюсь, что это поможет.

 public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { Uri selectedImageUri = data.getData( ); String picturePath = getPath( getActivity( ).getApplicationContext( ), selectedImageUri ); Log.d("Picture Path", picturePath); } } public static String getPath( Context context, Uri uri ) { String result = null; String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = context.getContentResolver( ).query( uri, proj, null, null, null ); if(cursor != null){ if ( cursor.moveToFirst( ) ) { int column_index = cursor.getColumnIndexOrThrow( proj[0] ); result = cursor.getString( column_index ); } cursor.close( ); } if(result == null) { result = "Not found"; } return result; } 

Попробуй это:

 Uri selectedImageURI = data.getData(); imageFile = new File(getRealPathFromURI(selectedImageURI)); 

А также

  private String getRealPathFromURI(Uri contentURI) { Cursor cursor = getContentResolver().query(contentURI, null, null, null, null); if (cursor == null) { // Source is Dropbox or other similar local file path return contentURI.getPath(); } else { cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); return cursor.getString(idx); } } 
 public class RealFilePath { /** * Get a file path from a Uri. This will get the the path for Storage Access * Framework Documents, as well as the _data field for the MediaStore and * other file-based ContentProviders. * * @param context The context. * @param uri The Uri to query */ public static String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } // TODO handle non-primary volumes } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id) ); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{ split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param context The context. * @param uri The Uri to query. * @param selection (Optional) Filter used in the query. * @param selectionArgs (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } } 

Попробуй это,

  file = new File(getPath(outputFileUri)); public String getPath(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; @SuppressWarnings("deprecation") Cursor cursor = managedQuery(uri, projection, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } 

Если вы похожи на меня, и у вас нет готового локального файла, например, вы хотите дать пользователю возможность сделать снимок, а затем загрузить изображение, вот как это сделать. Я ноб в java, но у меня есть опыт в кодировании. Stackoverflow помог мне выделить так, что теперь самое время сделать что-то.

При работе в классе вы должны объявить эти два элемента. Поскольку у вас есть рабочий класс загрузки и скрипт php.

ПРИМЕЧАНИЕ. Я не рассматриваю все различные API. Я использую java-компилятор 1.7 и диапазон API от 10 до 18.

 public class Yourproject extends Activity { File imageFile; File imageFileName; //This part is needed for decoding the path adres. private String getRealPathFromURI(Uri contentURI) { String result; Cursor cursor = getContentResolver().query(contentURI, null, null, null, null); if (cursor == null) { // Source is Dropbox or other similar local file path result = contentURI.getPath(); } else { cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME); result = cursor.getString(idx); cursor.close(); } return result; } //This is needed for the path name, now you might just want to use one decoding script depending on //your class in total. //In my case this was the way to go. //To use one single addres use this line ImageColumns.DATA in the int idx declaration. private String getRealPathFromNAME(Uri contentNAME) { String result; Cursor cursor = getContentResolver().query(contentNAME, null, null, null, null); if (cursor == null) { // Source is Dropbox or other similar local file path result = contentNAME.getPath(); } else { cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME); result = cursor.getString(idx); cursor.close(); } return result; } //Then under protected void onCreate(Bundle savedInstanceState) you place this code to get //the image and process it. @Override protected void onCreate(Bundle savedInstanceState) { //declare the ImageView final ImageView inputPicture = (ImageView) findViewById(R.id.imageView2); inputPicture.setImageURI((Uri) getIntent().getExtras().get("picture")); //here where recieve the image from last page "Putextra" method try { //here we will get the data and proces it trough to get the real //address for uploading. //This is send from a other activity with a Intent.EXTRA_STREAM //The code looks like this: /*********"Putextra"*********/ //final ImageView iv = (ImageView) findViewById(R.id.imageView1); //final Uri thumb = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM); //iv.setImageURI(thumb); //Sending it to the next activity //it.putExtra("picture", thumb); /*********"Putextra"*********/ Uri fileUri = (Uri) getIntent().getExtras().get("picture"); //get //Uri fileName = (Uri) getIntent().getExtras().get("picture"); //get imageFile = new File(getRealPathFromURI(fileUri)); //send imageFileName = new File(getRealPathFromNAME(fileUri)); //send //i got a exeption Uri fileName, use fileUri twice.. } catch (Exception e2) { // TODO Auto-generated catch block e2.printStackTrace(); } //here we will declare the name for furter processing. final File uploadFilePath = imageFile; final File uploadFileName = imageFileName; } 

И остальное я оставлю до вас, если вы доберетесь до этого, я уверен, что вы закончите.

Надеюсь, это поможет вам

  if (Build.VERSION.SDK_INT <19){ Intent intent = new Intent(); intent.setType("image/jpeg"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, getResources().getString(R.string.select_picture)),GALLERY_INTENT_CALLED); }else{ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/jpeg"); startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != Activity.RESULT_OK) return; if (null == data) return; Uri originalUri = null; if (requestCode == GALLERY_INTENT_CALLED) { originalUri = data.getData(); } else if (requestCode == GALLERY_KITKAT_INTENT_CALLED) { originalUri = data.getData(); final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // Check for the freshest data. getContentResolver().takePersistableUriPermission(originalUri, takeFlags); } loadSomeStreamAsynkTask(originalUri); } 

Попробуйте это, чтобы получить данные, а также путь к файлу и вставить в папку.

 public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); try { if (resultCode == RESULT_OK) { nav = data.getData(); String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(nav, projection, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String path= cursor.getString(column_index); Toast.makeText(getApplicationContext(), path, 500).show(); mBitmap = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), nav); insert(mBitmap); if (mBitmap != null) { mBitmap.recycle(); mBitmap = null; } } } catch (Exception e) { e.printStackTrace(); } } private void insert(Bitmap finalBitmap) { File myDir=new File("/sdcard/saved_images"); myDir.mkdirs(); Random generator = new Random(); int n = 10000; n = generator.nextInt(n); String fname = "Image-"+ n +".jpg"; File file = new File (myDir, fname); if (file.exists ()) file.delete (); try { FileOutputStream out = new FileOutputStream(file); finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out); out.flush(); out.close(); File dstFile = new File(file.getParent(), "." + file.getName()); file.renameTo(dstFile); } catch (Exception e) { e.printStackTrace(); } }