mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 09:20:19 +01:00
Use AttachmentSaver to save media overview files to device storage.
This commit is contained in:
committed by
Cody Henthorne
parent
18328079c8
commit
0ef627b864
@@ -1,56 +1,37 @@
|
||||
package org.thoughtcrime.securesms.mediaoverview;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentSaver;
|
||||
import org.thoughtcrime.securesms.database.MediaTable;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceDeleteSyncJob;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.util.AttachmentUtil;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.StorageUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import io.reactivex.rxjava3.core.Completable;
|
||||
|
||||
final class MediaActions {
|
||||
|
||||
private MediaActions() {
|
||||
}
|
||||
|
||||
static void handleSaveMedia(@NonNull Fragment fragment,
|
||||
@NonNull Collection<MediaTable.MediaRecord> mediaRecords,
|
||||
@Nullable Runnable postExecute)
|
||||
static Completable handleSaveMedia(@NonNull Fragment fragment,
|
||||
@NonNull Collection<MediaTable.MediaRecord> mediaRecords)
|
||||
{
|
||||
Context context = fragment.requireContext();
|
||||
|
||||
if (StorageUtil.canWriteToMediaStore()) {
|
||||
performSaveToDisk(context, mediaRecords, postExecute);
|
||||
return;
|
||||
}
|
||||
|
||||
SaveAttachmentTask.showWarningDialogIfNecessary(context, mediaRecords.size(), () -> Permissions.with(fragment)
|
||||
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
.ifNecessary()
|
||||
.withPermanentDenialDialog(fragment.getString(R.string.AttachmentSaver__signal_needs_the_storage_permission_in_order_to_write_to_external_storage_but_it_has_been_permanently_denied))
|
||||
.onAnyDenied(() -> Toast.makeText(context, R.string.AttachmentSaver__unable_to_write_to_external_storage_without_permission, Toast.LENGTH_LONG).show())
|
||||
.onAllGranted(() -> performSaveToDisk(context, mediaRecords, postExecute))
|
||||
.execute());
|
||||
return new AttachmentSaver(fragment).saveAttachmentsRx(mediaRecords);
|
||||
}
|
||||
|
||||
static void handleDeleteMedia(@NonNull Context context,
|
||||
@@ -96,37 +77,4 @@ final class MediaActions {
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private static void performSaveToDisk(@NonNull Context context, @NonNull Collection<MediaTable.MediaRecord> mediaRecords, @Nullable Runnable postExecute) {
|
||||
new ProgressDialogAsyncTask<Void, Void, List<SaveAttachmentTask.Attachment>>(context,
|
||||
R.string.MediaOverviewActivity_collecting_attachments,
|
||||
R.string.please_wait)
|
||||
{
|
||||
@Override
|
||||
protected List<SaveAttachmentTask.Attachment> doInBackground(Void... params) {
|
||||
List<SaveAttachmentTask.Attachment> attachments = new LinkedList<>();
|
||||
|
||||
for (MediaTable.MediaRecord mediaRecord : mediaRecords) {
|
||||
if (mediaRecord.getAttachment().getUri() != null) {
|
||||
attachments.add(new SaveAttachmentTask.Attachment(mediaRecord.getAttachment().getUri(),
|
||||
mediaRecord.getContentType(),
|
||||
mediaRecord.getDate(),
|
||||
mediaRecord.getAttachment().fileName));
|
||||
}
|
||||
}
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<SaveAttachmentTask.Attachment> attachments) {
|
||||
super.onPostExecute(attachments);
|
||||
SaveAttachmentTask saveTask = new SaveAttachmentTask(context, attachments.size());
|
||||
saveTask.executeOnExecutor(THREAD_POOL_EXECUTOR,
|
||||
attachments.toArray(new SaveAttachmentTask.Attachment[0]));
|
||||
|
||||
if (postExecute != null) postExecute.run();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,16 @@ import org.thoughtcrime.securesms.database.loaders.MediaLoader;
|
||||
import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory;
|
||||
import org.thoughtcrime.securesms.mediapreview.MediaPreviewV2Activity;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.util.BottomOffsetDecoration;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
|
||||
public final class MediaOverviewPageFragment extends Fragment
|
||||
implements MediaGalleryAllAdapter.ItemClickListener,
|
||||
MediaGalleryAllAdapter.AudioItemListener,
|
||||
@@ -359,9 +361,12 @@ public final class MediaOverviewPageFragment extends Fragment
|
||||
|
||||
bottomActionBar.setItems(Arrays.asList(
|
||||
new ActionItem(R.drawable.symbol_save_android_24, getResources().getQuantityString(R.plurals.MediaOverviewActivity_save_plural, selectionCount), () -> {
|
||||
MediaActions.handleSaveMedia(MediaOverviewPageFragment.this,
|
||||
getListAdapter().getSelectedMedia(),
|
||||
this::exitMultiSelect);
|
||||
lifecycleDisposable.add(
|
||||
MediaActions
|
||||
.handleSaveMedia(MediaOverviewPageFragment.this, getListAdapter().getSelectedMedia())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::exitMultiSelect)
|
||||
);
|
||||
}),
|
||||
new ActionItem(R.drawable.symbol_check_circle_24, getString(R.string.MediaOverviewActivity_select_all), this::handleSelectAllMedia),
|
||||
new ActionItem(R.drawable.symbol_trash_24, getResources().getQuantityString(R.plurals.MediaOverviewActivity_delete_plural, selectionCount), this::handleDeleteSelectedMedia)
|
||||
@@ -400,6 +405,12 @@ public final class MediaOverviewPageFragment extends Fragment
|
||||
voiceNoteMediaController.getVoiceNotePlaybackState().removeObserver(observer);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
private class ActionModeCallback implements ActionMode.Callback {
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user