Hình ảnh, được lưu vào sdcard, không xuất hiện trong ứng dụng Thư viện của Android


93

Tôi lưu một hình ảnh vào sdcard và nó không xuất hiện trong ứng dụng Thư viện cho đến khi tôi kéo thẻ sdcard ra và trả lại.

Bạn có bất kỳ ý tưởng tại sao nó như vậy?

Có vẻ như ứng dụng Thư viện có một số bộ nhớ cache chưa được cập nhật khi lưu tệp ...

Trên thực tế, tôi cũng muốn mở hình ảnh vừa lưu trong ứng dụng Thư viện và không thành công với điều đó,
đây là câu hỏi của tôi về vấn đề này.


1
Câu hỏi này đã được trả lời từng bước trong hướng dẫn này: stackoverflow.com/questions/30506301/…
Takermania

Câu trả lời:


45

Hệ thống quét thẻ SD khi nó được gắn để tìm bất kỳ tệp hình ảnh mới (và các tệp khác). Nếu bạn đang thêm tệp theo chương trình, thì bạn có thể sử dụng lớp này:

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


4
Lưu ý bên: Mặc dù câu hỏi đề cập đến việc thêm tệp, nhưng MediaScannerConnection không cung cấp giải pháp xóa tệp - ngay cả khi yêu cầu quét thư mục mẹ của tệp đã xóa.
AlikElzin-kilaka

86

Một giải pháp đơn giản hơn là sử dụng phương thức tiện lợi tĩnh scanFile () :

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

thishoạt động của bạn ở đâu (hoặc bất kỳ ngữ cảnh nào), loại mime chỉ cần thiết nếu bạn đang sử dụng phần mở rộng tệp không chuẩn và loại nulldành cho lệnh gọi lại tùy chọn (chúng tôi không cần trong trường hợp đơn giản như vậy).


2
Spot on, phương pháp truyền phát mà những người khác (và google) cung cấp, rất hiếm khi hoạt động).
Chris.Jenkins

2
Điều này đã hoạt động đối với tôi trong các phiên bản Android trước đó ~ 4.0 nhưng bây giờ trong 4.3+ dường như không hoạt động. Hình ảnh không hiển thị trong ứng dụng thư viện.
hooby3dfx

Hoàn hảo ! Bạn có thể lấy ngữ cảnh với: Android.App.Application.Context
jug

Làm việc trong marshmallow
Hitesh Sahu

66

Câu trả lời của tôi cho câu hỏi ban đầu và cho bất kỳ ai khác có thể gặp vấn đề này:

Tôi cũng gặp vấn đề này, hình ảnh trong ứng dụng của tôi mà mọi người đã lưu vào thẻ SD không hiển thị ngay trong Thư viện của họ. Sau một số tìm kiếm, tôi tìm thấy một dòng mã này được chèn sau mã 'lưu vào thẻ sdcard' của tôi đã khắc phục sự cố:

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

chúng ta có cần sử dụng máy quét phương tiện để có thể sử dụng chương trình phát sóng này không? tôi đang sử dụng phương thức khác để hiển thị hình ảnh trong bộ sưu tập của mình. Khi tôi đang sử dụng sendBroadcast ở trên, bấm vào nút lưu, thư viện của tôi không được cập nhật hình ảnh mới!
thay đổi

4
Nó cũ nhưng điều này có thể giúp ích cho ai đó - một đường dẫn cụ thể hơn: sendBroadcast (new Intent (Intent.ACTION_MEDIA_MOUNTED, Uri.parse ("file: //" + Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES)))); Phương pháp này (câu trả lời này, không chỉ là nhận xét của tôi) không hoạt động trên trình giả lập. Thử nghiệm trên thiết bị thực tế.

Tôi tin rằng câu trả lời được chấp nhận cung cấp cách làm chính xác. Nhưng nếu bạn đang cố gắng hỗ trợ API <= 7 thì đây là một dự phòng tốt.
Amr Mostafa

Câu trả lời của bạn rất hữu ích cho các thiết bị khác. Nó không hoạt động trên HTC, Khi tôi cố gắng quét thư mục Ứng dụng của mình. Nó không hiển thị hình ảnh mới được thêm vào.
MobileEvangelist

6
Điều này dường như không còn được hỗ trợ trên Android 4.4 trở lên. Một ngoại lệ về quyền sẽ được đưa ra trong trường hợp này.
rsp1984

13

Bạn cũng có thể thêm Hình ảnh vào Thư viện phương tiện theo ý định, hãy xem mã ví dụ để xem cách nó được thực hiện:

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

Chào. Phương pháp này thêm hình ảnh vào MediaStore, tôi đã xác nhận nó bằng cách kiểm tra trả lại Urinhưng vấn đề là hình ảnh được chèn không hiển thị trong thư viện. Tôi đã kiểm tra cả ở phần đầu và phần cuối của phòng trưng bày. Bạn có thể vui lòng đề xuất bất kỳ phương pháp nào để hình ảnh được chèn vào sẽ hiển thị ngay trong thư viện không?
Shajeel Afzal

12

Làm mới thư viện bao gồm 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())));
}

Mã nằm trong điều kiện đầu tiên trong câu lệnh "IF" hoạt động tốt đối với tôi trong KitKat (Android 4.4.4, API 19).
Alex

8

Đây là mã cho MediaScannerConnection:

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

newfile là đối tượng Tệp của tệp mới / đã lưu của bạn.


