mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-03 14:52:20 +00:00
committed by
Moxie Marlinspike
parent
170a4291de
commit
238471b847
@@ -348,7 +348,9 @@ public class ConversationFragment extends Fragment
|
||||
}
|
||||
|
||||
Log.w(TAG, "No slide with attachable media found, failing nicely.");
|
||||
Toast.makeText(getActivity(), R.string.ConversationFragment_error_while_saving_attachment_to_sd_card, Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(getActivity(),
|
||||
getResources().getQuantityString(R.plurals.ConversationFragment_error_while_saving_attachments_to_sd_card, 1),
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.Cursor;
|
||||
import android.os.Build.VERSION;
|
||||
@@ -29,6 +30,8 @@ import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
@@ -37,11 +40,17 @@ import android.widget.TextView;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.ImageDatabase.ImageRecord;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.util.AbstractCursorLoader;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Activity for displaying media attachments in-app
|
||||
@@ -137,12 +146,62 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity i
|
||||
}
|
||||
}
|
||||
|
||||
private void saveToDisk() {
|
||||
final Context c = this;
|
||||
|
||||
SaveAttachmentTask.showWarningDialog(this, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
new ProgressDialogAsyncTask<Void, Void, List<SaveAttachmentTask.Attachment>>(c,
|
||||
R.string.ConversationFragment_collecting_attahments,
|
||||
R.string.please_wait) {
|
||||
@Override
|
||||
protected List<SaveAttachmentTask.Attachment> doInBackground(Void... params) {
|
||||
Cursor cursor = DatabaseFactory.getImageDatabase(c).getImagesForThread(threadId);
|
||||
List<SaveAttachmentTask.Attachment> attachments = new ArrayList<>(cursor.getCount());
|
||||
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
ImageRecord record = ImageRecord.from(cursor);
|
||||
attachments.add(new SaveAttachmentTask.Attachment(record.getAttachment().getDataUri(),
|
||||
record.getContentType(),
|
||||
record.getDate()));
|
||||
}
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<SaveAttachmentTask.Attachment> attachments) {
|
||||
super.onPostExecute(attachments);
|
||||
|
||||
SaveAttachmentTask saveTask = new SaveAttachmentTask(c, masterSecret, attachments.size());
|
||||
saveTask.execute(attachments.toArray(new SaveAttachmentTask.Attachment[attachments.size()]));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}, gridView.getAdapter().getItemCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
|
||||
menu.clear();
|
||||
if (gridView.getAdapter() != null && gridView.getAdapter().getItemCount() > 0) {
|
||||
MenuInflater inflater = this.getMenuInflater();
|
||||
inflater.inflate(R.menu.media_overview, menu);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home: finish(); return true;
|
||||
case R.id.save: saveToDisk(); return true;
|
||||
case android.R.id.home: finish(); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -158,6 +217,7 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity i
|
||||
Log.w(TAG, "onLoadFinished()");
|
||||
gridView.setAdapter(new ImageMediaAdapter(this, masterSecret, cursor));
|
||||
noImages.setVisibility(gridView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,18 +33,26 @@ public class SaveAttachmentTask extends ProgressDialogAsyncTask<SaveAttachmentTa
|
||||
private final WeakReference<Context> contextReference;
|
||||
private final WeakReference<MasterSecret> masterSecretReference;
|
||||
|
||||
private final int attachmentCount;
|
||||
|
||||
public SaveAttachmentTask(Context context, MasterSecret masterSecret) {
|
||||
super(context, R.string.ConversationFragment_saving_attachment, R.string.ConversationFragment_saving_attachment_to_sd_card);
|
||||
this(context, masterSecret, 1);
|
||||
}
|
||||
|
||||
public SaveAttachmentTask(Context context, MasterSecret masterSecret, int count) {
|
||||
super(context,
|
||||
context.getResources().getQuantityString(R.plurals.ConversationFragment_saving_n_attachments, count, count),
|
||||
context.getResources().getQuantityString(R.plurals.ConversationFragment_saving_n_attachments_to_sd_card, count, count));
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
this.masterSecretReference = new WeakReference<>(masterSecret);
|
||||
this.attachmentCount = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(SaveAttachmentTask.Attachment... attachments) {
|
||||
if (attachments == null || attachments.length != 1 || attachments[0] == null) {
|
||||
throw new AssertionError("must pass in exactly one attachment");
|
||||
if (attachments == null || attachments.length == 0) {
|
||||
throw new AssertionError("must pass in at least one attachment");
|
||||
}
|
||||
Attachment attachment = attachments[0];
|
||||
|
||||
try {
|
||||
Context context = contextReference.get();
|
||||
@@ -58,20 +66,12 @@ public class SaveAttachmentTask extends ProgressDialogAsyncTask<SaveAttachmentTa
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
String contentType = MediaUtil.getCorrectedMimeType(attachment.contentType);
|
||||
File mediaFile = constructOutputFile(contentType, attachment.date);
|
||||
InputStream inputStream = PartAuthority.getAttachmentStream(context, masterSecret, attachment.uri);
|
||||
|
||||
if (inputStream == null) {
|
||||
return FAILURE;
|
||||
for (Attachment attachment : attachments) {
|
||||
if (attachment != null && !saveAttachment(context, masterSecret, attachment)) {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
OutputStream outputStream = new FileOutputStream(mediaFile);
|
||||
Util.copy(inputStream, outputStream);
|
||||
|
||||
MediaScannerConnection.scanFile(context, new String[]{mediaFile.getAbsolutePath()},
|
||||
new String[]{contentType}, null);
|
||||
|
||||
return SUCCESS;
|
||||
} catch (IOException ioe) {
|
||||
Log.w(TAG, ioe);
|
||||
@@ -79,6 +79,24 @@ public class SaveAttachmentTask extends ProgressDialogAsyncTask<SaveAttachmentTa
|
||||
}
|
||||
}
|
||||
|
||||
private boolean saveAttachment(Context context, MasterSecret masterSecret, Attachment attachment) throws IOException {
|
||||
String contentType = MediaUtil.getCorrectedMimeType(attachment.contentType);
|
||||
File mediaFile = constructOutputFile(contentType, attachment.date);
|
||||
InputStream inputStream = PartAuthority.getAttachmentStream(context, masterSecret, attachment.uri);
|
||||
|
||||
if (inputStream == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OutputStream outputStream = new FileOutputStream(mediaFile);
|
||||
Util.copy(inputStream, outputStream);
|
||||
|
||||
MediaScannerConnection.scanFile(context, new String[]{mediaFile.getAbsolutePath()},
|
||||
new String[]{contentType}, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Integer result) {
|
||||
super.onPostExecute(result);
|
||||
@@ -87,8 +105,10 @@ public class SaveAttachmentTask extends ProgressDialogAsyncTask<SaveAttachmentTa
|
||||
|
||||
switch (result) {
|
||||
case FAILURE:
|
||||
Toast.makeText(context, R.string.ConversationFragment_error_while_saving_attachment_to_sd_card,
|
||||
Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(context,
|
||||
context.getResources().getQuantityText(R.plurals.ConversationFragment_error_while_saving_attachments_to_sd_card,
|
||||
attachmentCount),
|
||||
Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case SUCCESS:
|
||||
Toast.makeText(context, R.string.ConversationFragment_success_exclamation,
|
||||
@@ -149,11 +169,16 @@ public class SaveAttachmentTask extends ProgressDialogAsyncTask<SaveAttachmentTa
|
||||
}
|
||||
|
||||
public static void showWarningDialog(Context context, OnClickListener onAcceptListener) {
|
||||
showWarningDialog(context, onAcceptListener, 1);
|
||||
}
|
||||
|
||||
public static void showWarningDialog(Context context, OnClickListener onAcceptListener, int count) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.ConversationFragment_save_to_sd_card);
|
||||
builder.setIconAttribute(R.attr.dialog_alert_icon);
|
||||
builder.setCancelable(true);
|
||||
builder.setMessage(R.string.ConversationFragment_saving_this_media_to_storage_warning);
|
||||
builder.setMessage(context.getResources().getQuantityString(R.plurals.ConversationFragment_saving_n_media_to_storage_warning,
|
||||
count, count));
|
||||
builder.setPositiveButton(R.string.yes, onAcceptListener);
|
||||
builder.setNegativeButton(R.string.no, null);
|
||||
builder.show();
|
||||
|
||||
Reference in New Issue
Block a user