미디어 저장소에서 URI의 파일 이름 및 경로 가져 오기


390

나는 한 onActivityResult나는 다음을 사용하여 이미지의 URI를 얻을 수있는 미디어 스토어 MediaStore의 이미지 선택에서 돌아 :

Uri selectedImage = data.getData();

이것을 문자열로 변환하면 다음과 같이됩니다.

content://media/external/images/media/47

또는 경로는 다음을 제공합니다.

/external/images/media/47

그러나 이미지를 복사하지 않고 이미지를 비트 맵에로드하고 싶기 때문에 이것을 절대 경로로 변환하는 방법을 찾지 못하는 것 같습니다. URI와 콘텐츠 분석기를 사용 하여이 작업을 수행 할 수 있다는 것을 알고 있지만 전화를 재부팅 할 때 깨지는 것처럼 보입니다. 재부팅 할 때 MediaStore번호가 동일하게 유지되지는 않습니다.



API 19 이상 솔루션은 stackoverflow.com/a/51227392/9815519 입니다. 희망이 여러분을 도울 수 있습니다.
Hasib Akter

답변:


609

API 19 이하 에서는이 코드를 사용하여 URI에서 파일 경로를 가져옵니다.

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);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
  } finally {
    if (cursor != null) {
      cursor.close();
    }
  }
}

65
managedQuery (.........) (더 이상 사용되지 않음) 대신 getContentResolver (). query (.....)를 동일한 매개 변수와 함께 사용할 수 있습니다. 좋은 일
Pablo Johnson

44
최신 Android 버전 (KitKat)에서는 오류가 발생합니다. 경로 문자열이 null입니다.
Christopher Masser

17
- 크리스토퍼가 지적 하듯이 더 많은 정보를 원하시면,이 질문을 참조 4.4에서 지원되지 않습니다 stackoverflow.com/questions/20067508/...
ılǝ

13
작동하지 않습니다. 커서가 null입니다. 그리고 나는 안드로이드 4.4 이상이 아니고 4.1.2에 있습니다.
matteo

11
5 개의 장치에서 테스트되었습니다. Android 4.1.2를 제외하고는 모두 널을 제공합니다. 모든 최신 Android에서는 null을 반환합니다.
Tina

127

첫 번째 답변에 대한 간단한 업데이트 : mActivity.managedQuery()이제 더 이상 사용되지 않습니다. 새로운 방법으로 코드를 업데이트했습니다.

private String getRealPathFromURI(Uri contentUri) {
    String[] proj = { MediaStore.Images.Media.DATA };
    CursorLoader loader = new CursorLoader(mContext, contentUri, proj, null, null, null);
    Cursor cursor = loader.loadInBackground();
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    String result = cursor.getString(column_index);
    cursor.close();
    return result;
}

안드로이드 개발 소스


3
@ 덱스터 : 이것은 나를 위해 작동하지 않았습니다. 파일 브라우저에서 파일을 클릭하면 작동하지만 전자 메일 첨부 파일을 클릭해도 여전히 content://...문제가 발생합니다. 나는 모든 제안을 운없이 시도했다. 왜 그런지 알아?
Luis A. Florit

@Luis 저도 같은 문제를
겪습니다

1
@dextor 커서를 닫아야합니다.
etherton

당신이 이것에 도울 수 있습니다 : stackoverflow.com/questions/27103529/…
Chlebta

@ dextor 나는이 솔루션을 시도했지만 작동하지 않았을 것입니다. 이 질문에서 Paul Burke의 솔루션은 stackoverflow.com/questions/20067508/…이 효과가있었습니다.
AndyZ

111

오레오

Uri uri = data.getData(); 
File file = new File(uri.getPath());//create path from uri
final String[] split = file.getPath().split(":");//split the path.
filePath = split[1];//assign it to a string(your choice).

