Android의 기본 갤러리 이미지 뷰어에서 URI를 사용하여 이미지 열기


85

이미지 uri를 추출했습니다. 이제 Android의 기본 이미지 뷰어로 이미지를 열고 싶습니다. 또는 더 나은 방법은 사용자가 이미지를 여는 데 사용할 프로그램을 선택할 수 있다는 것입니다. 파일을 열려고하면 파일 탐색기와 같은 기능이 제공됩니다.

답변:


168

받아 들인 대답이 저에게 효과가 없었습니다.

효과가 있었던 것 :

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + "/sdcard/test.jpg"), "image/*");
startActivity(intent);

4
네,하지만 안드로이드 2.2와 2.3에서 갤러리가 새로운 사진과 앨범을 검색한다고 말하는 동안 10 초간 검은 화면이 기다리는 것을 어떻게 피합니까?
max4ever

@ max4ever : 문제에 대한 해결책을 찾았습니까?
Code_Life 2012 년

4
예,File f = new File(..., ...); if (f.isFile()) { MediaScannerConnection.scanFile(SchedaActivity.this, new String[] { f.toString() }, null, new MediaScannerConnection.OnScanCompletedListener() { @Override public void onScanCompleted(String path, Uri uri) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri, "image/*"); SchedaActivity.this.startActivityForResult(intent, SchedaActivity.this.ACTIVITY_CODE); } });
max4ever

1
Android 4.1은 "image / *"만 지정하면 이미지를 표시합니다. Android 2.3에서는 작동하지 않습니다. MIME 유형 ( "image / jpeg")을 지정해야합니다.
AndroidDev 2013

6
이 답변은 file:///sdcard...-의도적입니까?
Danyal Aytekin 2014 년

38

앱이 Android N (7.0) 이상을 대상으로하는 경우 위의 답변 ( "Uri.fromFile"메서드의)을 사용해서는 안됩니다. 작동하지 않기 때문입니다.

대신 ContentProvider를 사용해야합니다.

예를 들어 이미지 파일이 외부 폴더에있는 경우 다음을 사용할 수 있습니다 ( 여기에서 만든 코드와 유사 함 ).

File file = ...;
final Intent intent = new Intent(Intent.ACTION_VIEW)//
                                    .setDataAndType(VERSION.SDK_INT >= VERSION_CODES.N ?
                                                    FileProvider.getUriForFile(this,getPackageName() + ".provider", file) : Uri.fromFile(file),
                            "image/*").addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

명백한:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

res / xml / provider_paths.xml :

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <!--<external-path name="external_files" path="."/>-->
    <external-path
        name="files_root"
        path="Android/data/${applicationId}"/>
    <external-path
        name="external_storage_root"
        path="."/>
</paths>

이미지가 앱의 개인 경로에있는 경우 링크에 "OpenFileProvider"를 만들었으므로 고유 한 ContentProvider를 만들어야합니다.


예, 이것은 Android N 및 Oreo에서 내 문제를 해결했습니다. 많은 감사합니다. 너가 확실히 맞아!
Serg Burlaka

감사합니다 !! 안드로이드 최신 버전 만이 솔루션은 작품
Divakar 인 Rajesh

공유 공간 (SD 카드)에 저장된 파일에도 적용 되나요?
Albert221

@ Albert221 그래야하지만 내가 테스트했다고 생각하지 않습니다. 제발 알려주세요.
안드로이드 개발자

갤러리에 저장된 이미지에 Uri가있는 경우 Android 10에서 작동하지 않습니다
rommex

29

나 자신에게 물어보고 나 자신에게도 대답하십시오.

startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("content://media/external/images/media/16"))); /** replace with your own uri */

또한 파일을 보는 데 사용할 프로그램을 묻습니다.


2
안녕하세요, 귀하의 코드는 이미지를 여는 데 유용합니다. 갤러리 폴더를 여는 솔루션을 가질 수 있습니까? 여기 내 질문이 있습니다. stackoverflow.com/questions/6519024/…
djk

@djk 여기에이 질문에 대답합니다. stackoverflow.com/questions/6074270/… 질문과 관련이 있는지 확인합니다.
PiyushMishra 2011

다른 사람이 나와 같은 문제에 봉착하는 경우를 대비하여 intent.setType ( "image / png")을 추가했습니다 (이미지가 png 파일 인 것을 알고 있음). 갤러리에서 이미지를 열 수 없습니다! 따라서 .setType은 여기에서 비생산적입니다. :)
Daniel

