Das auf der SD-Karte gespeicherte Bild wird in der Android-Galerie-App nicht angezeigt


92

Ich speichere ein Bild auf der SD-Karte und es wird erst in der Galerie-Anwendung angezeigt, wenn ich die SD-Karte abziehe und sie zurückschicke.

Hast du eine Idee warum es so ist?

Scheint, als ob die Galerie-Anwendung einen Cache hat, der beim Speichern der Datei nicht aktualisiert wird ...

Eigentlich möchte ich auch das gerade gespeicherte Bild in der Galerie-Anwendung öffnen und habe damit keinen Erfolg.
Dies ist meine Frage zu diesem Problem.


1
Diese Frage wurde Schritt für Schritt in diesem Tutorial beantwortet: stackoverflow.com/questions/30506301/…
Takermania

Antworten:


45

Das System scannt die SD-Karte beim Mounten, um neue Image- (und andere) Dateien zu finden. Wenn Sie programmgesteuert eine Datei hinzufügen, können Sie diese Klasse verwenden:

http://developer.android.com/reference/android/media/MediaScannerConnection.html


4
Randnotiz: Obwohl sich die Frage auf das Hinzufügen von Dateien bezieht, bietet MediaScannerConnection keine Lösung zum Löschen von Dateien - auch nicht, wenn der übergeordnete Ordner einer gelöschten Datei gescannt werden soll.
AlikElzin-Kilaka

85

Eine einfachere Lösung ist die Verwendung der statischen Komfortmethode scanFile () :

File imageFile = ...
MediaScannerConnection.scanFile(this, new String[] { imageFile.getPath() }, new String[] { "image/jpeg" }, null);

Wo thisist Ihre Aktivität (oder welcher Kontext auch immer), der MIME-Typ ist nur erforderlich, wenn Sie nicht standardmäßige Dateierweiterungen verwenden, und der nullist für den optionalen Rückruf (den wir für einen so einfachen Fall nicht benötigen).


2
Spot on, die Broadcast-Methode, die andere (und Google) anbieten, funktioniert sehr selten.
Chris.Jenkins

2
Dies funktionierte für mich in früheren Android-Versionen ~ 4.0, aber jetzt in 4.3+ scheint es nicht zu funktionieren. Die Bilder werden nicht in der Galerie-App angezeigt.
hooby3dfx

Perfekt ! Sie können Kontext erhalten mit: Android.App.Application.Context
Krug

Arbeitete in Marshmallow
Hitesh Sahu

66

Meine Antwort auf die ursprüngliche Frage und auf alle anderen, die dieses Problem haben könnten:

Ich hatte das gleiche Problem: Bilder in meiner App, die auf der SD-Karte gespeichert wurden, wurden nicht sofort in ihrer Galerie angezeigt. Nach einigem Suchen fand ich diese eine Codezeile, die nach meinem Code "Auf SD-Karte speichern" eingefügt wurde und das Problem behoben hat:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

Müssen wir einen Medienscanner verwenden, um diese Sendung nutzen zu können? Ich verwende eine andere Methode, um Bilder in meiner Galerie anzuzeigen. Wenn ich oben sendBroadcast beim Speichern verwende, klicken Sie auf Meine Galerie wird nicht mit dem neuen Bild aktualisiert!
Ändern Sie den

4
Es ist alt, aber dies kann jemandem helfen - ein spezifischerer Pfad: sendBroadcast (new Intent (Intent.ACTION_MEDIA_MOUNTED, Uri.parse ("file: //" + Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES))); Diese Methode (diese Antwort, nicht nur mein Kommentar) funktioniert auf dem Emulator nicht. Test auf echtem Gerät.

Ich glaube, die akzeptierte Antwort bietet den richtigen Weg, dies zu tun. Wenn Sie jedoch versuchen, API <= 7 zu unterstützen, ist dies ein guter Fallback.
Amr Mostafa

Ihre Antwort ist hilfreich für andere Geräte. Es funktioniert nicht auf HTC, wenn ich versuche, meinen Anwendungsordner zu scannen. Das neu hinzugefügte Bild wird nicht angezeigt.
MobileEvangelist