Oreo 아래의 모든 버전의 경우 URI에서 실제 경로를 얻는이 방법을 만들었습니다.

 @SuppressLint("NewApi")
    public static String getFilePath(Context context, Uri uri) throws URISyntaxException {
        String selection = null;
        String[] selectionArgs = null;
        // Uri is different in versions after KITKAT (Android 4.4), we need to
        if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            } else if (isDownloadsDocument(uri)) {
                final String id = DocumentsContract.getDocumentId(uri);
                uri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
            } else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                if ("image".equals(type)) {
                    uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                selection = "_id=?";
                selectionArgs = new String[]{
                        split[1]
                };
            }
        }
        if ("content".equalsIgnoreCase(uri.getScheme())) {


          if (isGooglePhotosUri(uri)) {
              return uri.getLastPathSegment();
           }

            String[] projection = {
                    MediaStore.Images.Media.DATA
            };
            Cursor cursor = null;
            try {
                cursor = context.getContentResolver()
                        .query(uri, projection, selection, selectionArgs, null);
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                if (cursor.moveToFirst()) {
                    return cursor.getString(column_index);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }

    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

  public static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}

7
그것이 모든 유형의 Uri에서 완벽하게 작동하는 유일한 버전입니다 – 최고의 답변이되어야합니다.
Matthew Fisher

6
이 코드는 사용자가 SD 카드에서 파일을 선택하지 않은 경우 작동합니다. 사용자가 SD 카드에서 파일을 선택한 경우 반환 된 경로보다 파일이 / storage / sdCard / filePath에있는 경우에도 / storage / emulated / 0 / filePath입니다.
adi9090

adi9090 에서이 문제를 해결하기위한 솔루션이 있습니까? 나는 거의 이틀 동안이 문제에 갇혀있다 :(
Ali Nawaz

2
잘 당신은 안드로이드 URL에 대한 재료 선택기 같은 일부 라이브러리를 시도 할 수 있습니다 : github.com/nbsp-team/MaterialFilePicker 이것은 솔루션에 더 가까이 걸릴 수 있습니다. 만약 어떤 솔루션을 친절하게 게시하면 아래에 있습니다 ..
Ali Nawaz

4
java.lang.UnsupportedOperationException : 지원되지 않는 Uri content : //com.android.externalstorage.documents/tree/primary%3ADCIM%2FCamera...Android 팀이 삶을 어렵게 만든 이유
Leon

96

파일 시스템에서 URI를 찾으려고하지 마십시오. 데이터베이스에서 검색하는 것이 느립니다.

팩토리에 파일을 제공하는 것처럼 입력 스트림을 팩토리에 제공하여 URI에서 비트 맵을 얻을 수 있습니다.

InputStream is = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();

5
실제로 이것은 유일한 정답입니다. 아무도 파일 이름에 관심이 없습니다. 우리에게 필요한 것은 내용입니다. 실제 파일은 앱의 개인 폴더, 인터넷, sqlite에 있거나 순전히 가상이고 즉시 생성 될 수 있습니다.
durilka

18
구체적인 질문은 파일 이름과 경로입니다. 그렇습니다. OP는 파일에서 비트 맵을 도출하려고하지만 경로를 찾는 모든 사람에게 해당되는 것은 아닙니다. 때로는 실제 파일 내용이 필요합니다.
Huperniketes

3
@durilka, 예 : 파일이 비디오이고 썸네일을 원할 경우 "ThumbnailUtils.createVideoThumbnail"함수는 String 유형의 경로로 호출 할 수 있으며 inputStream의 tipe를 허용하지 않습니다.
ElYeante

1
먼저 동영상의 콘텐츠 제공 업체가 메타 데이터와 함께 미리보기 이미지를 제공하는지 확인합니다. 안드로이드는 "누군가 이미이 작업을 수행 한 경우 직접 구현하지 마십시오"에 관한 것입니다. 모든 야심 찬 응용 프로그램이 자신의 사진 캡처를 만드는 방법을 정말로 놀라게합니다.
durilka

4
방금 OutOfMemory 버그로 이어지는 경로를 소개했습니다
sandalone

39

다음은 file : // ... 및 content : // ...와 같은 URI에서 파일 이름을 얻는 예입니다. Android MediaStore뿐만 아니라 EzExplorer와 같은 타사 응용 프로그램에서도 작동합니다.

public static String getFileNameByUri(Context context, Uri uri)
{
    String fileName="unknown";//default fileName
    Uri filePathUri = uri;
    if (uri.getScheme().toString().compareTo("content")==0)
    {      
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        if (cursor.moveToFirst())
        {
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);//Instead of "MediaStore.Images.Media.DATA" can be used "_data"
            filePathUri = Uri.parse(cursor.getString(column_index));
            fileName = filePathUri.getLastPathSegment().toString();
        }
    }
    else if (uri.getScheme().compareTo("file")==0)
    {
        fileName = filePathUri.getLastPathSegment().toString();
    }
    else
    {
        fileName = fileName+"_"+filePathUri.getLastPathSegment();
    }
    return fileName;
}

4
이것은 file : //과 content : // URI 사이를 변환 할 수 있습니까? 프로젝트에 코드를 포함하려고 시도했지만 ApplicationObject를 확인할 수 없습니다.
user280109

5
ApplicationObject에 문제가 있습니다. 코드 좀 주시겠습니까?
Nikolay Nikiforchuk

오, 괜찮아요, 걱정하지 마십시오. 작동하는 다른 예제 코드를 찾았습니다.
user280109

2
이것은 가장 좋은 대답이 될 가치가 있으며, 더 포괄적이며 내가 가진 문제를 해결했습니다.
Andreas Rudolph

getLastPathSegment ()가 이미 문자열을 반환 할 때 왜 getLastPathSegment (). toString ()을 호출합니까?
droid8421

15

좋은 기존 답변, 그중 일부는 내 자신을 생각해 냈습니다.

URI에서 경로를 가져와 경로에서 URI를 가져와야하며 Google은 동일한 문제가있는 사람 (예 : MediaStore물리적 위치가 이미있는 비디오 에서 미리보기 이미지를 가져 오는 것)을 구별하기가 어렵습니다. ). 전자 :

/**
 * Gets the corresponding path to a file from the given content:// URI
 * @param selectedVideoUri The content:// URI to find the file path from
 * @param contentResolver The content resolver to use to perform the query.
 * @return the file path as a string
 */
private String getFilePathFromContentUri(Uri selectedVideoUri,
        ContentResolver contentResolver) {
    String filePath;
    String[] filePathColumn = {MediaColumns.DATA};

    Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
    cursor.moveToFirst();

    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    filePath = cursor.getString(columnIndex);
    cursor.close();
    return filePath;
}

후자는 비디오에 사용되지만 MediaStore.Video를 MediaStore.Audio 등으로 대체하여 오디오 또는 파일 또는 다른 유형의 저장된 콘텐츠에도 사용할 수 있습니다.