또한를 사용 intent.setDataAndType(uri, "image/*");하여 Android에서 이미지보기 앱을 사용하도록 할 수 있습니다.
Diego Stiehl 2014

이 방법을 사용하여 이미지를보기위한 새 레이아웃 생성을 방지 할 수 있습니까?
Marek

21

그것을 사용해보십시오 :

Uri uri =  Uri.fromFile(entry);
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
String mime = "*/*";
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
if (mimeTypeMap.hasExtension(
    mimeTypeMap.getFileExtensionFromUrl(uri.toString())))
    mime = mimeTypeMap.getMimeTypeFromExtension(
        mimeTypeMap.getFileExtensionFromUrl(uri.toString()));
intent.setDataAndType(uri,mime);
startActivity(intent);

이것은 완벽 해요! 안드로이드 OS 기반의 팝업 / 레이아웃을 열어 사용자의 선택에 따라 플레이어 또는 뷰어를 선택할 수 있습니다. 예를 들어 이미지, 음악, 비디오, 앱 또는 모든 파일을 표시합니다.
Pratik Saluja

"Intent.getData ()를 통해 앱을 넘어서 노출"오류가 발생했습니다.
Ramiz Ansari

당신이 "Intent.getData를 통해 응용 프로그램을 넘어 노출 ()"지고 경우 문제 해결이 링크를 확인할 수 있습니다 오류 stackoverflow.com/a/45751453/10619147을
Wojuola Ayotola

18

Vikas 답변을 기반으로 하지만 약간 수정 : Uri는 매개 변수에 의해 수신됩니다.

private void showPhoto(Uri photoUri){
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    intent.setDataAndType(photoUri, "image/*");
    startActivity(intent);
}

1
선택한 이미지는 하나만 표시되고 동일한 폴더의 다른 이미지는 표시되지 않습니다 (사용자가 왼쪽 / 오른쪽으로 스 와이프하여 다른 이미지를 볼 수 있음). 이것을 달성하는 방법을 아십니까?
Atul

이 경우 @Atul은 사용 사례가 완전히 다릅니다. OP는 URI를 사용하여 X 이미지를 표시하려고합니다. a) 결정된 위치에서 갤러리를 열거 나 b) URI가있는 사진의 하위 집합을 갤러리에서 엽니 다. 사용 사례가 완전히 다르므로 웹에서 조사하거나 새로운 질문을하십시오.
Joaquin Iurchuk 2016

빠른 답장을 보내 주셔서 감사합니다. OP가 요청한 것과 동일한 것을 달성해야합니다. 귀하의 (및 Vikas의) 답변은 그것을 매우 잘 달성합니다. 단지 한 번 이미지가 표시되면 동일한 폴더의 다른 이미지를 스크롤 할 수 없습니다 (사용자가 왼쪽 또는 오른쪽으로 스 와이프 할 때). 많은 앱 (예 : WhatsApp)이 갤러리 뷰어에 이미지를 표시하는 것을 보았습니다 (당신이하는 것과 똑같습니다).하지만 사용자가 같은 폴더에있는 왼쪽 오른쪽 이미지를 스크롤 할 수도 있습니다.
Atul

@Atul OP는 URI가 주어진 갤러리로 하나의 이미지 를 열려고 합니다. WhatsApp 구현은 완전히 다릅니다. 갤러리가 URI가 많은 인 텐트 수신을 지원하는지 여부를 모르겠습니다. 어쨌든, 이것을 확인하면 도움이 될 것입니다.
Joaquin Iurchuk 2016

나는 당신이 준 링크를 이미 보았다. 어쨌든 고마워. 그러나 누군가 내가 원하는 것에 대한 질문 을 이미 게시 한 것을 발견했습니다 . 그러나 그의 대답은 이해하기에는 너무 짧습니다.
Atul

11

Android N 이하로 작업하는 경우 도움이 될 수 있습니다.

 File file=new File(Environment.getExternalStorageDirectory()+"/directoryname/"+filename);
        Uri path= FileProvider.getUriForFile(MainActivity.this,BuildConfig.APPLICATION_ID + ".provider",file);

        Intent intent=new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(path,"image/*");
        intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION); //must for reading data from directory

FLAG_GRANT_READ_URI_PERMISSION은 Intent.ACTION_VIEW를 사용하여 이미지를 보는 데 도움이되었습니다
Pavan

나를 위해 일했습니다. "intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);"를 사용하고 있는지 기억하십시오. 그런 다음 "intent.setFlags (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);"을 추가해야합니다. 그 후 .. 멋진 솔루션에 감사드립니다.
snehal agrawal