6
Dies scheint unter Android 4.4 oder höher nicht mehr unterstützt zu werden. In diesem Fall wird eine Berechtigungsausnahme ausgelöst.
rsp1984

13

Sie können der Mediengalerie auch absichtlich ein Bild hinzufügen. Sehen Sie sich den Beispielcode an, um zu sehen, wie es gemacht wird:

ContentValues image = new ContentValues();

image.put(Images.Media.TITLE, imageTitle);
image.put(Images.Media.DISPLAY_NAME, imageDisplayName);
image.put(Images.Media.DESCRIPTION, imageDescription);
image.put(Images.Media.DATE_ADDED, dateTaken);
image.put(Images.Media.DATE_TAKEN, dateTaken);
image.put(Images.Media.DATE_MODIFIED, dateTaken);
image.put(Images.Media.MIME_TYPE, "image/png");
image.put(Images.Media.ORIENTATION, 0);

 File parent = imageFile.getParentFile();
 String path = parent.toString().toLowerCase();
 String name = parent.getName().toLowerCase();
 image.put(Images.ImageColumns.BUCKET_ID, path.hashCode());
 image.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, name);
 image.put(Images.Media.SIZE, imageFile.length());

 image.put(Images.Media.DATA, imageFile.getAbsolutePath());

 Uri result = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);

Hallo. Diese Methode fügt das Bild dem MediaStore hinzu. Ich habe es durch Überprüfen der zurückgegebenen bestätigt, Uriaber das Problem ist, dass das eingefügte Bild nicht in der Galerie angezeigt wird . Ich habe sowohl am Anfang als auch am Ende der Galerie nachgesehen. Können Sie bitte eine Methode vorschlagen, damit das eingefügte Bild sofort in der Galerie angezeigt wird?
Shajeel Afzal

12

Galerie aktualisieren einschließlich Android KITKAT

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File f = new File("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
}
else
{
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}

Der Code, der sich in der ersten Bedingung mit der Anweisung "IF" befindet, funktioniert in KitKat (Android 4.4.4, API 19) einwandfrei.
Alex

8

Hier ist der Code für die MediaScannerConnection:

MyMediaConnectorClient client = new MyMediaConnectorClient(newfile);
MediaScannerConnection scanner = new MediaScannerConnection(context, client);
client.setScanner(scanner);
scanner.connect();

newfile ist das Dateiobjekt Ihrer neuen / gespeicherten Datei.


2
Vielen Dank für Ihre Antwort. Eigentlich habe ich dieses Projekt schon vor langer Zeit abgeschlossen ... Ich erinnere mich nicht einmal, welche Lösung ich verwendet habe. Andere Benutzer könnten Ihre Lösung hilfreich finden, wenn Sie auch die Implementierung von MyMediaConnectorClient...
Michael Kessler

Ja - ich habe im Moment echte Kopfschmerzen damit. Bitte poste :)
Steve

Ja, ich bin mir nicht ganz sicher, wie der Ablauf sein soll. Korrigieren Sie mich, wo ich falsch liege. Ich kann MediaScannerConnection verwenden, um die SDCAARD-Informationen zu aktualisieren, damit ich mit der Kamera fotografiere und die neue Datei an die MSC weitergebe. Jetzt kann ich auf die Datei zugreifen mit mit einem Verbindungsscanner-Client?
Steve

Der Ablauf ist: Sie machen ein Bild, speichern es auf Ihrer SD-Karte und führen dann eine Aktualisierung des Scanners durch, sodass das Dateisystem aktualisiert wird, um Ihr gespeichertes Bild in der Gerätegalerie anzuzeigen. Wenn Sie dies mit dem Scanner nicht tun, wird Ihr Bild nach dem nächsten Neustart des Geräts in der Galerie angezeigt.
3dmg

7

Im Emulator befindet sich eine App mit der Aufschrift "Dev Tools".

Klicken Sie darauf und wählen Sie "Medienscannen". Alle Bilder werden gescannt