/**
 * Gets the MediaStore video ID of a given file on external storage
 * @param filePath The path (on external storage) of the file to resolve the ID of
 * @param contentResolver The content resolver to use to perform the query.
 * @return the video ID as a long
 */
private long getVideoIdFromFilePath(String filePath,
        ContentResolver contentResolver) {


    long videoId;
    Log.d(TAG,"Loading file " + filePath);

            // This returns us content://media/external/videos/media (or something like that)
            // I pass in "external" because that's the MediaStore's name for the external
            // storage on my device (the other possibility is "internal")
    Uri videosUri = MediaStore.Video.Media.getContentUri("external");

    Log.d(TAG,"videosUri = " + videosUri.toString());

    String[] projection = {MediaStore.Video.VideoColumns._ID};

    // TODO This will break if we have no matching item in the MediaStore.
    Cursor cursor = contentResolver.query(videosUri, projection, MediaStore.Video.VideoColumns.DATA + " LIKE ?", new String[] { filePath }, null);
    cursor.moveToFirst();

    int columnIndex = cursor.getColumnIndex(projection[0]);
    videoId = cursor.getLong(columnIndex);

    Log.d(TAG,"Video ID is " + videoId);
    cursor.close();
    return videoId;
}

기본적으로 (또는 쿼리하는 하위 섹션의) DATA열은 MediaStore파일 경로를 저장하므로 해당 DATA필드 를 조회하기 위해 알고있는 것을 사용하거나 원하는 다른 것을 조회하기 위해 필드를 사용하십시오.

그런 다음 Scheme위와 같이 데이터를 사용하여 수행 할 작업을 파악합니다.

 private boolean  getSelectedVideo(Intent imageReturnedIntent, boolean fromData) {

    Uri selectedVideoUri;

    //Selected image returned from another activity
            // A parameter I pass myself to know whether or not I'm being "shared via" or
            // whether I'm working internally to my app (fromData = working internally)
    if(fromData){
        selectedVideoUri = imageReturnedIntent.getData();
    } else {
        //Selected image returned from SEND intent 
                    // which I register to receive in my manifest
                    // (so people can "share via" my app)
        selectedVideoUri = (Uri)getIntent().getExtras().get(Intent.EXTRA_STREAM);
    }

    Log.d(TAG,"SelectedVideoUri = " + selectedVideoUri);

    String filePath;

    String scheme = selectedVideoUri.getScheme(); 
    ContentResolver contentResolver = getContentResolver();
    long videoId;

    // If we are sent file://something or content://org.openintents.filemanager/mimetype/something...
    if(scheme.equals("file") || (scheme.equals("content") && selectedVideoUri.getEncodedAuthority().equals("org.openintents.filemanager"))){

        // Get the path
        filePath = selectedVideoUri.getPath();

        // Trim the path if necessary
        // openintents filemanager returns content://org.openintents.filemanager/mimetype//mnt/sdcard/xxxx.mp4
        if(filePath.startsWith("/mimetype/")){
            String trimmedFilePath = filePath.substring("/mimetype/".length());
            filePath = trimmedFilePath.substring(trimmedFilePath.indexOf("/"));
        }

        // Get the video ID from the path
        videoId = getVideoIdFromFilePath(filePath, contentResolver);

    } else if(scheme.equals("content")){

        // If we are given another content:// URI, look it up in the media provider
        videoId = Long.valueOf(selectedVideoUri.getLastPathSegment());
        filePath = getFilePathFromContentUri(selectedVideoUri, contentResolver);

    } else {
        Log.d(TAG,"Failed to load URI " + selectedVideoUri.toString());
        return false;
    }

     return true;
 }

11

이 답변 중 어느 것도 모든 경우에 나에게 도움이되지 못했습니다. 이 주제에 대한 Google 문서 https://developer.android.com/guide/topics/providers/document-provider.html 로 직접 이동하여 유용한 방법을 찾았습니다.

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
    ParcelFileDescriptor parcelFileDescriptor =
    getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();
    return image;
}

이 비트 맵을 사용하여 이미지보기에 표시 할 수 있습니다.


7

API 19 이상 에서는 Uri의 이미지 파일 경로 가 완벽하게 작동합니다. 이 최신 PIE API 28 도 확인하십시오 .

public String getImageFilePath(Uri uri) {
    String path = null, image_id = null;

    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
    if (cursor != null) {
        cursor.moveToFirst();
        image_id = cursor.getString(0);
        image_id = image_id.substring(image_id.lastIndexOf(":") + 1);
        cursor.close();
    }

    Cursor cursor = getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
    if (cursor!=null) {
        cursor.moveToFirst();
        path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
        cursor.close();
    }
    return path;
}

3
먼저 커서를 두 번 초기화했습니다! 둘째,이 코드는 CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0다음 줄을 처리합니다.path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
Harshil Pansare

저는 Oreo stock android를 사용하고 있으며 어떤 이유로 든 작동하지 않습니다
Harshil Pansare

URI에서 pdf 파일 파일 경로를 얻는 방법 도와주세요

@HarshilPansare, Android Oreo에서 어떻게 작동하게 되었습니까? 나는 이틀 동안 붙어 있습니다.
Kashish Malhotra

선택한 항목이 이미지가 아닌 경우 작동하지 않습니다.
Mustansir

5

Uri에서 이미지 파일 경로 가져 오기를 시도하십시오.

