Mở hình ảnh bằng URI trong trình xem hình ảnh thư viện mặc định của Android


83

Tôi đã trích xuất hình ảnh uri, bây giờ tôi muốn mở hình ảnh bằng trình xem ảnh mặc định của Android. Hoặc thậm chí tốt hơn, người dùng có thể chọn chương trình sử dụng để mở hình ảnh. Một cái gì đó giống như File Explorers cung cấp cho bạn nếu bạn cố gắng mở một tệp.

Câu trả lời:


168

Câu trả lời được chấp nhận không phù hợp với tôi,

Những gì đã hoạt động:

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

4
vâng, nhưng làm thế nào để bạn tránh được trên android 2.2 và 2.3 rằng màn hình đen 10 giây chờ đợi trong khi bộ sưu tập cho biết nó tìm kiếm fotos và album mới?
max4ever

@ max4ever: Bạn đã tìm ra giải pháp cho vấn đề chưa?
Code_Life 8/10/12

4
vâng,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 sẽ hiển thị cho bạn hình ảnh nếu bạn chỉ chỉ định "hình ảnh / *". Điều này sẽ không hoạt động trên Android 2.3. Bạn PHẢI chỉ định loại kịch câm: "image / jpeg".
AndroidDev

6
Câu trả lời này kết thúc với file:///sdcard...- đó là cố ý?
Danyal Aytekin

38

Nếu ứng dụng của bạn nhắm mục tiêu Android N (7.0) trở lên, bạn không nên sử dụng các câu trả lời ở trên (của phương pháp "Uri.fromFile") vì nó sẽ không phù hợp với bạn.

Thay vào đó, bạn nên sử dụng ContentProvider.

Ví dụ: nếu tệp hình ảnh của bạn nằm trong thư mục bên ngoài, bạn có thể sử dụng điều này (tương tự như mã tôi đã tạo ở đây ):

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);

rõ ràng:

<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>

Nếu hình ảnh của bạn nằm trong đường dẫn riêng của ứng dụng, bạn nên tạo ContentProvider của riêng mình, vì tôi đã tạo "OpenFileProvider" trên liên kết.


Có, chỉ điều này hoạt động và giải quyết được vấn đề của tôi từ Android N và Oreo. Cảm ơn nhiều. Bạn hoàn toàn đúng!
Serg Burlaka

Cảm ơn rất nhiều!! chỉ giải pháp này công trình cho các phiên bản mới hơn android
Divakar Rajesh

Nó có áp dụng cho các tệp được lưu trong không gian dùng chung (thẻ SD) không?
Albert221

@ Albert221 Nó nên, nhưng tôi không nghĩ rằng tôi đã thử nghiệm nó. Hãy thử và cho tôi biết.
nhà phát triển android

Không làm việc cho Android 10 trong trường hợp khi tôi có Uri cho một hình ảnh được lưu vào Gallery
rommex

29

Hãy tự hỏi bản thân mình, cũng hãy tự trả lời:

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

Nó cũng sẽ hỏi chương trình sử dụng để xem tệp.


2
Xin chào hari, mã của bạn rất hữu ích để mở hình ảnh. Bạn có thể có một giải pháp để mở thư mục của bộ sưu tập. đây là câu hỏi của tôi stackoverflow.com/questions/6519024/...
ĐK

@djk Tôi chỉ trả lời nhiệm vụ này ở đây stackoverflow.com/questions/6074270/… xem nó có liên quan đến câu hỏi của bạn không.
PiyushMishra

Đề phòng trường hợp ai đó khác gặp phải vấn đề tương tự như tôi - tôi đã thêm ý định.setType ("image / png") (tôi biết hình ảnh sẽ là tệp png) và nó ngăn thư viện mở hình ảnh! Vì vậy, .setType phản tác dụng ở đây :)
Daniel

Ngoài ra, bạn có thể sử dụng intent.setDataAndType(uri, "image/*");để buộc Android sử dụng ứng dụng xem hình ảnh.
Diego Stiehl

Có thể sử dụng phương pháp này để tránh tạo bố cục mới chỉ để xem hình ảnh không?
Marek

20

Hãy thử sử dụng nó:

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);

Đây là hoàn hảo! Nó mở ra cửa sổ bật lên / bố cục dựa trên hệ điều hành android, để người dùng có thể chọn trình phát hoặc trình xem dựa trên sự lựa chọn của người dùng. ví dụ, để hiển thị hình ảnh, nhạc, video, ứng dụng hoặc thậm chí bất kỳ tệp nào.
Pratik Saluja

Tôi gặp lỗi "hiển thị bên ngoài ứng dụng thông qua Intent.getData ()".
Ramiz Ansari

Nếu bạn đang gặp lỗi "hiển thị bên ngoài ứng dụng thông qua Intent.getData ()", bạn có thể kiểm tra liên kết này để giải quyết sự cố stackoverflow.com/a/45751453/10619147
Wojuola Ayotola

18

Dựa trên câu trả lời của Vikas nhưng có một chút sửa đổi: Uri được nhận bằng tham số:

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

1
Điều này chỉ hiển thị một hình ảnh được chọn duy nhất và không hiển thị các hình ảnh khác trong cùng một thư mục (để người dùng có thể vuốt sang trái / phải để xem các hình ảnh khác). Bất kỳ ý tưởng làm thế nào để đạt được điều này?
Atul

@Atul trong trường hợp đó trường hợp sử dụng hoàn toàn khác. OP muốn hiển thị một hình ảnh X bằng cách sử dụng URI của nó. Có vẻ như bạn muốn a) Mở thư viện ở vị trí xác định hoặc b) Mở trong thư viện một tập hợp con các ảnh mà bạn có URI. Thực hiện một số nghiên cứu trên web hoặc đặt một câu hỏi mới, vì trường hợp sử dụng của bạn hoàn toàn khác.
Joaquin Iurchuk

Cảm ơn vì đã phản hồi sớm. Tôi cần đạt được những gì OP đã yêu cầu. Câu trả lời của bạn (và của Vikas) đạt được điều đó rất tốt, Chỉ có điều, khi nó hiển thị hình ảnh, nó không cho phép cuộn qua các hình ảnh khác trong cùng một thư mục (khi người dùng vuốt sang trái hoặc phải). Tôi đã thấy nhiều ứng dụng (ví dụ: WhatsApp) hiển thị hình ảnh trong trình xem thư viện (giống như những gì bạn làm) nhưng chúng cũng cho phép người dùng cuộn qua các hình ảnh bên trái bên phải trong cùng một thư mục.
Atul

@Atul OP muốn mở một hình ảnh với Thư viện được cung cấp URI của nó. Việc triển khai WhatsApp hoàn toàn khác. Tôi không biết Gallery có hỗ trợ nhận Intent với nhiều URI hay không. Dù sao, hãy kiểm tra điều này, nó có thể giúp bạn.
Joaquin Iurchuk

Tôi đã thấy liên kết bạn đưa ra. Dù sao đi nữa cũng xin cám ơn. Nhưng tôi thấy ai đó đã đăng một câu hỏi về những gì tôi muốn. Tuy nhiên, câu trả lời của anh ta quá ngắn gọn để hiểu.
Atul

11

Điều này có thể hữu ích nếu bạn làm việc với Android N trở xuống

 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 đã trợ giúp để xem hình ảnh bằng Intent.ACTION_VIEW
Pavan

Đã làm cho tôi. Chỉ cần nhớ nếu bạn đang sử dụng "ý định.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);" thì bạn phải thêm "ý định.setFlags (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);" sau đó .. Cảm ơn vì giải pháp tuyệt vời.
Snehal agrawal

6

Một câu trả lời rõ ràng hơn, an toàn hơn cho vấn đề này (bạn thực sự không nên viết mã Strings):

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);
}

Tất cả những gì bạn phải làm là thêm id hình ảnh vào cuối đường dẫn cho EXTERNAL_CONTENT_URI . Sau đó, khởi chạy Ý định với hành động Xem và Uri.

Id hình ảnh đến từ việc truy vấn trình phân giải nội dung.


Nó có cho phép người dùng vuốt và cuộn qua các hình ảnh khác trong cùng một thư mục không?
Atul

4

Tất cả các câu trả lời ở trên không mở hình ảnh .. khi tôi cố gắng mở lần thứ hai nó hiển thị thư viện không phải hình ảnh.

Tôi nhận được giải pháp từ sự kết hợp của nhiều câu trả lời SO khác nhau ..

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);

Cái này chỉ làm việc cho tôi ..


4

Vấn đề với việc hiển thị tệp bằng cách sử dụng Intent.ACTION_VIEW, là nếu bạn chuyển Uriđường dẫn phân tích cú pháp. Không hoạt động trong mọi trường hợp. Để khắc phục sự cố đó, bạn cần sử dụng:

Uri.fromFile(new File(filePath));

Thay vì:

Uri.parse(filePath);

Biên tập

Đây là mã hoàn chỉnh của tôi:

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);

Thông tin

MediaFilelà lớp miền của tôi để bọc các tệp từ cơ sở dữ liệu trong các đối tượng. MediaFile.getExtension()trả về một Stringvới Mimetypecho phần mở rộng tệp. Thí dụ:"image/png"


Mã bổ sung: cần thiết để hiển thị bất kỳ tệp nào (phần mở rộng)

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();
    }
}

Hãy cho tôi biết nếu bạn cần thêm mã.


3

Tôi sử dụng cái này, nó phù hợp với tôi

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

1

Giải pháp của tôi bằng cách sử dụng Trình cung cấp tệp

    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

Hầu như KHÔNG có cơ hội sử dụng ứng dụng ảnh hoặc thư viện (có thể tồn tại một ứng dụng), nhưng bạn có thể thử trình xem nội dung.

Vui lòng xem một câu trả lời khác cho câu hỏi tương tự tại đây


0

Giải pháp của tôi

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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.