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.