public void getImageFilePath(Context context, Uri uri) {

    Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
    cursor.moveToFirst();
    String image_id = cursor.getString(0);
    image_id = image_id.substring(image_id.lastIndexOf(":") + 1);
    cursor.close();
    cursor = context.getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
    cursor.moveToFirst();
    String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
    cursor.close();
    upLoadImageOrLogo(path);
}


3

갤러리에서 이미지를 가져온 후 Android 4.4 (KitKat)에 대해서만 아래 방법으로 URI를 전달하십시오 .

public String getPath(Uri contentUri) {// Will return "image:x*"

    String wholeID = DocumentsContract.getDocumentId(contentUri);

    // Split at colon, use second item in the array
    String id = wholeID.split(":")[1];

    String[] column = { MediaStore.Images.Media.DATA };

    // Where id is equal to
    String sel = MediaStore.Images.Media._ID + "=?";

    Cursor cursor = getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel,
            new String[] { id }, null);

    String filePath = "";

    int columnIndex = cursor.getColumnIndex(column[0]);

    if (cursor.moveToFirst()) {
        filePath = cursor.getString(columnIndex);
    }

    cursor.close();
    return filePath;
}

이것은 나를 위해 일한 유일한 사람입니다. 나는 갤러리에서 무언가를 원했다. Kitkat 아래에 대한 작동 방법이 있습니까? @sharma_kunai
SIr Codealot 2016 년

3

이 시도

그래도 실제 경로를 얻는 데 문제가 있으면 내 대답을 시도해 볼 수 있습니다. 위의 답변은 도움이되지 않았습니다.

설명 :-이 메소드는 URI를 가져온 다음 API 레벨에 따라 Android 장치의 API 레벨을 확인하여 실제 경로를 생성합니다. 실제 경로 방법을 생성하기위한 코드는 API 레벨에 따라 다릅니다.

  1. URI에서 실제 경로를 얻는 방법

    @SuppressLint("ObsoleteSdkInt")
    public String getPathFromURI(Uri uri){
        String realPath="";
    // SDK < API11
        if (Build.VERSION.SDK_INT < 11) {
            String[] proj = { MediaStore.Images.Media.DATA };
            @SuppressLint("Recycle") Cursor cursor = getContentResolver().query(uri, proj, null, null, null);
            int column_index = 0;
            String result="";
            if (cursor != null) {
                column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                realPath=cursor.getString(column_index);
            }
        }
        // SDK >= 11 && SDK < 19
        else if (Build.VERSION.SDK_INT < 19){
            String[] proj = { MediaStore.Images.Media.DATA };
            CursorLoader cursorLoader = new CursorLoader(this, uri, proj, null, null, null);
            Cursor cursor = cursorLoader.loadInBackground();
            if(cursor != null){
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                realPath = cursor.getString(column_index);
            }
        }
        // SDK > 19 (Android 4.4)
        else{
            String wholeID = DocumentsContract.getDocumentId(uri);
            // Split at colon, use second item in the array
            String id = wholeID.split(":")[1];
            String[] column = { MediaStore.Images.Media.DATA };
            // where id is equal to
            String sel = MediaStore.Images.Media._ID + "=?";
            Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null);
            int columnIndex = 0;
            if (cursor != null) {
                columnIndex = cursor.getColumnIndex(column[0]);
                if (cursor.moveToFirst()) {
                    realPath = cursor.getString(columnIndex);
                }
                cursor.close();
            }
        }
        return realPath;
     }
  2. 이 방법을 이렇게 사용하십시오

    Log.e(TAG, "getRealPathFromURI: "+getPathFromURI(your_selected_uri) );

산출:-

04-06 12 : 39 : 46.993 6138-6138 / com.app.qtm E / tag : getRealPathFromURI : /storage/emulated/0/Video/avengers_infinity_war_4k_8k-7680x4320.jpg


1
나의 물리적 장치 (25) API 레벨을 반환 치명적인 예외 명령으로이 String wholeID = DocumentsContract.getDocumentId(uri);내가 얻을 :java.lang.RuntimeException: Failure delivering result
Aliton 올리베이라

3

나는 이렇게했다 :

    Uri queryUri = MediaStore.Files.getContentUri("external");
    String columnData = MediaStore.Files.FileColumns.DATA;
    String columnSize = MediaStore.Files.FileColumns.SIZE;

    String[] projectionData = {MediaStore.Files.FileColumns.DATA};


    String name = null;
    String size = null;

    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if ((cursor != null)&&(cursor.getCount()>0)) {
        int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
        int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);

        cursor.moveToFirst();

        name = cursor.getString(nameIndex);
        size = cursor.getString(sizeIndex);

        cursor.close();
    }

    if ((name!=null)&&(size!=null)){
        String selectionNS = columnData + " LIKE '%" + name + "' AND " +columnSize + "='" + size +"'";

        Cursor cursorLike = getContentResolver().query(queryUri, projectionData, selectionNS, null, null);

        if ((cursorLike != null)&&(cursorLike.getCount()>0)) {
            cursorLike.moveToFirst();
            int indexData = cursorLike.getColumnIndex(columnData);
            if (cursorLike.getString(indexData) != null) {
                result = cursorLike.getString(indexData);
            }
            cursorLike.close();
        }
    }

    return result;

2

managedQuery는 더 이상 사용되지 않으므로 다음을 시도해 볼 수 있습니다.

CursorLoader cursorLoader = new CursorLoader(context, uri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();

2

여기에서 BROWSE 버튼을 만드는 방법을 보여 드리겠습니다.이 버튼을 클릭하면 SD 카드가 열리고 파일을 선택하고 결과적으로 선택한 파일 이름과 파일 경로를 얻을 수 있습니다 하나:

당신이 칠 버튼

browse.setOnClickListener(new OnClickListener()
{
    public void onClick(View v)
    {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_PICK);
        Uri startDir = Uri.fromFile(new File("/sdcard"));
        startActivityForResult(intent, PICK_REQUEST_CODE);
    }
});

결과 파일 이름과 파일 경로를 얻는 함수

protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
    if (requestCode == PICK_REQUEST_CODE)
    {
        if (resultCode == RESULT_OK)
        {
            Uri uri = intent.getData();

            if (uri.getScheme().toString().compareTo("content")==0)
            {
                Cursor cursor =getContentResolver().query(uri, null, null, null, null);
                if (cursor.moveToFirst())
                {
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);//Instead of "MediaStore.Images.Media.DATA" can be used "_data"
                    Uri filePathUri = Uri.parse(cursor.getString(column_index));
                    String file_name = filePathUri.getLastPathSegment().toString();
                    String file_path=filePathUri.getPath();
                    Toast.makeText(this,"File Name & PATH are:"+file_name+"\n"+file_path, Toast.LENGTH_LONG).show();
                }
            }
        }
    }
}

나는 여기의 제안을 따르고 작동하지 않았습니다. K9 이메일 클라이언트 첨부 파일을 클릭하면가 나타납니다 content://com.fsck.k9.attachmentprovider/34fc2cc9-aa46-45e9-9e3f-2f27f0457249/1‌​/VIEW. 여기에 메소드를 적용한 후에도 올바른 경로가 아닌 동일한 문자열, 즉을 얻습니다 /mnt/sdcard/Android/data/com.fsck.k9/files/34fc2cc9-aa46-45e9-9e3f-2f27f0457249‌​.db_att/1. 단서가 있습니까?
Luis A. Florit

2

MediaStore.Images.Media.DATA를 더 이상 사용할 수 없을 때 과거 Android Q에 대한 방법이 있습니까? 이 필드는 Android Q에서 감가 상각됩니다.

이 상수는 API 레벨 29에서 더 이상 사용되지 않습니다. 앱에이 경로에 직접 액세스 할 수있는 파일 시스템 권한이 없을 수 있습니다. 앱은이 경로를 직접 열려는 대신 ContentResolver # openFileDescriptor (Uri, String)를 사용하여 액세스해야합니다.

https://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#DATA

--- 편집

과거 Android Q에 대해 아는 한 RELATIVE_PATH 에서 릴레이하는 것이 유일한 방법입니다.

저장 장치 내에서이 미디어 항목의 상대 경로입니다. 예를 들어, /storage/0000-0000/DCIM/Vacation/IMG1024.JPG에 저장된 항목의 경로는 DCIM / Vacation /입니다.

https://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#RELATIVE_PATH


안드로이드 Q의 모든 파일에 상대 경로가 있습니까? 파일이 이미 장치에 존재하는 경우 상대 경로를 사용할 수있는 것처럼 추가해야합니까?
1234567

1
링크에 설명에 따라 @ 1234567을 null로 전달하면 시스템이 올바르게 설정합니다. 파일이 이미 있으면 미디어 스캐너가 필드를 추가해야합니다.
말라 키 아스

당신은 목표 API 안드로이드 Q 필요하고 아마도 범위가 지정된 저장 장치를 켜
Malachiasz

1

@PercyPercy의 약간 수정 된 버전-문제가 발생하면 throw되지 않고 null을 반환합니다 .

public String getPathFromMediaUri(Context context, Uri uri) {
    String result = null;

    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
    int col = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
    if (col >= 0 && cursor.moveToFirst())
        result = cursor.getString(col);
    cursor.close();

    return result;
}

1

여기에서 파일 이름을 얻습니다

String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME};
                    Uri uri = data.getData();
                    String fileName = null;
                    ContentResolver cr = getActivity().getApplicationContext().getContentResolver();

                    Cursor metaCursor = cr.query(uri,
                            projection, null, null, null);
                    if (metaCursor != null) {
                        try {
                            if (metaCursor.moveToFirst()) {
                                fileName = metaCursor.getString(0);
                            }
                        } finally {
                            metaCursor.close();
                        }
                    }

아마도 파일 이름뿐만 아니라 절대 경로를 찾고 있었기 때문에 op에 도움이되지 않았을 것입니다 ...하지만 지옥이 프로세스를 이해하는 데 도움이 된 것은 확실합니다.
신비한 콜라

1

간단하고 쉽습니다. 아래와 같이 URI에서이 작업을 수행 할 수 있습니다!

public void getContents(Uri uri)
{
    Cursor vidCursor = getActivity.getContentResolver().query(uri, null, null,
                                                              null, null);
    if (vidCursor.moveToFirst())
    {
        int column_index =
        vidCursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        Uri filePathUri = Uri.parse(vidCursor .getString(column_index));
        String video_name =  filePathUri.getLastPathSegment().toString();
        String file_path=filePathUri.getPath();
        Log.i("TAG", video_name + "\b" file_path);
    }
}

1

이 솔루션은 모든 경우에 적용됩니다.

