简体   繁体   English

在 Android 的默认图库图像查看器中使用 URI 打开图像

[英]Open an image using URI in Android's default gallery image viewer

I have extracted image uri, now I would like to open image with Android's default image viewer.我已经提取了图像 uri,现在我想用 Android 的默认图像查看器打开图像。 Or even better, user could choose what program to use to open the image.或者更好的是,用户可以选择使用什么程序打开图像。 Something like File Explorers offer you if you try to open a file.如果您尝试打开文件,文件资源管理器之类的东西会为您提供。

Accepted answer was not working for me,接受的答案对我不起作用,

What had worked:什么起作用了:

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

If your app targets Android N (7.0) and above, you should not use the answers above (of the "Uri.fromFile" method), because it won't work for you.如果您的应用程序以 Android N (7.0) 及更高版本为目标,则您不应使用上面的答案(“Uri.fromFile”方法),因为它对您不起作用。

Instead, you should use a ContentProvider.相反,您应该使用 ContentProvider。

For example, if your image file is in external folder, you can use this (similar to the code I've made here ):例如,如果您的图像文件在外部文件夹中,您可以使用它(类似于我在这里制作的代码):

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

manifest:显现:

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

If your image is in the private path of the app, you should create your own ContentProvider, as I've created "OpenFileProvider" on the link.如果您的图像位于应用程序的私有路径中,您应该创建自己的 ContentProvider,因为我已经在链接上创建了“OpenFileProvider”。

Ask myself, answer myself also:问我自己,也回答我自己:

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

It will also ask what program to use to view the file.它还将询问使用什么程序来查看文件。

Try use it:尝试使用它:

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

Based on Vikas answer but with a slight modification: The Uri is received by parameter:基于Vikas 的回答,但稍作修改:Uri 由参数接收:

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

This thing might help if your working with android N and below如果您使用的是 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

A much cleaner, safer answer to this problem (you really shouldn't hard code 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);
}

All you have to do is append the image id to the end of the path for the EXTERNAL_CONTENT_URI .您所要做的就是将图像 ID 附加到EXTERNAL_CONTENT_URI的路径末尾。 Then launch an Intent with the View action, and the Uri.然后使用 View 操作和 Uri 启动 Intent。

The image id comes from querying the content resolver.图像 ID 来自查询内容解析器。

All the above answers not opening image.. when second time I try to open it show the gallery not image.以上所有答案均未打开图像。当我第二次尝试打开它时,显示的是图库而不是图像。

I got solution from mix of various SO answers..我从各种 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);

This one only worked for me..这个只对我有用..

The problem with showing a file using Intent.ACTION_VIEW , is that if you pass the Uri parsing the path.使用Intent.ACTION_VIEW显示文件的问题在于,如果您传递解析路径的Uri Doesn't work in all cases.并非在所有情况下都有效。 To fix that problem, you need to use:要解决该问题,您需要使用:

Uri.fromFile(new File(filePath));

Instead of:代替:

Uri.parse(filePath);

Edit编辑

Here is my complete code:这是我的完整代码:

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

Info信息

MediaFile is my domain class to wrap files from database in objects. MediaFile是我的域类,用于将数据库中的文件包装在对象中。 MediaFile.getExtension() returns a String with Mimetype for the file extension. MediaFile.getExtension()返回一个带有文件扩展名的MimetypeString Example: "image/png"示例: "image/png"


Aditional code: needed for showing any file (extension)附加代码:需要显示任何文件(扩展名)

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

Let me know if you need more code.如果您需要更多代码,请告诉我。

I use this it works for me我用这个对我有用

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

My solution using File Provider我使用文件提供程序的解决方案

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

Almost NO chance to use photo or gallery application(might exist one), but you can try the content-viewer.几乎没有机会使用照片或画廊应用程序(可能存在),但您可以尝试内容查看器。

Please checkout another answer to similar question here在此处查看类似问题的另一个答案

My solution我的解决方案

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

The uri must be content uri not file uri, You can get contentUri by FileProvider as uri 必须是内容 uri 而不是文件 uri,您可以通过 FileProvider 获取 contentUri 作为

Uri contentUri = FileProvider.getUriForFile(getContext(),"com.github.myApp",curFile);

Don't forget adding provider in Manifest file.不要忘记在清单文件中添加提供程序。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM