mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-03 12:42:25 +00:00
in-app image media preview
// FREEBIE
This commit is contained in:
@@ -4,17 +4,19 @@ import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public abstract class ProgressDialogAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
|
||||
private final Context context;
|
||||
private ProgressDialog progress;
|
||||
private final String title;
|
||||
private final String message;
|
||||
private final WeakReference<Context> contextReference;
|
||||
private ProgressDialog progress;
|
||||
private final String title;
|
||||
private final String message;
|
||||
|
||||
public ProgressDialogAsyncTask(Context context, String title, String message) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
this.contextReference = new WeakReference<Context>(context);
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ProgressDialogAsyncTask(Context context, int title, int message) {
|
||||
@@ -23,7 +25,8 @@ public abstract class ProgressDialogAsyncTask<Params, Progress, Result> extends
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
progress = ProgressDialog.show(context, title, message, true);
|
||||
final Context context = contextReference.get();
|
||||
if (context != null) progress = ProgressDialog.show(context, title, message, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
162
src/org/thoughtcrime/securesms/util/SaveAttachmentTask.java
Normal file
162
src/org/thoughtcrime/securesms/util/SaveAttachmentTask.java
Normal file
@@ -0,0 +1,162 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.providers.PartProvider;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
public class SaveAttachmentTask extends ProgressDialogAsyncTask<SaveAttachmentTask.Attachment, Void, Integer> {
|
||||
private static final String TAG = SaveAttachmentTask.class.getSimpleName();
|
||||
|
||||
private static final int SUCCESS = 0;
|
||||
private static final int FAILURE = 1;
|
||||
private static final int WRITE_ACCESS_FAILURE = 2;
|
||||
|
||||
private final WeakReference<Context> contextReference;
|
||||
private final WeakReference<MasterSecret> masterSecretReference;
|
||||
|
||||
public SaveAttachmentTask(Context context, MasterSecret masterSecret) {
|
||||
super(context, R.string.ConversationFragment_saving_attachment, R.string.ConversationFragment_saving_attachment_to_sd_card);
|
||||
this.contextReference = new WeakReference<Context>(context);
|
||||
this.masterSecretReference = new WeakReference<MasterSecret>(masterSecret);
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
Attachment attachment = attachments[0];
|
||||
|
||||
try {
|
||||
Context context = contextReference.get();
|
||||
MasterSecret masterSecret = masterSecretReference.get();
|
||||
|
||||
if (!Environment.getExternalStorageDirectory().canWrite()) {
|
||||
return WRITE_ACCESS_FAILURE;
|
||||
}
|
||||
|
||||
if (context == null) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
File mediaFile = constructOutputFile(attachment.contentType, attachment.date);
|
||||
InputStream inputStream = DatabaseFactory.getEncryptingPartDatabase(context, masterSecret).getPartStream(ContentUris.parseId(attachment.uri));
|
||||
OutputStream outputStream = new FileOutputStream(mediaFile);
|
||||
|
||||
org.whispersystems.textsecure.util.Util.copy(inputStream, outputStream);
|
||||
|
||||
MediaScannerConnection.scanFile(context, new String[]{mediaFile.getAbsolutePath()},
|
||||
new String[]{attachment.contentType}, null);
|
||||
|
||||
return SUCCESS;
|
||||
} catch (IOException ioe) {
|
||||
Log.w(TAG, ioe);
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Integer result) {
|
||||
super.onPostExecute(result);
|
||||
Context context = contextReference.get();
|
||||
if (context == null) return;
|
||||
|
||||
switch (result) {
|
||||
case FAILURE:
|
||||
Toast.makeText(context, R.string.ConversationFragment_error_while_saving_attachment_to_sd_card,
|
||||
Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case SUCCESS:
|
||||
Toast.makeText(context, R.string.ConversationFragment_success_exclamation,
|
||||
Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case WRITE_ACCESS_FAILURE:
|
||||
Toast.makeText(context, R.string.ConversationFragment_unable_to_write_to_sd_card_exclamation,
|
||||
Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private File constructOutputFile(String contentType, long timestamp) throws IOException {
|
||||
File sdCard = Environment.getExternalStorageDirectory();
|
||||
File outputDirectory;
|
||||
|
||||
if (contentType.startsWith("video/")) {
|
||||
outputDirectory = new File(sdCard.getAbsoluteFile() + File.separator + Environment.DIRECTORY_MOVIES);
|
||||
} else if (contentType.startsWith("audio/")) {
|
||||
outputDirectory = new File(sdCard.getAbsolutePath() + File.separator + Environment.DIRECTORY_MUSIC);
|
||||
} else if (contentType.startsWith("image/")) {
|
||||
outputDirectory = new File(sdCard.getAbsolutePath() + File.separator + Environment.DIRECTORY_PICTURES);
|
||||
} else {
|
||||
outputDirectory = new File(sdCard.getAbsolutePath() + File.separator + Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
if (!outputDirectory.mkdirs()) Log.w(TAG, "mkdirs() returned false, attempting to continue");
|
||||
|
||||
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
|
||||
String extension = mimeTypeMap.getExtensionFromMimeType(contentType);
|
||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd-HHmmss");
|
||||
String base = "textsecure-" + dateFormatter.format(timestamp);
|
||||
|
||||
if (extension == null)
|
||||
extension = "attach";
|
||||
|
||||
int i = 0;
|
||||
File file = new File(outputDirectory, base + "." + extension);
|
||||
while (file.exists()) {
|
||||
file = new File(outputDirectory, base + "-" + (++i) + "." + extension);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public static class Attachment {
|
||||
public Uri uri;
|
||||
public String contentType;
|
||||
public long date;
|
||||
|
||||
public Attachment(Uri uri, String contentType, long date) {
|
||||
if (uri == null || contentType == null || date < 0) {
|
||||
throw new AssertionError("uri, content type, and date must all be specified");
|
||||
}
|
||||
if (!PartProvider.isAuthority(uri)) {
|
||||
throw new AssertionError("attachment must be a TextSecure attachment");
|
||||
}
|
||||
this.uri = uri;
|
||||
this.contentType = contentType;
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
|
||||
public static void showWarningDialog(Context context, OnClickListener onAcceptListener) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.ConversationFragment_save_to_sd_card);
|
||||
builder.setIcon(Dialogs.resolveIcon(context, R.attr.dialog_alert_icon));
|
||||
builder.setCancelable(true);
|
||||
builder.setMessage(R.string.ConversationFragment_this_media_has_been_stored_in_an_encrypted_database_warning);
|
||||
builder.setPositiveButton(R.string.yes, onAcceptListener);
|
||||
builder.setNegativeButton(R.string.no, null);
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user