경우에 따라 URL에서 경로를 얻는 것이 너무 어렵습니다. 그렇다면 왜 경로가 필요합니까? 다른 장소에 파일을 복사하려면? 당신은 경로가 필요하지 않습니다.

public void SavePhotoUri (Uri imageuri, String Filename){

    File FilePath = context.getDir(Environment.DIRECTORY_PICTURES,Context.MODE_PRIVATE);
    try {
        Bitmap selectedImage = MediaStore.Images.Media.getBitmap(context.getContentResolver(), imageuri);
        String destinationImagePath = FilePath + "/" + Filename;
        FileOutputStream destination = new FileOutputStream(destinationImagePath);
        selectedImage.compress(Bitmap.CompressFormat.JPEG, 100, destination);
        destination.close();
    }
    catch (Exception e) {
        Log.e("error", e.toString());
    }
}

0

게시물의 고정 코드를 완벽하게 처리합니다 .

  public static String getRealPathImageFromUri(Uri uri) {
        String fileName =null;
        if (uri.getScheme().equals("content")) {
            try (Cursor cursor = MyApplication.getInstance().getContentResolver().query(uri, null, null, null, null)) {
                if (cursor.moveToFirst()) {
                    fileName = cursor.getString(cursor.getColumnIndexOrThrow(ediaStore.Images.Media.DATA));
                }
            } catch (IllegalArgumentException e) {
                Log.e(mTag, "Get path failed", e);
            }
        }
        return fileName;
    }

0

추가 기능으로 입력 스트림을 열기 전에 파일이 있는지 확인해야하는 경우 DocumentsContract를 사용할 수 있습니다.

(코 틀린 코드)

var iStream = null
if(DocumentsContract.isDocumentUri(context,myUri)) {
   val pfd: ParcelFileDescriptor? = context.contentResolver.openFileDescriptor(
            myUri, "r") ?: return null
   iStream = ParcelFileDescriptor.AutoCloseInputStream(pfd)
}

0

위의 답변이 저에게 효과적이지 않았으므로 다음은 저에게 효과적입니다.

> 19 및 <= 19 API 레벨 모두.

이 방법은 URI에서 filePath를 얻는 모든 경우를 다룹니다.

/**
 * Get a file path from a Uri. This will get the the path for Storage Access
 * Framework Documents, as well as the _data field for the MediaStore and
 * other file-based ContentProviders.
 *
 * @param context The activity.
 * @param uri The Uri to query.
 * @author paulburke
 */