6

Lassen Sie Ihre Aktivität 'MediaScannerConnectionClient' implementieren und fügen Sie dies Ihrer Aktivität hinzu:

private void startScan() 
{ 
    if(conn!=null) conn.disconnect();  
    conn = new MediaScannerConnection(YourActivity.this,YourActivity.this); 
    conn.connect(); 
} 

@Override 
public void onMediaScannerConnected() { 
    try{
        conn.scanFile(yourImagePath, "image/*");
       } catch (java.lang.IllegalStateException e){
       }
}

@Override 
public void onScanCompleted(String path, Uri uri) { 
    conn.disconnect(); 
} 

Hallo! Was ist, wenn wir Uridas Bild kennen, zum Beispiel:content://media/external/images/media/1231778
Shajeel Afzal

6

diese Arbeit mit mir

File file = ..... // Save file

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));

4
 File folderGIF = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/newgif2");    //path where gif will be stored
success = folderGIF.mkdir();    //make directory
 String finalPath = folderGIF + "/test1.gif";  //path of file
.....
/* changes in gallery app if any changes in done*/
 MediaScannerConnection.scanFile(this,
                    new String[]{finalPath}, null,
                    new MediaScannerConnection.OnScanCompletedListener() {
                        public void onScanCompleted(String path, Uri uri) {
                            Log.i("ExternalStorage", "Scanned " + path + ":");
                            Log.i("ExternalStorage", "-> uri=" + uri);
                        }
                    });

Ich möchte eine animierte GIF-Datei speichern, die sich im externen Speicher befindet, und ich habe den Pfad dh / storage / emulated / 0 / Android / data / <Paketname> / files / <Foldername> /xyz.gif. Jetzt möchte ich diese Datei speichern / in die Bildergalerie kopieren und dort anzeigen. Wie macht man das.
Zia Ur Rahman

3

