Messaging: Migrate attachments to MediaStore

* Saving them doesn't work otherwise
* We don't have to care about MediaScanner and DownloadManager
  anymore that way, either

Fixes: https://gitlab.com/LineageOS/issues/android/-/issues/8573
Change-Id: I7a3b1dc6916feff4849bdfa2b8937460c32bc5a2
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
(cherry picked from commit 93bd39838d4a395dd710796b0e71ada1ec1f5ff2)
This commit is contained in:
Michael W
2025-03-30 18:11:09 +02:00
committed by Luca Stefani
parent 906ee2fb94
commit 3c107a2161
2 changed files with 22 additions and 40 deletions

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2015 The Android Open Source Project * Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project * Copyright (C) 2024-2025 The LineageOS Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,10 +18,11 @@
package com.android.messaging.ui.conversation; package com.android.messaging.ui.conversation;
import android.app.Activity; import android.app.Activity;
import android.app.DownloadManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
@@ -36,6 +37,7 @@ import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Parcelable; import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.v7.mms.pdu.ContentType; import android.support.v7.mms.pdu.ContentType;
import android.telephony.PhoneNumberUtils; import android.telephony.PhoneNumberUtils;
import android.text.TextUtils; import android.text.TextUtils;
@@ -1295,16 +1297,22 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
} }
protected void onExecute() { protected void onExecute() {
final File appDir = new File(Environment.getExternalStoragePublicDirectory( final String appDir = Environment.DIRECTORY_PICTURES
Environment.DIRECTORY_PICTURES), + File.separator
mContext.getResources().getString(R.string.app_name)); + mContext.getResources().getString(R.string.app_name);
final File downloadDir = Environment.getExternalStoragePublicDirectory( final String downloadDir = Environment.DIRECTORY_DOWNLOADS;
Environment.DIRECTORY_DOWNLOADS); final ContentResolver resolver = mContext.getContentResolver();
for (final AttachmentToSave attachment : mAttachmentsToSave) { for (final AttachmentToSave attachment : mAttachmentsToSave) {
final boolean isImageOrVideo = ContentType.isImageType(attachment.contentType) final boolean isImageOrVideo = ContentType.isImageType(attachment.contentType)
|| ContentType.isVideoType(attachment.contentType); || ContentType.isVideoType(attachment.contentType);
attachment.persistedUri = UriUtil.persistContent(attachment.uri, ContentValues values = new ContentValues();
isImageOrVideo ? appDir : downloadDir, attachment.contentType); values.put(MediaStore.MediaColumns.MIME_TYPE, attachment.contentType);
values.put(MediaStore.MediaColumns.RELATIVE_PATH, isImageOrVideo ?
appDir : downloadDir);
attachment.persistedUri = resolver.insert(isImageOrVideo
? MediaStore.Images.Media.EXTERNAL_CONTENT_URI
: MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
UriUtil.persistContent(mContext, attachment.uri, attachment.persistedUri);
} }
} }
@@ -1319,35 +1327,12 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
continue; continue;
} }
// Inform MediaScanner about the new file
final Intent scanFileIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
scanFileIntent.setData(attachment.persistedUri);
mContext.sendBroadcast(scanFileIntent);
if (ContentType.isImageType(attachment.contentType)) { if (ContentType.isImageType(attachment.contentType)) {
imageCount++; imageCount++;
} else if (ContentType.isVideoType(attachment.contentType)) { } else if (ContentType.isVideoType(attachment.contentType)) {
videoCount++; videoCount++;
} else { } else {
otherCount++; otherCount++;
// Inform DownloadManager of the file so it will show in the "downloads" app
final DownloadManager downloadManager =
(DownloadManager) mContext.getSystemService(
Context.DOWNLOAD_SERVICE);
final String filePath = attachment.persistedUri.getPath();
final File file = new File(filePath);
if (file.exists()) {
downloadManager.addCompletedDownload(
file.getName() /* title */,
mContext.getString(
R.string.attachment_file_description) /* description */,
true /* isMediaScannerScannable */,
attachment.contentType,
file.getAbsolutePath(),
file.length(),
false /* showNotification */);
}
} }
} }

View File

@@ -258,14 +258,12 @@ public class UriUtil {
/** /**
* Persist a piece of content from the given sourceUri, byte by byte to the * Persist a piece of content from the given sourceUri, byte by byte to the
* specified output directory. * specified targetUri.
* @return the output Uri if the operation succeeded, or null if failed.
*/ */
@DoesNotRunOnMainThread @DoesNotRunOnMainThread
public static Uri persistContent( public static void persistContent(
final Uri sourceUri, final File outputDir, final String contentType) { final Context context, final Uri sourceUri, final Uri targetUri) {
InputStream inputStream = null; InputStream inputStream = null;
final Context context = Factory.get().getApplicationContext();
try { try {
if (UriUtil.isLocalResourceUri(sourceUri)) { if (UriUtil.isLocalResourceUri(sourceUri)) {
inputStream = context.getContentResolver().openInputStream(sourceUri); inputStream = context.getContentResolver().openInputStream(sourceUri);
@@ -273,13 +271,12 @@ public class UriUtil {
// The content is remote. Download it. // The content is remote. Download it.
inputStream = getInputStreamFromRemoteUri(sourceUri); inputStream = getInputStreamFromRemoteUri(sourceUri);
if (inputStream == null) { if (inputStream == null) {
return null; return;
} }
} }
return persistContent(inputStream, outputDir, contentType); copyContent(context, inputStream, targetUri);
} catch (final Exception ex) { } catch (final Exception ex) {
LogUtil.e(LogUtil.BUGLE_TAG, "Error while retrieving media ", ex); LogUtil.e(LogUtil.BUGLE_TAG, "Error while retrieving media ", ex);
return null;
} finally { } finally {
if (inputStream != null) { if (inputStream != null) {
try { try {