public static String getPath(final Context context, final Uri uri) {

    // DocumentProvider
    if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }else{
                Toast.makeText(context, "Could not get file path. Please try again", Toast.LENGTH_SHORT).show();
            }
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            } else {
                contentUri = MediaStore.Files.getContentUri("external");
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[] {
                    split[1]
            };

            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

0

모든 종류의 파일 경로를 얻으려면 다음을 사용하십시오.

/*
 * Copyright (C) 2007-2008 OpenIntents.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.yourpackage;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.MimeTypeMap;

import java.io.File;
import java.io.FileFilter;
import java.text.DecimalFormat;
import java.util.Comparator;
import java.util.List;

/**
 * @author Peli
 * @author paulburke (ipaulpro)
 * @version 2013-12-11
 */
public class FileUtils {
    private FileUtils() {
    } //private constructor to enforce Singleton pattern

    /**
     * TAG for log messages.
     */
    static final String TAG = "FileUtils";
    private static final boolean DEBUG = true; // Set to true to enable logging

    public static final String MIME_TYPE_AUDIO = "audio/*";
    public static final String MIME_TYPE_TEXT = "text/*";
    public static final String MIME_TYPE_IMAGE = "image/*";
    public static final String MIME_TYPE_VIDEO = "video/*";
    public static final String MIME_TYPE_APP = "application/*";

    public static final String HIDDEN_PREFIX = ".";

    /**
     * Gets the extension of a file name, like ".png" or ".jpg".
     *
     * @param uri
     * @return Extension including the dot("."); "" if there is no extension;
     * null if uri was null.
     */
    public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(".");
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            // No extension.
            return "";
        }
    }

    /**
     * @return Whether the URI is a local one.
     */
    public static boolean isLocal(String url) {
        if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
            return true;
        }
        return false;
    }

    /**
     * @return True if Uri is a MediaStore Uri.
     * @author paulburke
     */
    public static boolean isMediaUri(Uri uri) {
        return "media".equalsIgnoreCase(uri.getAuthority());
    }

    /**
     * Convert File into Uri.
     *
     * @param file
     * @return uri
     */
    public static Uri getUri(File file) {
        if (file != null) {
            return Uri.fromFile(file);
        }
        return null;
    }

    /**
     * Returns the path only (without file name).
     *
     * @param file
     * @return
     */
    public static File getPathWithoutFilename(File file) {
        if (file != null) {
            if (file.isDirectory()) {
                // no file to be split off. Return everything
                return file;
            } else {
                String filename = file.getName();
                String filepath = file.getAbsolutePath();

                // Construct path without file name.
                String pathwithoutname = filepath.substring(0,
                        filepath.length() - filename.length());
                if (pathwithoutname.endsWith("/")) {
                    pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length() - 1);
                }
                return new File(pathwithoutname);
            }
        }
        return null;
    }

    /**
     * @return The MIME type for the given file.
     */
    public static String getMimeType(File file) {

        String extension = getExtension(file.getName());

        if (extension.length() > 0)
            return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1));

        return "application/octet-stream";
    }

    /**
     * @return The MIME type for the give Uri.
     */
    public static String getMimeType(Context context, Uri uri) {
        File file = new File(getPath(context, uri));
        return getMimeType(file);
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is {@link LocalStorageProvider}.
     * @author paulburke
     */
    public static boolean isLocalStorageDocument(Uri uri) {
        return LocalStorageProvider.AUTHORITY.equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     * @author paulburke
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     * @author paulburke
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     * @author paulburke
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     * @author paulburke
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                if (DEBUG)
                    DatabaseUtils.dumpCursor(cursor);

                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * Get a file path from a Uri. This will quickGet the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.<br>
     * <br>
     * Callers should check whether the path is local before assuming it
     * represents a local file.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     * @see #isLocal(String)
     * @see #getFile(Context, Uri)
     */
    public static String getPath(final Context context, final Uri uri) {

        if (DEBUG)
            Log.d(TAG + " File -",
                    "Authority: " + uri.getAuthority() +
                            ", Fragment: " + uri.getFragment() +
                            ", Port: " + uri.getPort() +
                            ", Query: " + uri.getQuery() +
                            ", Scheme: " + uri.getScheme() +
                            ", Host: " + uri.getHost() +
                            ", Segments: " + uri.getPathSegments().toString()
            );
        // DocumentProvider
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
            // LocalStorageProvider
            if (isLocalStorageDocument(uri)) {
                // The path is the id
                return DocumentsContract.getDocumentId(uri);
            }
            // ExternalStorageProvider
            else if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

//                if ("primary".equalsIgnoreCase(type)) {
//                    return Environment.getExternalStorageDirectory() + "/" + split[1];
//                }
                return Environment.getExternalStorageDirectory() + "/" + split[1];

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                try {
                    final String id = DocumentsContract.getDocumentId(uri);
                    Log.d(TAG, "getPath: id= " + id);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                }catch (Exception e){
                    e.printStackTrace();
                    List<String> segments = uri.getPathSegments();
                    if(segments.size() > 1) {
                        String rawPath = segments.get(1);
                        if(!rawPath.startsWith("/")){
                            return rawPath.substring(rawPath.indexOf("/"));
                        }else {
                            return rawPath;
                        }
                    }
                }
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Convert Uri into File, if possible.
     *
     * @return file A local file that the Uri was pointing to, or null if the
     * Uri is unsupported or pointed to a remote resource.
     * @author paulburke
     * @see #getPath(Context, Uri)
     */
    public static File getFile(Context context, Uri uri) {
        if (uri != null) {
            String path = getPath(context, uri);
            if (path != null && isLocal(path)) {
                return new File(path);
            }
        }
        return null;
    }

    /**
     * Get the file size in a human-readable string.
     *
     * @param size
     * @return
     * @author paulburke
     */
    public static String getReadableFileSize(int size) {
        final int BYTES_IN_KILOBYTES = 1024;
        final DecimalFormat dec = new DecimalFormat("###.#");
        final String KILOBYTES = " KB";
        final String MEGABYTES = " MB";
        final String GIGABYTES = " GB";
        float fileSize = 0;
        String suffix = KILOBYTES;

        if (size > BYTES_IN_KILOBYTES) {
            fileSize = size / BYTES_IN_KILOBYTES;
            if (fileSize > BYTES_IN_KILOBYTES) {
                fileSize = fileSize / BYTES_IN_KILOBYTES;
                if (fileSize > BYTES_IN_KILOBYTES) {
                    fileSize = fileSize / BYTES_IN_KILOBYTES;
                    suffix = GIGABYTES;
                } else {
                    suffix = MEGABYTES;
                }
            }
        }
        return String.valueOf(dec.format(fileSize) + suffix);
    }

    /**
     * Attempt to retrieve the thumbnail of given File from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param file
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, File file) {
        return getThumbnail(context, getUri(file), getMimeType(file));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri) {
        return getThumbnail(context, uri, getMimeType(context, uri));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @param mimeType
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) {
        if (DEBUG)
            Log.d(TAG, "Attempting to quickGet thumbnail");

        if (!isMediaUri(uri)) {
            Log.e(TAG, "You can only retrieve thumbnails for images and videos.");
            return null;
        }

        Bitmap bm = null;
        if (uri != null) {
            final ContentResolver resolver = context.getContentResolver();
            Cursor cursor = null;
            try {
                cursor = resolver.query(uri, null, null, null, null);
                if (cursor.moveToFirst()) {
                    final int id = cursor.getInt(0);
                    if (DEBUG)
                        Log.d(TAG, "Got thumb ID: " + id);

                    if (mimeType.contains("video")) {
                        bm = MediaStore.Video.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Video.Thumbnails.MINI_KIND,
                                null);
                    } else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) {
                        bm = MediaStore.Images.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Images.Thumbnails.MINI_KIND,
                                null);
                    }
                }
            } catch (Exception e) {
                if (DEBUG)
                    Log.e(TAG, "getThumbnail", e);
            } finally {
                if (cursor != null)
                    cursor.close();
            }
        }
        return bm;
    }

    /**
     * File and folder comparator. TODO Expose sorting option method
     *
     * @author paulburke
     */
    public static Comparator<File> sComparator = new Comparator<File>() {
        @Override
        public int compare(File f1, File f2) {
            // Sort alphabetically by lower case, which is much cleaner
            return f1.getName().toLowerCase().compareTo(
                    f2.getName().toLowerCase());
        }
    };

    /**
     * File (not directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sFileFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return files only (not directories) and skip hidden files
            return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Folder (directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sDirFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return directories only and skip hidden directories
            return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Get the Intent for selecting content to be used in an Intent Chooser.
     *
     * @return The intent for opening a file with Intent.createChooser()
     * @author paulburke
     */
    public static Intent createGetContentIntent() {
        // Implicitly allow the user to select a particular kind of data
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // The MIME data type filter
        intent.setType("*/*");
        // Only return URIs that can be opened with ContentResolver
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        return intent;
    }
}

Zain

마지막으로 작동하는 방법! (이 코드에서 방금 LocalStorageProvider를 제거했습니다)
Starwave

0

아래의 방법이 Oreo 8.1에서도 훌륭하게 작동하는지 확인하십시오 ..

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO ManualMT-generated method stub
    switch (requestCode) {
        case PICKFILE_RESULT_CODE:
            if (resultCode == RESULT_OK) {

                try {
                    FilePath = data.getData().getPath();
                    Uri selectedImageUri = data.getData();

                    if (selectedImageUri.toString().contains("storage/emulated")){
                        String[] split = selectedImageUri.toString().split("storage/");
                        FilePath = "storage/"+split[1];
                    } else {
                        FilePath = ImageFilePath.getPath(getApplicationContext(), selectedImageUri);
                    }

                    recyclerview.setVisibility(View.VISIBLE);

                    if (FilePath == null) {
                        FilePath = "";
                    }
                    File file = new File(FilePath);
                    reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                    image_list.add(FilePath);
                    composeImageAdapter.notifyDataSetChanged();
                } catch (Exception e){
                    Toast.makeText(ClusterCreateNote.this , e.toString(),Toast.LENGTH_SHORT).show();
                }
            }
            break;
    }

}

URI 경로 클래스 :

public static class ImageFilePath {

    /**
     * Method for return file path of Gallery image
     *
     * @param context
     * @param uri
     * @return path of the selected image file from gallery
     */
    public static String getPath(final Context context, final Uri uri) {
        String selection = null;
        String[] selectionArgs = null;

        // DocumentProvider
        if (DocumentsContract.isDocumentUri(context, uri)) {

            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.wifAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Log.e("typetype",type);

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                selection = "_id=?";
                selectionArgs = new String[]{
                        split[1]
                };

                Log.e("gddhjf",getDataColumn(context, contentUri, selection, selectionArgs));

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        if ("content".equalsIgnoreCase(uri.getScheme())) {


            if (isGooglePhotosUri(uri)) {
                return uri.getLastPathSegment();
            }

            String[] projection = {
                    MediaStore.Images.Media.DATA
            };
            Cursor cursor = null;
            try {
                cursor = context.getContentResolver()
                        .query(uri, projection, selection, selectionArgs, null);
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                if (cursor.moveToFirst()) {
                    return cursor.getString(column_index);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }


    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return
                "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    public static boolean isGooglePhotosUri(Uri uri) {
        return
                "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }
}

1
데이터 열을 사용하면 더 이상 작동하지 않습니다.
HB.

0

하나의 라이너 로이 작업을 수행합니다.

val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)

onActivityResult에서 다음과 같이 보입니다.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_IMAGE_PICKER ) {
        data?.data?.let { imgUri: Uri ->
            val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imgUri)
        }
    }
}

어떤 이유로 삼성 갤러리 앱을 사용하여 이미지를 선택하면이 방법이 작동하지 않습니다.
KMC

기묘한. 나는 Samsung Galaxy S10을 개발 중이었습니다.
Joel Broström

0

API 레벨 29 Android Q 이후에는 상황이 복잡해졌습니다 . 콘텐츠 Uri에서 파일 이름을 가져 오는 방법입니다.

        public static String getNameFromContentUri(Context context, Uri contentUri){  
                            Cursor returnCursor = context.getContentResolver().query(contentUri, null, null, null, null);
                            int nameColumnIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                            returnCursor.moveToFirst();
                            String fileName = returnCursor.getString(nameColumnIndex);
                            return fileName;}

이것이 모든 안드로이드 버전에 대한 콘텐츠 URI의 전체 경로를 얻는 방법입니다

public static String getFullPathFromContentUri(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if ("com.android.externalstorage.documents".equals(uri.getAuthority())) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                   Cursor cursor = null;
                   final String column = "_data";
                   final String[] projection = {
                      column
                    };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

private static String getDataColumn(Context context, Uri uri, String selection,
                                 String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

0

시스템 버전이 19 이상인 경우 완벽하게 작동합니다. 희망이 있습니다.

  @TargetApi(Build.VERSION_CODES.KITKAT)
    public static String getPath(final Context context, final Uri uri) {
        final boolean isOverKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        // DocumentProvider
        if (isOverKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/"
                            + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection,
                        selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }

-2

Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);


이것은 질문에 대한 답변을 제공하지 않습니다. 평판 이 충분 하면 모든 게시물댓글 수 있습니다 . 대신 asker의 설명이 필요없는 답변을 제공하십시오 . - 리뷰에서
ישו אוהב אותך

"어딘가에 복사하지 않고 이미지를 비트 맵에로드하고 싶습니다." 이 답변이 질문에 대한 답변을 제공한다고 생각합니다.
Drastaro
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.