2017-02-28 6 views
10

누우 트에서이 기능이 작동하지 않습니다. IllegalArgumentException : '_data'열이 없습니다.


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(); 
     } 
    } 
} 

충돌 로그 :이 기능은 내가 기사 file:// scheme is now not allowed to be attached with Intent on targetSdkVersion 24 (Android Nougat)를 읽을 안드로이드 N. 전에 장치에서 제대로 작동

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) 

. 그러나 어떤 해결책도 찾을 수 없었습니다. 그러니 도와주세요.

+1

왜 URI에서 파일 경로를 가져 오려고합니까? 일반적으로 모든 URI가 경로가있는 로컬 파일로 백업되지 않으므로 URI로 스트림을 사용하여 작업해야합니다. Exif 데이터를 읽으려는 목적으로 파일에 대한 액세스를 시도하는 경우이를 스트림으로 열고이 지원 라이브러리를 사용하여 exif 데이터를 읽을 수 있습니다. https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html – startoftext

답변

16

이 함수는 거의 Uri 값에 대해 작동

는, (예를 들어, MediaStore에 의해 색인 것들에 대한 로컬 파일이 아닌 그 결과가 없을 수 있습니다 안드로이드 N하기 전에 장치에서 제대로 작동), 사용 가능한 결과가 없을 수 있습니다 (예 : 이동식 저장소의 파일).

제발 도와주세요.

Uri에 의해 확인 된 내용에 InputStream를 얻을 수 ContentResolveropenInputStream() 용도. 이상적으로, 당신이하려고하는 것이 무엇이든간에 직접적으로 그 스트림을 직접 사용하십시오. 또는 콘텐트의 복사본을 만들기 위해 제어하는 ​​파일에 InputStream 및 일부 FileOutputStream을 사용하고 해당 파일을 사용하십시오.

+0

파일 경로를 데이터베이스에 저장하고 파일 경로를 저장하려면 어떻게해야합니까? – vidha

+0

Uri의 파일을 표시하고 이미지를 표시하려면 어떻게해야합니까? – vidha

+1

@vidha : 답변에서 썼 듯이 데이터 ** 사본 **을 자신의 파일에 만들어서 관리해야합니다. – CommonsWare

8

CommonsWare에 의해 주어진 대답은 당으로, 솔루션 코드입니다 :이 당신을 도움이되기를 바랍니다

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.copy(inputStream, outputStream); 
     inputStream.close(); 
     outputStream.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

.

+0

@ tf.alves 해결책을 찾은 것을 기쁘게 생각합니다. 환영합니다 :) – vidha