2
Cảm ơn bạn vì câu trả lời. Trên thực tế, tôi đã hoàn thành dự án này từ lâu ... Tôi thậm chí không nhớ giải pháp mà tôi đã sử dụng là gì. Những người dùng khác có thể tìm thấy giải pháp của bạn hữu ích nếu bạn cũng muốn cung cấp việc thực hiện MyMediaConnectorClient...
Michael Kessler

vâng - tôi đang thực sự đau đầu với điều này vào lúc này. Vui lòng đăng lên :)
Steve

Có Tôi không thực sự rõ ràng về quy trình như thế nào -Hãy sửa cho tôi nơi tôi sai Tôi có thể sử dụng MediaScannerConnection để cập nhật thông tin SDCAARD, vì vậy tôi chụp ảnh bằng máy ảnh và chuyển tệp mới vào MSC và bây giờ tôi có thể truy cập tệp với một ứng dụng quét kết nối?
Steve

Quy trình là: bạn chụp ảnh, lưu nó vào thẻ sdcard của bạn và sau đó thực hiện cập nhật máy quét, để hệ thống tệp được cập nhật để xem ảnh đã lưu của bạn trong thư viện thiết bị. Nếu bạn không làm điều đó với máy quét, bạn sẽ thấy ảnh của mình sau khi thiết bị tiếp theo khởi động lại trong thư viện.
3

7

có một ứng dụng trong trình giả lập cho biết - 'Công cụ phát triển'

nhấp vào đó và chọn 'Media Scanning' .. tất cả hình ảnh sẽ được quét


tuyệt vời để biết, cách duy nhất tôi biết trước khi bạn nói rằng là để khởi động lại điện thoại :)
Mishkin

6

Để hoạt động của bạn triển khai 'MediaScannerConnectionClient' và thêm nó vào hoạt động của bạn:

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

Chào! Điều gì sẽ xảy ra nếu chúng ta biết Urivề hình ảnh, ví dụ:content://media/external/images/media/1231778
Shajeel Afzal

6

công việc này với tôi

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

Tôi muốn lưu tệp gif động nằm trong bộ nhớ ngoài và tôi có đường dẫn tức là / storage / emulated / 0 / Android / data / <PackageName> / files / <FolderName> /xyz.gif. Bây giờ tôi muốn Lưu / sao chép tệp này vào Thư viện hình ảnh và hiển thị ở đó. Làm như thế nào.
Zia Ur Rahman

3

Ở đây tôi đang chia sẻ mã có thể tải hình ảnh dưới dạng bitmap từ và lưu hình ảnh đó vào thư viện sdcard trong thư mục tên ứng dụng. Bạn nên làm theo các bước sau

  1. Tải xuống bản đồ bit hình ảnh trước tiên



     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. Vui lòng cung cấp quyền sau trong tệp AndroidManifest.xml của bạn.


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


  1. Đây là toàn bộ mã được viết bằng Activty mà chúng tôi muốn thực hiện tác vụ này.



     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. Hy vọng rằng nó có thể giải quyết toàn bộ vấn đề của bạn.

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

Dường như không hoạt động trên KITKAT. Nó ném ra ngoại lệ từ chối quyền và làm sập ứng dụng. Vì vậy, đối với điều này, tôi đã làm như sau,

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

Hy vọng nó giúp.


2

Sử dụng cái này sau khi lưu hình ảnh

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

3
Điều này hiệu quả nhưng nó không phải là giải pháp tốt nhất. Bạn đang lừa hệ thống nghĩ rằng thẻ SD sẽ được gắn (lắp lại) và có thể buộc phải quét lại toàn bộ thẻ SD. MediaScanner.scanFile (..) là giải pháp tốt nhất khi bạn hiện tập tin bạn muốn thêm.
pocmo

1
Tìm kiếm này cho tất cả các hình ảnh. Và nó liên quan đến rất nhiều xử lý dữ liệu không cần thiết có thể không liên quan khi chúng ta chỉ có một hình ảnh duy nhất được hiển thị trong bộ sưu tập.
Rahul Rastogi

2

Mã của tôi cho 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

Bạn cần cấp quyền cho ứng dụng Thư viện. Chỉ cần nhấn và giữ biểu tượng ứng dụng thư viện trong màn hình chính và nhấn vào 'THÔNG TIN ỨNG DỤNG' bật lên ở đầu màn hình. Làm điều đó sẽ hiển thị cài đặt ứng dụng thư viện. Bây giờ, hãy vào tab Quyền và bật quyền lưu trữ, quyền đối với máy ảnh bằng cách chuyển đổi nó. Bây giờ, hãy truy cập ứng dụng thư viện gốc của bạn và bạn sẽ nhận được những hình ảnh đã lưu của mình.


0

Điều này sẽ giải quyết được vấn đề của bạn nếu hình ảnh của bạn trong thư viện không hiển thị thay vào đó chúng có thể hiển thị bitmap loại 404 ở giữa. vui lòng thêm một thẻ có trong mã của tôi với hình ảnh của bạn vì phải có một số dữ liệu meta để hiển thị hình ảnh trong thư viện.

      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

Hãy thử cái này, nó sẽ phát về một hình ảnh mới được tạo, để hình ảnh của bạn hiển thị. bên trong một phòng trưng bày. photoFile thay thế bằng đường dẫn tệp thực tế của hình ảnh mới tạo

private void galleryAddPicBroadCast() {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri contentUri = Uri.fromFile(photoFile);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
    }
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.