2017-02-28 5 views
10

Nougatでは、この関数は機能していません。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(); 
     } 
    } 
} 

クラッシュログ:

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) 

この機能は、Android N.前のデバイスで正常に動作している私は記事を読んfile:// scheme is now not allowed to be attached with Intent on targetSdkVersion 24 (Android Nougat)。しかし、解決策を見つけることができませんでした。だから助けてください。

+1

なぜあなたはURIからファイルパスを取得しようとしていますか?一般的に、すべてのURIがパスを持つローカルファイルによってサポートされているわけではないので、URIをストリームとして扱うようにしてください。 Exifデータを読み込む目的でファイルにアクセスしようとすると、ストリームとして開いてこのサポートライブラリを使用してexifデータを読み取ることができます。 https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html – startoftext

答えて

16

この機能は、それは非常に少ないUri値のために働く

は、(例えば、MediaStoreでインデックス化されているもののためにローカルファイルではないという結果を持っていない可能性がAndroidのN前のデバイスで正常に動作しています)、使用可能な結果が得られない可能性があります(例えば、リムーバブルストレージ上のファイルの場合)。

Uriによって識別されるコンテンツにInputStreamを取得するためにContentResolveropenInputStream()を使用してください。理想的には、あなたがしようとしていることが何であれ、そのストリームを直接使用してください。または、コンテンツのコピーを作成するために制御しているファイルにそのInputStreamといくつかのFileOutputStreamを使用し、そのファイルを使用します。

+0

ファイルパスを保存し、ファイルパスをデータベースに保存する場合はどうすればよいですか? – vidha

+0

Uriからのファイルと表示イメージを表示するにはどうすればよいですか? – vidha

+1

@vidha:答えに書いたように、データの**コピー**を自分のファイルに**作成して管理する必要があります。 – CommonsWare

8

CommonsWareによって与えられた答えを1として、ソリューションのコードは次のとおりです。私はこれがあなたの役に立てば幸い

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

関連する問題