2011-01-20 33 views
11

Ứng dụng của tôi cho phép người dùng lưu hình ảnh vào thẻ SD của họ. Nhưng tôi không chắc chắn làm thế nào để làm cho nó xuất hiện trong bộ sưu tập cho đến khi bạn unmount và remount thẻ SD. Tôi đã googled cho một vài ngày với vấn đề này nhưng tôi không chắc chắn làm thế nào để làm cho nó xuất hiện tự động. Tôi đã tìm thấy liên kết this nhưng tôi không chắc chắn cách sử dụng lớp học. Đây là những gì tôi sử dụng để lưu các tập tin. Ở dưới cùng của khối try try là nơi tôi muốn quét thẻ sd cho phương tiện mới.Quét thẻ SD Android cho các tệp mới

FileOutputStream outStream = null; 
    File file = new File(dirPath, fileName); 
    try { 
     outStream = new FileOutputStream(file); 
     bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream); 
     outStream.flush(); 
     outStream.close(); 
    } catch { 
     ... 
    } 

Nếu bất cứ ai có thể chỉ cho tôi đúng hướng, tôi sẽ đánh giá cao.

+0

Ứng dụng "sdrescan" thực hiện những gì bạn muốn. Nó miễn phí; có thể bạn có thể yêu cầu tác giả cho một đoạn mã. Hoặc chỉ cần khởi chạy ứng dụng từ ứng dụng của bạn. –

+0

Có cách nào để quét lại mà không dừng trình phát nhạc không? Nó nói Xin lỗi, trình phát đa phương tiện không hỗ trợ tệp này, cho đến khi tôi nhấn lại một bản nhạc, chuyển tiếp bản nhạc, sau đó phát lại. – NoBugs

Trả lời

5

Kể từ khi câu trả lời cuối cùng tôi đã đăng rõ ràng không phải là một phương pháp thích hợp, Tôi tìm thấy một phương pháp khác here. Về cơ bản bạn tạo một lớp bao bọc, khởi tạo nó, và sau đó gọi phương thức scan(). Bài đăng rất hữu ích. Hãy cho tôi biết nếu điều này là không thích hợp hoặc.

+0

Lưu ý: Điều này sử dụng scanFile() đã có sẵn từ cấp API bắt đầu 1. Không phải là tệp scanFile() mới hơn đã có sẵn sau khi API cấp 8. – Brian

0

Bạn có thể sử dụng MediaStore.Images.Media.insertImage để chèn một mục vào thư viện.

+0

Cảm ơn sự giúp đỡ. Nhưng tôi không thể có được "insertImage" để làm việc. Tôi tìm thấy câu trả lời trên một diễn đàn khác mặc dù. – Brian

4

Sử dụng MediaScannerConnection:

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

Nó có thể là một chút của một cơn đau do nhiều cấp độ của các cuộc gọi không đồng bộ, như vậy là các API 8 (Froyo) có một hàm helper:

http://developer.android.com/reference/android/media/MediaScannerConnection.html#scanFile(android.content.Context, java.lang.String [], java.lang.String [], android.media.MediaScannerConnection.OnScanCompletedListener)

+0

Tôi đã đọc qua tài liệu tham khảo nhiều lần và tôi không thể tìm ra cách để mediaScannerConnection hoạt động. Theo như chức năng trợ giúp, tôi không nghĩ đó sẽ là cách tiếp cận tốt nhất. API 8 không quá cũ và sẽ không được hỗ trợ trên nhiều thiết bị (bao gồm cả điện thoại thử nghiệm của tôi). Tôi chơi xung quanh trong một vài ngày với các liên kết trong bài viết ban đầu của tôi và tôi không thể có được ví dụ đó để làm việc. Nếu bạn có thể đăng một số đoạn trích hoặc chỉ cho tôi một ví dụ khác, tôi sẽ đánh giá cao nó. Cho đến lúc đó tôi sẽ phải rời khỏi phương thức "sendBroadcast" vì đây là cách duy nhất hoạt động ngay bây giờ. – Brian

+0

Có bản giới thiệu API cho hàm mới tại đây: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.html Bạn có thể tìm thấy việc triển khai mã để tạo mô hình cho việc triển khai của riêng bạn tại đây: http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=media/java/android/media/MediaScannerConnection.java – hackbod

+1

Để lặp lại: KHÔNG gửi ACTION_MEDIA_MOUNTED. Điều đó sẽ làm TẤT CẢ các loại nội dung, bao gồm quét toàn bộ thẻ SD. Trong thực tế, tôi cần phải chắc chắn rằng trong các phiên bản tương lai của các ứng dụng nền tảng không thể gửi nó, bởi vì nó có khả năng gây ra các phần của nền tảng để hành vi sai trái nếu họ nhận được nó vào thời điểm sai. Vì vậy, mong đợi trong tương lai nếu bạn đang làm điều này cho ứng dụng của bạn để phá vỡ. – hackbod

2

