L'immagine, salvata su sdcard, non viene visualizzata nell'app Galleria di Android


92

Salvo un'immagine sulla sdcard e non appare nell'applicazione Gallery finché non la tolgo e la restituisco.

Hai idea del perché sia ​​così?

Sembra che l'applicazione Gallery abbia una cache che non viene aggiornata al salvataggio del file ...

In realtà, voglio anche aprire l'immagine appena salvata nell'applicazione Galleria e non ho successo con
questa mia domanda su questo problema.


1
Questa questione è stata risolta passo dopo passo in questo tutorial: stackoverflow.com/questions/30506301/...
Takermania

Risposte:


45

Il sistema esegue la scansione della scheda SD quando è montata per trovare nuovi file di immagine (e altri). Se stai aggiungendo un file a livello di codice, puoi usare questa classe:

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


4
Nota a margine: sebbene la domanda si riferisca all'aggiunta di file, MediaScannerConnection non fornisce una soluzione per l'eliminazione dei file, nemmeno quando si richiede di eseguire la scansione della cartella principale di un file eliminato.
AlikElzin-kilaka

85

Una soluzione più semplice è utilizzare il metodo di convenienza statico scanFile () :

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

dov'è la thistua attività (o qualunque contesto), il tipo mime è necessario solo se stai usando estensioni di file non standard e lo nullè per la richiamata opzionale (di cui non abbiamo bisogno per un caso così semplice).


2
Spot on, il metodo di trasmissione che altri (e Google) forniscono, funziona molto raramente).
Chris.Jenkins

2
Questo funzionava per me nelle versioni precedenti di Android ~ 4.0 ma ora in 4.3+ non sembra funzionare. Le immagini non vengono visualizzate nell'app della galleria.
hooby3dfx

Perfetto ! Puoi ottenere il contesto con: Android.App.Application.Context
brocca

Ha lavorato in marshmallow
Hitesh Sahu

66

La mia risposta alla domanda originale ea chiunque altro possa avere questo problema:

Avevo lo stesso problema, le immagini nella mia app che le persone salvate sulla scheda SD non venivano visualizzate immediatamente nella loro Galleria. Dopo alcune ricerche ho trovato questa riga di codice inserita dopo il mio codice "save to sdcard" che ha risolto il problema:

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

abbiamo bisogno di utilizzare media scanner per poter utilizzare questa trasmissione? Sto usando un altro metodo per visualizzare le immagini nella mia galleria. Quando sto usando sendBroadcast sopra sul pulsante Salva, fai clic sulla mia galleria non è aggiornata con la nuova immagine!
modifica il

4
È vecchio ma questo potrebbe aiutare qualcuno - un percorso più specifico: sendBroadcast (new Intent (Intent.ACTION_MEDIA_MOUNTED, Uri.parse ("file: //" + Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES)))); Questo metodo (questa risposta, non solo il mio commento) non funziona sull'emulatore. Prova su dispositivo reale.

Credo che la risposta accettata offra il modo corretto per farlo. Ma se stai cercando di supportare API <= 7, questo è un bel ripiego.
Amr Mostafa

La tua risposta è utile per altri dispositivi. Non funziona su HTC, quando provo a eseguire la scansione della cartella dell'applicazione. Non mostra l'immagine appena aggiunta.
MobileEvangelist

6
Questo sembra non essere più supportato su Android 4.4 o versioni successive. In questo caso verrà generata un'eccezione di autorizzazione.
rsp1984

13

Puoi anche aggiungere un'immagine alla Galleria multimediale per intento, dai un'occhiata al codice di esempio per vedere come è fatto:

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

Ciao. Questo metodo aggiunge l'immagine al MediaStore, l'ho confermato controllando il reso Urima il problema è che l'immagine inserita non viene mostrata nella galleria. Ho controllato sia all'inizio che alla fine della galleria. Potete per favore suggerire un metodo in modo che l'immagine inserita venga visualizzata immediatamente nella galleria?
Shajeel Afzal

12

Aggiornamento della galleria incluso 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())));
}

Il codice che si trova nella prima condizione con l'istruzione "IF" funziona bene per me in KitKat (Android 4.4.4, API 19).
Alex

8

Ecco il codice per MediaScannerConnection:

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

newfile è l'oggetto File del file nuovo / salvato.


2
La ringrazio per la risposta. In realtà ho già finito questo progetto molto tempo fa ... non ricordo nemmeno quale fosse la soluzione che ho usato. Altri utenti potrebbero trovare utile la tua soluzione se fornissi anche l'implementazione di MyMediaConnectorClient...
Michael Kessler

sì, al momento sto avendo dei veri grattacapi. Per favore posta :)
Steve

Sì, non sono molto chiaro su come dovrebbe essere il flusso -Correggimi dove sbaglio Posso usare MediaScannerConnection per aggiornare le informazioni SDCAARD quindi scatto la foto con la fotocamera e passo il nuovo file nell'MSC e ora posso accedere al file con un client di scanner di connessione?
Steve il

Il flusso è: scatti una foto, la salvi sulla tua sdcard e poi fai l'aggiornamento dello scanner, in modo che il filesystem venga aggiornato per vedere la tua foto salvata nella galleria del dispositivo. Se non lo fai con lo scanner, vedrai la tua immagine dopo il successivo riavvio del dispositivo nella galleria.
3dmg

7

c'è un'app nell'emulatore che dice: "Dev Tools"

cliccaci sopra e seleziona "Media Scanning" .. tutte le immagini verranno scansionate


bello sapere, l'unico modo che conoscevo prima che tu
dicessi

6

Consenti alla tua attività di implementare "MediaScannerConnectionClient" e aggiungilo alla tua attività:

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

Ciao! E se conosciamo l' Uriimmagine dell'immagine, ad esempio:content://media/external/images/media/1231778
Shajeel Afzal

6

questo lavoro con me

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

Voglio salvare il file gif animato che si trova nella memoria esterna e ho il percorso ie / storage / emulated / 0 / Android / data / <PackageName> / files / <FolderName> /xyz.gif. Ora voglio salvare / copiare questo file nella Galleria di immagini e mostrarlo lì. Come fare questo.
Zia Ur Rahman

3

Qui sto condividendo il codice che può caricare l'immagine in forma di bitmap da e salvare quell'immagine nella galleria sdcard nella cartella del nome dell'app. Dovresti seguire questi passaggi

  1. Scarica prima l'immagine bitmap



     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. Fornisci anche la seguente autorizzazione nel tuo file AndroidManifest.xml.


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


  1. Ecco tutto il codice scritto in Activty in cui vogliamo eseguire questa operazione.



     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. Spero che possa risolvere il tuo intero problema.

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

Non sembra funzionare su KITKAT. Genera un'eccezione di negazione dell'autorizzazione e blocca l'app. Quindi, per questo, ho fatto quanto segue,

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

Spero che sia d'aiuto.


2

Usalo dopo aver salvato l'immagine

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

3
Funziona ma non è la soluzione migliore. Stai ingannando il sistema facendogli credere che la scheda SD sarebbe stata (ri) montata e forse forzando la nuova scansione dell'intera scheda SD. MediaScanner.scanFile (..) è la soluzione migliore quando hai ora il file che desideri aggiungere.
pocmo

1
Questa ricerca per tutte le immagini. E comporta un sacco di elaborazione dati non necessaria che può essere irrilevante quando abbiamo solo una singola immagine da mostrare nella galleria.
Rahul Rastogi

2

Il mio codice per 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

Devi concedere le autorizzazioni all'app Galleria. Basta premere a lungo l'icona dell'app della galleria nella schermata principale e toccare "INFO APP" che si apre nella parte superiore dello schermo. In questo modo verranno visualizzate le impostazioni dell'app della galleria. Ora vai nella scheda Autorizzazioni e abilita l'archiviazione, i permessi della fotocamera attivandola. Ora vai alla tua app galleria nativa e otterrai le tue immagini salvate.


0

Questo risolverà anche il tuo problema se la tua immagine nella galleria non viene visualizzata, invece potrebbe mostrare una bitmap di tipo 404 nel midle. per favore aggiungi i tag che sono nel mio codice con la tua immagine perché ci devono essere alcuni metadati per mostrare l'immagine nella galleria.

      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

Prova questo, trasmetterà una nuova immagine creata, quindi la tua immagine sarà visibile. all'interno di una galleria. photoFile viene sostituito con il percorso file effettivo dell'immagine appena creata

private void galleryAddPicBroadCast() {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri contentUri = Uri.fromFile(photoFile);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.