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

Android 實現雲相冊自動上傳:監聽相機廣播與 MediaStore 變化

     編輯:程式設計疑難解答

核心思路

Android 系統拍照完成後會發送廣播,並更新 MediaStore 媒體庫。應用可通過以下兩種方式實現照片自動上傳:

方案一:監聽相機廣播(即時性較好)

<!-- AndroidManifest.xml -->
<receiver android:name=".CameraBroadcastReceiver">
    <intent-filter>
        <action android:name="android.hardware.action.NEW_PICTURE" />
        <action android:name="android.hardware.action.NEW_VIDEO" />
        <!-- Android 7.0+ 需動態註冊 -->
    </intent-filter>
</receiver>
// CameraBroadcastReceiver.java
public class CameraBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.hardware.action.NEW_PICTURE")) {
            // 獲取新照片 URI
            Uri imageUri = intent.getData();
            if (imageUri != null) {
                // 啟動上傳服務
                Intent uploadIntent = new Intent(context, UploadService.class);
                uploadIntent.setData(imageUri);
                context.startService(uploadIntent);
            }
        }
    }
}

方案二:監聽 MediaStore 變化(兼容性更強)

// 使用 ContentObserver 監聽媒體庫變化
public class MediaStoreObserver extends ContentObserver {
    private Context context;
    private Uri lastUri;

    public MediaStoreObserver(Handler handler, Context context) {
        super(handler);
        this.context = context;
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        super.onChange(selfChange, uri);
        // 過濾圖片類型變化
        if (uri != null && uri.toString().contains("images")) {
            // 查詢最新圖片
            queryAndUploadLatestImage();
        }
    }

    private void queryAndUploadLatestImage() {
        String[] projection = {MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA};
        String sortOrder = MediaStore.Images.Media.DATE_ADDED + " DESC";
        try (Cursor cursor = context.getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
                projection, null, null, sortOrder)) {
            if (cursor != null && cursor.moveToFirst()) {
                String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
                // 啟動上傳
                startUpload(path);
            }
        }
    }
}

// 在 Service/Application 中註冊
getContentResolver().registerContentObserver(
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, mediaStoreObserver);

上傳服務實現要點

public class UploadService extends IntentService {
    public UploadService() { super("UploadService"); }

    @Override
    protected void onHandleIntent(Intent intent) {
        Uri imageUri = intent.getData();
        // 1. 獲取文件路徑
        String filePath = getRealPathFromUri(imageUri);
        // 2. 壓縮圖片(可選)
        File compressedFile = compressImage(filePath);
        // 3. 多部分上傳
        uploadToServer(compressedFile);
        // 4. 記錄上傳狀態到本地數據庫
        recordUploadStatus(filePath, success);
    }
}

關鍵權限配置

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Android 10 以下 -->
<!-- Android 10+ 使用 Scoped Storage,無需 WRITE 權限 -->

方案對比與選擇建議

維度廣播監聽MediaStore 監聽
即時性高(拍照瞬間觸發)中(需查詢最新)
Android 版本兼容7.0+ 需動態註冊,部分機型受限全版本支持
獲取文件路徑直接從 Intent 獲取 URI需查詢 Cursor 獲取路徑
推薦場景拍照即上傳、實時性要求高相冊同步、批量備份、兼容性優先

最佳實踐總結

  1. 組合使用:廣播作為即時觸發,MediaStore 作為補償機制(防止廣播丟失)。
  2. 使用 WorkManager:替代 IntentService 實現可靠的後台上傳,支持網絡狀態感知、重試策略。
  3. 斷點續傳:大文件分片上傳,記錄已上傳分片,避免重複傳輸。
  4. 隱私合規:明確告知用戶自動上傳功能,提供開關選項。

雲相冊流程示意

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