마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

갤러리 이미지 절대경로

0 추천

https://hhhhhhhong.tistory.com/28

해당블로그 보고 갤러리 이미지 절대경로를 가져오려고 해봤으나 

Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

라고나옵니다.. 구글링해봐도 잘 안나오네요

현재 uri 까지 잘끌고오고 이미지뷰에도 글라이드 통해서 뿌려봤는데 잘 됩니다만 

private fun getPath(uri : Uri) {

    var result = ""
    var cursor : Cursor = activity?.contentResolver?.query(uri, null, null, null, null)!!

    if(cursor == null) {
        result = uri?.path.toString()
    }else {
        cursor.moveToFirst()
        var idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
        result = cursor.getString(idx)
        cursor.close()
    }
    Log.e("tag", "절대 "+ result)
}

현재 이렇게 썼는데 익셉션이 저렇게 터집니다.. 뭘까요..?

 

수원통학러 (3,570 포인트) 님이 2020년 12월 28일 질문

1개의 답변

0 추천
안드로이드에서 사진을 가져오는 코드는 정말 많이 변했습니다.
오래된 소스를 가져왔을 경우 안됩니다. 저도 최근에 예전에 쓰던 코드가 안되어 삽질을 했죠.
코틀린으로 변환해서 테스트는 되었습니다만, deprecated 문제가 있긴 하네요.
이게 버전 이슈가 있을 것 같은데, 일단 동작은 하지만 나중에 보완하셔야 할 듯..

        fun getFullPath(ctx : Activity, uri : Uri): String {

            var result = ""
            val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
            var cursor : Cursor = ctx?.contentResolver?.query(uri, filePathColumn, null, null, null)!!

            if(cursor == null) {
                result = uri?.path.toString()
            }else {
                cursor.moveToFirst()
                var idx = cursor.getColumnIndex(filePathColumn[0])
                result = cursor.getString(idx)
                cursor.close()
            }
            Log.e("tag", "절대 "+ result)

            return result;
        }

위의 코드가 잘 동작하지만,
MediaStore.Images.Media.DATA 가 deprecated 이슈가 있어서,
아래로 수정합니다.
파일 업로드도 잘되네요.
이후에 갤러리에서 가져올 때 오류가 있어서 수정합니다.
좀 더 간결하게 만들 수 있을 것 같은데,
폰 이슈가 있을 것 같아서 아래로 정리합니다.

    public static String getFullPathFromUri(Context ctx, Uri fileUri) {
        String fullPath = null;
        final String column = "_data";
        Cursor cursor = ctx.getContentResolver().query(fileUri, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
            String document_id = cursor.getString(0);
            if (document_id == null) {
                for (int i=0; i < cursor.getColumnCount(); i++) {
                    if (column.equalsIgnoreCase(cursor.getColumnName(i))) {
                        fullPath = cursor.getString(i);
                        break;
                    }
                }
            } else {
                document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
                cursor.close();

                final String[] projection = {column};
                try {
                    cursor = ctx.getContentResolver().query(
                            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            projection, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
                    if (cursor != null) {
                        cursor.moveToFirst();
                        fullPath = cursor.getString(cursor.getColumnIndexOrThrow(column));
                    }
                } finally {
                    if (cursor != null) cursor.close();
                }
            }
        }
        return fullPath;
    }
Will Kim (43,170 포인트) 님이 2020년 12월 28일 답변
Will Kim님이 2020년 12월 31일 수정
일단 그냥 startactivityforresult onactivityresult로 쓰니까 되긴되네요 감사합니다
문제는 deprecate...
JAVA에서는 표시가 나지않아 deprecated인지 몰랐죠.
코틀린으로 바꾸니까 바로 표시나네요.

파일을 복사하거나 서버로 업로드하지 않을거라면,
pic.setImageURI(selectedImage);
그냥, 이렇게 Uri로 이미지 뷰를 바로 Uri로 표시하거나
Glide로도 아래와 같이하면 Uri로 바로 표시 가능합니다.
Glide.with(getActivity()).load(imageUri).into(imageProfile);

샘플이 Java 지만, 금방 변환이 가능하므로...
서버로 업로드할거라.. 구글링해보니 절대경로로 해야된다해서 절대경로를 구해야됩니다 ㅠㅠ
코틀린에 이런게 있네요. 1.3.0 이상이어야 합니다.

uri.toFile()

--> 제 개발환경에서는 오류가 나서 코멘트 남깁니다.
deprecated 문제를 해결한 버전입니다.
추가로 갤러리에서 가져올 때 오류도 수정했습니다.
위에 답변을 아래로 수정하겠습니다.

    public static String getFullPathFromUri(Context ctx, Uri fileUri) {
        String fullPath = null;
        final String column = "_data";
        Cursor cursor = ctx.getContentResolver().query(fileUri, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
            String document_id = cursor.getString(0);
            if (document_id == null) {
                for (int i=0; i < cursor.getColumnCount(); i++) {
                    if (column.equalsIgnoreCase(cursor.getColumnName(i))) {
                        fullPath = cursor.getString(i);
                        break;
                    }
                }
            } else {
                document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
                cursor.close();

                final String[] projection = {column};
                try {
                    cursor = ctx.getContentResolver().query(
                            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            projection, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
                    if (cursor != null) {
                        cursor.moveToFirst();
                        fullPath = cursor.getString(cursor.getColumnIndexOrThrow(column));
                    }
                } finally {
                    if (cursor != null) cursor.close();
                }
            }
        }
        return fullPath;
    }
...