首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 4.4+ 強制更新媒體庫掃描檔案

     編輯:程式設計綜合問答

問題背景

Android 4.4 (KitKat) 後,發送 ACTION_MEDIA_MOUNTED 廣播需系統簽名權限,第三方 App 無法直接觸發媒體掃描。MediaScannerConnection.scanFile() 成為標準做法,但部分開發者回報「刪除檔案會更新,新增檔案不更新」。

正確使用 MediaScannerConnection

需實作 MediaScannerConnectionClient 介面,確保連線建立後再呼叫 scanFile。以下為完整封裝類別:

public class MediaScannerWrapper implements MediaScannerConnection.MediaScannerConnectionClient {
    private MediaScannerConnection mConnection;
    private String mPath;
    private String mMimeType;

    public MediaScannerWrapper(Context context, String mimeType) {
        mMimeType = mimeType;
        mConnection = new MediaScannerConnection(context, this);
    }

    public void scan(String path) {
        mPath = path;
        if (mConnection.isConnected()) {
            mConnection.scanFile(mPath, mMimeType);
        } else {
            mConnection.connect(); // 非同步連線,連線成功後會呼叫 onMediaScannerConnected
        }
    }

    @Override
    public void onMediaScannerConnected() {
        mConnection.scanFile(mPath, mMimeType);
    }

    @Override
    public void onScanCompleted(String path, Uri uri) {
        Log.d("MediaScanner", "掃描完成: " + path + " -> " + uri);
        // 可在此通知 UI 更新
    }

    public void disconnect() {
        if (mConnection.isConnected()) mConnection.disconnect();
    }
}

使用範例

// 新增照片後呼叫
File photoFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "IMG_" + System.currentTimeMillis() + ".jpg");
// ... 儲存檔案 ...
MediaScannerWrapper scanner = new MediaScannerWrapper(this, "image/jpeg");
scanner.scan(photoFile.getAbsolutePath());
// 記得在 Activity onDestroy 等適當時機呼叫 scanner.disconnect()

常見錯誤與解決

  • 未等待連線建立就呼叫 scanFile:需在 onMediaScannerConnected 中執行,或檢查 isConnected()。
  • MIME 傳 null 或錯誤:傳 "image/jpeg"、"video/mp4" 或 "*/*" 讓系統自動判斷。
  • 檔案實際不存在:掃描前確認 file.exists()。
  • Android 10+ 分區儲存:需使用 MediaStore API 插入媒體記錄,而非直接掃描檔案路徑。

Android 10 (API 29) 以上新做法

ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/MyApp");
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
try (OutputStream os = getContentResolver().openOutputStream(uri)) {
    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, os);
}
// 此方式無需額外掃描,即時出現在相簿

依據 Android 版本選擇適當 API,確保媒體檔案即時被系統識別。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved