Öffnen Sie ein Bild mit URI in der Standard-Galerie-Bildanzeige von Android

82

Ich habe Bild-Uri extrahiert, jetzt möchte ich das Bild mit dem Standard-Bildbetrachter von Android öffnen. Oder noch besser, der Benutzer kann auswählen, mit welchem ​​Programm das Bild geöffnet werden soll. So etwas wie File Explorer bieten Ihnen, wenn Sie versuchen, eine Datei zu öffnen.

Badr Hari
quelle

Antworten:

168

Akzeptierte Antwort funktionierte nicht für mich,

Was hatte funktioniert:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + "/sdcard/test.jpg"), "image/*");
startActivity(intent);
Vikas
quelle
4
Ja, aber wie vermeidest du auf Android 2.2 und 2.3, dass 10 Sekunden schwarzer Bildschirm warten, während die Galerie sagt, dass nach neuen Fotos und Alben gesucht wird?
Max4ever
@ max4ever: Haben Sie eine Lösung für Ihr Problem gefunden?
Code_Life
4
ja,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 zeigt Ihnen ein Bild, wenn Sie nur "image / *" angeben. Dies funktioniert nicht unter Android 2.3. Sie MÜSSEN den MIME-Typ angeben: "image / jpeg".
AndroidDev
6
Diese Antwort endet mit file:///sdcard...- ist das beabsichtigt?
Danyal Aytekin
38

Wenn Ihre App auf Android N (7.0) und höher ausgerichtet ist, sollten Sie die obigen Antworten (der Methode "Uri.fromFile") nicht verwenden, da dies für Sie nicht funktioniert.

Verwenden Sie stattdessen einen ContentProvider.

Wenn sich Ihre Bilddatei beispielsweise in einem externen Ordner befindet, können Sie dies verwenden (ähnlich dem Code, den ich hier erstellt habe ):

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

Wenn sich Ihr Bild im privaten Pfad der App befindet, sollten Sie Ihren eigenen ContentProvider erstellen, da ich über den Link "OpenFileProvider" erstellt habe.

Android-Entwickler
quelle
Ja, nur das funktioniert und hat mein Problem mit Android N und Oreo gelöst. Vielen Dank. Du liegst absolut richtig!
Serg Burlaka
Danke vielmals!! Nur diese Lösung funktioniert für neuere Android-Versionen
Divakar Rajesh
Gilt dies auch für Dateien, die im gemeinsam genutzten Speicherplatz (SD-Karte) gespeichert sind?
Albert221
@ Albert221 Es sollte, aber ich glaube nicht, dass ich es getestet habe. Bitte versuchen Sie es und lassen Sie es mich wissen.
Android-Entwickler
Funktioniert nicht für Android 10, wenn ich Uri zu einem Bild in der Galerie gespeichert habe
Rommex
29

Fragen Sie sich, antworten Sie mir auch:

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

Sie werden auch gefragt, mit welchem ​​Programm die Datei angezeigt werden soll.

Badr Hari
quelle
2
Hallo Hari, dein Code ist nützlich zum Öffnen des Bildes. Können Sie eine Lösung haben, um den Ordner der Galerie zu öffnen? Hier ist meine Frage stackoverflow.com/questions/6519024/…
djk
@djk Ich beantworte diese Quest einfach hier stackoverflow.com/questions/6074270/… um zu sehen, ob sie sich auf deine Frage bezieht.
PiyushMishra
Nur für den Fall, dass jemand anderes das gleiche Problem wie ich hat - ich habe intent.setType ("image / png") hinzugefügt (ich wusste, dass das Bild eine PNG-Datei sein würde) und es hat die Galerie daran gehindert, das Bild zu öffnen! Also .setType ist hier kontraproduktiv :)
Daniel
Darüber hinaus können Sie intent.setDataAndType(uri, "image/*");Android zwingen, eine App zum Anzeigen von Bildern zu verwenden.
Diego Stiehl
Kann diese Methode verwendet werden, um zu vermeiden, dass ein neues Layout erstellt wird, nur um das Bild anzuzeigen?
Marek
20

Versuchen Sie es:

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);
Eugene
quelle
Dies ist perfekt! Es öffnet Popup / Layout basierend auf Android OS, so dass Benutzer Player oder Viewer basierend auf Benutzerauswahl auswählen können. Zum Beispiel, um Bilder, Musik, Videos, Apps oder sogar beliebige Dateien anzuzeigen.
Pratik Saluja
Ich habe den Fehler "durch Intent.getData () über die App hinaus angezeigt" erhalten.
Ramiz Ansari
Wenn der Fehler "Durch Intent.getData () über die App hinaus angezeigt wird" angezeigt wird, können Sie diesen Link überprüfen, um das Problem zu beheben. Stackoverflow.com/a/45751453/10619147
Wojuola Ayotola
18

Basierend auf der Antwort von Vikas, jedoch mit einer geringfügigen Änderung: Der Uri wird per Parameter empfangen:

private void showPhoto(Uri photoUri){
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    intent.setDataAndType(photoUri, "image/*");
    startActivity(intent);
}
Joaquin Iurchuk
quelle
1
Dies zeigt nur ein einzelnes ausgewähltes Bild und keine anderen Bilder im selben Ordner (so dass der Benutzer nach links / rechts wischen kann, um andere Bilder anzuzeigen). Irgendeine Idee, wie man das erreicht?
Atul
@Atul in diesem Fall ist der Anwendungsfall völlig anders. OP möchte ein X-Bild mit seiner URI anzeigen. Es scheint, dass Sie a) die Galerie an einer bestimmten Position öffnen möchten oder b) in der Galerie eine Teilmenge von Fotos öffnen möchten, für die Sie die URIs haben. Recherchieren Sie im Internet oder stellen Sie eine neue Frage, da Ihr Anwendungsfall völlig anders ist.
Joaquin Iurchuk
Danke für deine schnelle Antwort. Ich muss dasselbe erreichen, was OP verlangt hat. Ihre (und Vikas ') Antwort erreicht dies sehr gut. Das einzige ist, dass es nach dem Anzeigen des Bildes nicht mehr möglich ist, durch andere Bilder im selben Ordner zu scrollen (wenn der Benutzer nach links oder rechts wischt). Ich habe viele Apps (z. B. WhatsApp) gesehen, die Bilder im Galerie-Viewer anzeigen (genau wie Sie), aber sie ermöglichen es dem Benutzer auch, durch Bilder von links nach rechts in demselben Ordner zu scrollen.
Atul
@Atul OP möchte ein Bild mit Galerie unter Angabe der URI öffnen . Die WhatsApp-Implementierung ist völlig anders. Ich weiß nicht, ob Gallery das Empfangen einer Absicht mit vielen URIs unterstützt. Wie auch immer, sehen Sie sich das an, es könnte Ihnen helfen.
Joaquin Iurchuk
Ich hatte den von Ihnen angegebenen Link bereits gesehen. Trotzdem danke. Aber ich habe festgestellt, dass jemand bereits eine Frage zu dem gestellt hat, was ich möchte. Seine Antwort ist jedoch zu kurz, um sie zu verstehen.
Atul
11

Diese Sache könnte helfen, wenn Sie mit Android N und darunter arbeiten

 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
baswaraj
quelle
FLAG_GRANT_READ_URI_PERMISSION half beim Anzeigen von Bildern mit Intent.ACTION_VIEW
Pavan
Hat für mich gearbeitet. Denken Sie daran, wenn Sie "intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK)" verwenden. dann müssen Sie "intent.setFlags (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION)" hinzufügen; danach .. Danke für die tolle Lösung.
Snehal Agrawal
5

Eine viel sauberere und sicherere Antwort auf dieses Problem (Sie sollten Strings wirklich nicht hart codieren):

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

Sie müssen lediglich die Bild-ID an das Ende des Pfads für EXTERNAL_CONTENT_URI anhängen . Starten Sie dann eine Absicht mit der Aktion Anzeigen und dem Uri.

Die Bild-ID stammt aus der Abfrage des Inhaltsauflösers.

Christopher Perry
quelle
Ermöglicht es dem Benutzer, durch andere Bilder im selben Ordner zu wischen und zu scrollen?
Atul
4

Alle obigen Antworten öffnen das Bild nicht. Wenn ich das zweite Mal versuche, es zu öffnen, zeigt die Galerie kein Bild.

Ich habe eine Lösung aus einer Mischung verschiedener SO-Antworten erhalten.

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

Dieser hat nur für mich funktioniert ..

Ranjith Kumar
quelle
4

Das Problem beim Anzeigen einer Datei mit besteht darin Intent.ACTION_VIEW, dass Sie Uriden Pfad beim Parsen übergeben. Funktioniert nicht in allen Fällen. Um dieses Problem zu beheben, müssen Sie Folgendes verwenden:

Uri.fromFile(new File(filePath));

Anstatt:

Uri.parse(filePath);

Bearbeiten

Hier ist mein vollständiger 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);

Die Info

MediaFileist meine Domänenklasse zum Umschließen von Dateien aus der Datenbank in Objekte. MediaFile.getExtension()Gibt ein Stringwith Mimetypefür die Dateierweiterung zurück. Beispiel:"image/png"


Zusätzlicher Code: Wird zum Anzeigen einer Datei (Erweiterung) benötigt.

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

Lassen Sie mich wissen, wenn Sie mehr Code benötigen.

IgniteCoders
quelle
3

Ich benutze das, es funktioniert für mich

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

Meine Lösung mit 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);
}
Creativecoder
quelle
0

Fast KEINE Möglichkeit, eine Foto- oder Galerieanwendung (möglicherweise vorhanden) zu verwenden, aber Sie können den Content-Viewer ausprobieren.

Bitte Kasse eine andere Antwort auf ähnliche Frage hier

TeeTracker
quelle
0

Meine Lösung

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);
Ritterwürfel
quelle