6

이 문제에 대한 훨씬 더 깨끗하고 안전한 답입니다 (정말로 문자열을 하드 코딩해서는 안됩니다).

public void openInGallery(String imageId) {
  Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon().appendPath(imageId).build();
  Intent intent = new Intent(Intent.ACTION_VIEW, uri);
  startActivity(intent);
}

EXTERNAL_CONTENT_URI 경로 끝에 이미지 ID를 추가하기 만하면 됩니다. 그런 다음보기 작업과 Uri를 사용하여 인 텐트를 시작합니다.

이미지 ID는 콘텐츠 리졸버 쿼리에서 제공됩니다.


사용자가 같은 폴더에있는 다른 이미지를 스 와이프하고 스크롤 할 수 있습니까?
Atul

4

위의 모든 답변은 이미지를 열지 않습니다. 두 번째로 열려고하면 이미지가 아닌 갤러리가 표시됩니다.

다양한 SO 답변을 혼합하여 솔루션을 얻었습니다 ..

Intent galleryIntent = new Intent(Intent.ACTION_VIEW, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
galleryIntent.setDataAndType(Uri.fromFile(mImsgeFileName), "image/*");
galleryIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(galleryIntent);

이건 저 한테만 효과가 있었어요 ..


4

를 사용하여 파일을 표시 할 때의 문제 는 경로 구문 분석 Intent.ACTION_VIEW을 전달하는 것 Uri입니다. 모든 경우에 작동하지 않습니다. 이 문제를 해결하려면 다음을 사용해야합니다.

Uri.fromFile(new File(filePath));

대신에:

Uri.parse(filePath);

편집하다

내 완전한 코드는 다음과 같습니다.

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(mediaFile.filePath)), mediaFile.getExtension());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

정보

MediaFile데이터베이스의 파일을 개체로 래핑하는 도메인 클래스입니다. 파일 확장자에 MediaFile.getExtension()대해 Stringwith Mimetype를 반환합니다 . 예:"image/png"


추가 코드 : 모든 파일 (확장자)을 표시하는 데 필요

import android.webkit.MimeTypeMap;

public String getExtension () {
    MimeTypeMap myMime = MimeTypeMap.getSingleton();
    return myMime.getMimeTypeFromExtension(MediaFile.fileExtension(filePath));
}

public static String fileExtension(String path) {
    if (path.indexOf("?") > -1) {
        path = path.substring(0, path.indexOf("?"));
    }
    if (path.lastIndexOf(".") == -1) {
        return null;
    } else {
        String ext = path.substring(path.lastIndexOf(".") + 1);
        if (ext.indexOf("%") > -1) {
            ext = ext.substring(0, ext.indexOf("%"));
        }
        if (ext.indexOf("/") > -1) {
            ext = ext.substring(0, ext.indexOf("/"));
        }
        return ext.toLowerCase();
    }
}

더 많은 코드가 필요하면 알려주세요.


3

나는 이것을 사용한다 그것은 나를 위해 일한다

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), 1);

2

파일 공급자를 사용하는 내 솔루션

    private void viewGallery(File file) {

 Uri mImageCaptureUri = FileProvider.getUriForFile(
  mContext,
  mContext.getApplicationContext()
  .getPackageName() + ".provider", file);

 Intent view = new Intent();
 view.setAction(Intent.ACTION_VIEW);
 view.setData(mImageCaptureUri);
 List < ResolveInfo > resInfoList =
  mContext.getPackageManager()
  .queryIntentActivities(view, PackageManager.MATCH_DEFAULT_ONLY);
 for (ResolveInfo resolveInfo: resInfoList) {
  String packageName = resolveInfo.activityInfo.packageName;
  mContext.grantUriPermission(packageName, mImageCaptureUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
 }
 view.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
 Intent intent = new Intent();
 intent.setAction(Intent.ACTION_VIEW);
 intent.setDataAndType(mImageCaptureUri, "image/*");
 mContext.startActivity(intent);
}

0

거의 NO 사용 사진이나 갤러리 응용 프로그램 (하나있을 수있는) 기회,하지만 당신은 컨텐츠 뷰어를 시도 할 수 있습니다.

여기 에서 유사한 질문에 대한 다른 답변을 확인 하십시오.


0

내 솔루션

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory().getPath()+"/your_app_folder/"+"your_picture_saved_name"+".png")), "image/*");
context.startActivity(intent);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.