Bạn cũng có thể gọi cho trình quét đa phương tiện một cách rõ ràng bằng cách gửi chương trình phát sóng.

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

Here là một cách khác để buộc quét:

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,"uri to file")); 

Và sau đó hệ thống sẽ cháy phát sóng ACTION_MEDIA_SCANNER_FINISHED vì vậy bạn có thể phản ứng trên nó với BroadcastReceiver

Để có thể nhận được phát sóng ACTION_MEDIA_SCANNER_FINISHED , bộ lọc ý định nên chứa lược đồ dữ liệu:

IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_FINISHED); 
intentFilter.addDataScheme("file"); 
context.registerReceiver(mMediaScannerFinishReceiver, intentFilter); 

từ doc:

public static String thức ACTION_MEDIA_SCANNER_SCAN_FILE

gia tăng ở mức API 1 Broadcast Hành động: Yêu cầu máy quét phương tiện truyền thông để quét một tập tin và thêm nó vào cơ sở dữ liệu truyền thông. Đường dẫn đến tệp là được chứa trong trường Intent.mData.

public static String thức ACTION_MEDIA_SCANNER_FINISHED

gia tăng ở mức API 1 Broadcast Hành động: Các máy quét phương tiện truyền thông đã hoàn tất quét một thư mục. Đường dẫn đến thư mục được quét có chứa trong trường Intent.mData.

9

Tôi đã thử nhiều phương pháp khác nhau để kích hoạt MediaScanner và đây là những kết quả của tôi.

SendBroadcast

Giải pháp đơn giản nhất và ngây thơ. Nó bao gồm trong việc thực hiện các hướng dẫn sau đây từ mã của bạn:

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

Tuy nhiên, này không còn hoạt động trong các thiết bị KitKat, do thiếu các điều khoản cần thiết.


MediaScannerWrapper

Như posted here (mỗi @ Brian của câu trả lời), nó bao gồm trong gói một trường hợp MediaScannerConnection để kích hoạt các phương pháp scan() trên một thư mục cụ thể. Phương pháp này đã được chứng minh là làm việc tốt cho 4.3 và dưới đây, nhưng vẫn không có may mắn với KitKat (4.4+).


FileWalker

Một trong nhiều ứng dụng Play Store mà cố gắng để vượt qua sự thiếu cam kết của MediaStore để cập nhật cơ sở dữ liệu của nó là ReScan SD. Nó sẽ gửi rất nhiều chương trình phát sóng khác nhau:

sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable/SD"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable/MicroSD"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///mnt/Removable/MicroSD"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///mnt"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///storage"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable"))); 

và cố gắng hỗ trợ KitKat bằng cách thủ công kích hoạt các phương pháp scan() qua mỗi tập tin của thư mục gốc. Thật không may, đây là cả hai rất nhiều CPU và tốn thời gian, vì vậy nó không phải là rất khuyến khích.


"Cách vỏ"

Điều duy nhất mà dường như làm việc với KitKat trong một số trường hợp được gửi broadcast qua adb shell. Vì vậy, đoạn này cho phép bạn làm việc đó cách lập trình:

Runtime.getRuntime().exec("am broadcast -a android.intent.action.MEDIA_MOUNTED -d file://" + Environment.getExternalStorageDirectory()); 

Nó là nhiều hơn một cách hack-ish để làm việc đó, nhưng tại thời điểm này là tốt nhất tôi có thể nghĩ ra.


Tóm lại

Mỗi phòng trong số các giải pháp trên thực sự làm việc cho tất cả mọi thứ đó không phải là KitKat. Đó là bởi vì, nhờ vào số Justin, một lỗi đã được tìm thấy và phát hành cho số official Tracker. Điều này có nghĩa là, cho đến khi lỗi được khắc phục, chúng tôi sẽ không hỗ trợ KitKat thực sự.

Loại nào để sử dụng? Trong số đó, tôi sẽ sử dụng giải pháp MediaScannerWrapper, cùng với phương pháp shell-ish (giải pháp cuối cùng).

+0

Phương thức trình bao trên KITKAT Bạn đã đề cập nó hoạt động trong một số trường hợp. Tôi muốn biết trường hợp sử dụng phương pháp này không thành công? hoặc theo đó việc sử dụng nó hoạt động? – Ahmed

+0

Tôi không thể tìm thấy bất kỳ trường hợp sử dụng cố định nào. Điều duy nhất có vẻ hiệu quả là làm mới MediaScanner sau khi một tệp đã được thêm vào. Mặt khác, nó không hoạt động khi một tập tin được gỡ bỏ. – Sebastiano

+2

Nó hoạt động khi tôi gửi phát sóng từ dòng lệnh bằng cách sử dụng adb shell hoạt động cho các tệp mới cũng như các tệp đã xóa. Nhưng nó không hoạt động theo chương trình trên KitKat hoặc cho các tệp mới hoặc loại bỏ một tệp. Tôi đã thử nghiệm với các tệp nhạc âm thanh và sử dụng API trình giả lập 19. – Ahmed

Các vấn đề liên quan