Unknown URI:content://downloads/public_downloads -- Android




안드로이드에서 이미지파일을 서버로 업로드하기 위해 인텐트를 이용하여 이미지선택을 해야 한다.
이전에는 잘 동작하던 코드가, 안드로이드 8.0이상부터는 이미지 선택을 다운로드 폴더에서 하면 아래의 에러가 발생했다.

Unknown URI:content://downloads/public_downloads

선택된 이미지의 실제 경로를 구하는 과정에서 나오는 에러인데, 참조한 사이트에서 알게된 것은 안드로이드 8.0부터는 선택한 이미지를 캐시 디렉토리로 저장 후 사용해야 한다고 한다.

실제 경로를 구하는 전체소스는 생략하기로 하고, 다운로드 폴더의 파일들을 실제 경로로 구하는 부분에 대해서만 작성한다. 실제 경로를 구하는 부분은 과거에 참고하였던 해당 글을 참고 바란다.


// 선택한 이미지의 uri에서 id를 추출
String id = DocumentsContract.getDocumentId(uri);

if (!TextUtils.isEmpty(id)) {
    if (id.startsWith("raw:")) {
        return id.replaceFirst("raw:", "");
    }
    long fileId = getFileId(uri);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        try {
            InputStream inputStream = context.getContentResolver().openInputStream(uri);
            File file = new File(context.getCacheDir().getAbsolutePath() + "/" + fileId);
            writeFile(inputStream, file);
            return file.getAbsolutePath();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    } else {
        String[] contentUriPrefixesToTry = new String[]{
                "content://downloads/public_downloads",
                "content://downloads/my_downloads",
                "content://downloads/all_downloads"
        };

        for (String contentUriPrefix : contentUriPrefixesToTry) {
            try {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), fileId);
                String path = getDataColumn(context, contentUri, null, null);
                if (path != null) {
                    return path;
                }
            } catch (Exception e) {
                Log.d("content-Provider", e.getMessage());
            }
        }
    }
}

// 이미지의 ID가 Long형태가 아닌 경우가 있어서 처리한다.
private static Long getFileId(Uri uri) {
    long strReulst = 0;
    try {
        String path = uri.getPath();
        String[] paths = path.split("/");
        if (paths.length >= 3) {
            strReulst = Long.parseLong(paths[2]);
        }
    } catch (NumberFormatException | IndexOutOfBoundsException e) {
        strReulst = Long.parseLong(new File(uri.getPath()).getName());
    }
    return strReulst;
}

// 캐시 폴더에 저장
private static void writeFile(InputStream in, File file) {
     OutputStream out = null;
     try {
         out = new FileOutputStream(file);
         byte[] buf = new byte[1024];
         int len;
         while ((len = in.read(buf)) > 0) {
             out.write(buf, 0, len);
         }
     } catch (Exception e) {
         e.printStackTrace();
     } finally {
         try {
             if (out != null) {
                 out.close();
             }
             in.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }


덧글

댓글 입력 영역



20140817_300_250

통계 위젯 (화이트)

48227
1037
1030811