Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IllegalArgumentException: column '_data' does not exist

In Nougat, this function is not working.

String path = getRealPathFromURI(this, getIntent().getParcelableExtra(Intent.EXTRA_STREAM)); 


public String getRealPathFromURI(Context context, Uri contentUri) {     Cursor cursor = null;     try {         String[] proj = {MediaStore.Images.Media.DATA};         cursor = context.getContentResolver().query(contentUri, proj, null, null, null);         if (cursor == null) return contentUri.getPath();         int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);         cursor.moveToFirst();         return cursor.getString(column_index);     } finally {         if (cursor != null) {             cursor.close();         }     } } 

Crash log:

java.lang.RuntimeException: Unable to start activity ComponentInfo{class path}: java.lang.IllegalArgumentException: column '_data' does not exist    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2659)    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)    at android.app.ActivityThread.-wrap12(ActivityThread.java)    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)    at android.os.Handler.dispatchMessage(Handler.java:102)    at android.os.Looper.loop(Looper.java:154)    at android.app.ActivityThread.main(ActivityThread.java:6123)    at java.lang.reflect.Method.invoke(Method.java)    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) Caused by java.lang.IllegalArgumentException: column '_data' does not exist    at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:333)    at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:87)    at com.package.SaveImageActivity.getRealPathFromURI()    at com.package.SaveImageActivity.onCreate()    at android.app.Activity.performCreate(Activity.java:6672)    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2612)    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)    at android.app.ActivityThread.-wrap12(ActivityThread.java)    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)    at android.os.Handler.dispatchMessage(Handler.java:102)    at android.os.Looper.loop(Looper.java:154)    at android.app.ActivityThread.main(ActivityThread.java:6123)    at java.lang.reflect.Method.invoke(Method.java)    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 

This function is working properly in devices before Android N. I read the article file:// scheme is now not allowed to be attached with Intent on targetSdkVersion 24 (Android Nougat). But couldn't find any solution. So please help.

like image 493
vidha Avatar asked Feb 28 '17 12:02

vidha


2 Answers

As per given answer by CommonsWare, the solution code is :

public static String getFilePathFromURI(Context context, Uri contentUri) {     //copy file and send new file path      String fileName = getFileName(contentUri);     if (!TextUtils.isEmpty(fileName)) {         File copyFile = new File(TEMP_DIR_PATH + File.separator + fileName);         copy(context, contentUri, copyFile);         return copyFile.getAbsolutePath();     }     return null; }  public static String getFileName(Uri uri) {     if (uri == null) return null;     String fileName = null;     String path = uri.getPath();     int cut = path.lastIndexOf('/');     if (cut != -1) {         fileName = path.substring(cut + 1);     }     return fileName; }  public static void copy(Context context, Uri srcUri, File dstFile) {     try {         InputStream inputStream = context.getContentResolver().openInputStream(srcUri);         if (inputStream == null) return;         OutputStream outputStream = new FileOutputStream(dstFile);         IOUtils.copyStream(inputStream, outputStream);         inputStream.close();         outputStream.close();     } catch (IOException e) {         e.printStackTrace();     } } 

I hope this helps you.

The origin of IOUtils.copy is from this site : https://www.developerfeed.com/copy-bytes-inputstream-outputstream-android/ (May need to change a bit the exception but it works as needed)

like image 58
vidha Avatar answered Sep 20 '22 23:09

vidha


This function is working properly in devices before Android N

It works for very few Uri values, may not have a result (e.g., for things that are indexed by MediaStore that are not local files), and may not have a usable result (e.g., for files on removable storage).

So please help.

Use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Ideally, just use that stream directly, for whatever it is that you are trying to do. Or, use that InputStream and some FileOutputStream on a file that you control to make a copy of the content, then use that file.

like image 25
CommonsWare Avatar answered Sep 20 '22 23:09

CommonsWare