Hier teile ich Code, mit dem Bilder in Form einer Bitmap geladen und in der SD-Kartengalerie im Ordner mit den App-Namen gespeichert werden können. Sie sollten diese Schritte befolgen

  1. Laden Sie zuerst die Bild-Bitmap herunter



     private Bitmap loadBitmap(String url) {
        try {
            InputStream in = new java.net.URL(url).openStream();
            return BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
       }


  1. Bitte geben Sie auch die folgende Berechtigung in Ihrer AndroidManifest.xml-Datei an.


    uses-permission android:name="android.permission.INTERNET" 
    uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"


  1. Hier ist der gesamte Code, der in Activty geschrieben ist und in dem wir diese Aufgabe ausführen möchten.



     void saveMyImage(String appName, String imageUrl, String imageName) {

            Bitmap bmImg = loadBitmap(imageUrl);
            File filename;
            try {
                String path1 = android.os.Environment.getExternalStorageDirectory()
                        .toString();
                File file = new File(path1 + "/" + appName);
                if (!file.exists())
                    file.mkdirs();
                filename = new File(file.getAbsolutePath() + "/" + imageName
                        + ".jpg");
                FileOutputStream out = new FileOutputStream(filename);
                bmImg.compress(Bitmap.CompressFormat.JPEG, 90, out);
                out.flush();
                out.close();
                ContentValues image = new ContentValues();
                image.put(Images.Media.TITLE, appName);
                image.put(Images.Media.DISPLAY_NAME, imageName);
                image.put(Images.Media.DESCRIPTION, "App Image");
                image.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
                image.put(Images.Media.MIME_TYPE, "image/jpg");
                image.put(Images.Media.ORIENTATION, 0);
                File parent = filename.getParentFile();
                image.put(Images.ImageColumns.BUCKET_ID, parent.toString()
                        .toLowerCase().hashCode());
                image.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, parent.getName()
                        .toLowerCase());
                image.put(Images.Media.SIZE, filename.length());
                image.put(Images.Media.DATA, filename.getAbsolutePath());
                Uri result = getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);
                Toast.makeText(getApplicationContext(),
                        "File is Saved in  " + filename, Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }


  1. Hoffe, dass es Ihr ganzes Problem lösen kann.

3
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

Scheint bei KITKAT nicht zu funktionieren. Es löst eine Ausnahme für die Verweigerung von Berechtigungen aus und stürzt die App ab. Deshalb habe ich Folgendes getan:

String path = mediaStorageDir.getPath() + File.separator
                    + "IMG_Some_name.jpg";
CameraActivity.this.sendBroadcast(new Intent(
                             Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri
                            .parse("file://" + path)));

Ich hoffe es hilft.


2

Verwenden Sie dies nach dem Speichern des Bildes

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

3
Dies funktioniert, ist aber nicht die beste Lösung. Sie täuschen das System vor, die SD-Karte würde (neu) montiert, und erzwingen möglicherweise ein erneutes Scannen der gesamten SD-Karte. MediaScanner.scanFile (..) ist die beste Lösung, wenn Sie jetzt die Datei hinzufügen möchten.
Pocmo

1
Diese Suche nach allen Bildern. Und es beinhaltet eine Menge unnötiger Datenverarbeitung, die irrelevant sein kann, wenn nur ein einzelnes Bild in der Galerie angezeigt wird.
Rahul Rastogi

2

Mein Code für MyMediaConnectorClient:

public class MyMediaConnectorClient implements MediaScannerConnectionClient {

    String _fisier;
    MediaScannerConnection MEDIA_SCANNER_CONNECTION;

    public MyMediaConnectorClient(String nume) {
        _fisier = nume;
    }

    public void setScanner(MediaScannerConnection msc){
        MEDIA_SCANNER_CONNECTION = msc;
    }

    @Override
    public void onMediaScannerConnected() {
        MEDIA_SCANNER_CONNECTION.scanFile(_fisier, null);
    }

    @Override
    public void onScanCompleted(String path, Uri uri) {
        if(path.equals(_fisier))
            MEDIA_SCANNER_CONNECTION.disconnect();
    }
}

0

Sie müssen der Galerie-App Berechtigungen erteilen. Drücken Sie einfach lange auf das Galerie-App-Symbol auf dem Startbildschirm und tippen Sie auf 'APP INFO', das oben auf dem Bildschirm angezeigt wird. Dadurch werden die Einstellungen der Galerie-App angezeigt. Gehen Sie nun zur Registerkarte Berechtigungen und aktivieren Sie den Speicher und die Kameraberechtigungen, indem Sie sie umschalten. Gehen Sie jetzt zu Ihrer nativen Galerie-App und Sie erhalten die gespeicherten Bilder.


0

Dies löst auch Ihr Problem, wenn Ihr Bild in der Galerie nicht angezeigt wird, sondern möglicherweise eine Bitmap vom Typ 404 in der Mitte angezeigt wird. Bitte fügen Sie die Tags in meinem Code zu Ihrem Bild hinzu, da einige Metadaten erforderlich sind, um das Bild in der Galerie anzuzeigen.

      String resultPath = getExternalFilesDir(Environment.DIRECTORY_PICTURES)+ 
      getString(R.string.directory) + System.currentTimeMillis() + ".jpg";

       new File(resultPath).getParentFile().mkdir();

        try {
            OutputStream fileOutputStream = new FileOutputStream(resultPath);
            savedBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e2) {
            e2.printStackTrace();
        }
        savedBitmap.recycle();

        File file = new File(resultPath);
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, "Photo");
        values.put(MediaStore.Images.Media.DESCRIPTION, "Edited");
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis ());
        values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
        values.put(MediaStore.Images.ImageColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
        values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
        values.put("_data", resultPath);

        ContentResolver cr = getContentResolver();
        cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);




        return  resultPath;

0

Versuchen Sie dieses, es wird über ein neu erstelltes Bild gesendet, so dass Ihr Bild sichtbar ist. in einer Galerie. Fotodatei durch tatsächlichen Dateipfad des neu erstellten Bildes ersetzen

private void galleryAddPicBroadCast() {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri contentUri = Uri.fromFile(photoFile);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.