2011-01-06 11:56:20 -05:00
|
|
|
package com.fsck.k9.view;
|
|
|
|
|
2014-10-20 19:39:16 -04:00
|
|
|
|
2011-04-23 23:56:34 -04:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.OutputStream;
|
2014-11-09 15:57:16 -05:00
|
|
|
import java.util.List;
|
2011-04-23 23:56:34 -04:00
|
|
|
|
2014-11-09 15:57:16 -05:00
|
|
|
import android.content.ActivityNotFoundException;
|
2011-01-06 11:56:20 -05:00
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
2014-11-09 15:57:16 -05:00
|
|
|
import android.content.pm.PackageManager;
|
|
|
|
import android.content.pm.ResolveInfo;
|
2011-01-06 11:56:20 -05:00
|
|
|
import android.graphics.Bitmap;
|
|
|
|
import android.graphics.BitmapFactory;
|
|
|
|
import android.net.Uri;
|
2014-02-16 18:10:44 -05:00
|
|
|
import android.os.AsyncTask;
|
2011-01-06 11:56:20 -05:00
|
|
|
import android.os.Environment;
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.view.View;
|
2012-02-27 15:34:18 -05:00
|
|
|
import android.view.View.OnClickListener;
|
|
|
|
import android.view.View.OnLongClickListener;
|
2011-04-23 23:56:34 -04:00
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.FrameLayout;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.TextView;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
2011-01-06 11:56:20 -05:00
|
|
|
import com.fsck.k9.Account;
|
|
|
|
import com.fsck.k9.K9;
|
|
|
|
import com.fsck.k9.R;
|
|
|
|
import com.fsck.k9.controller.MessagingController;
|
|
|
|
import com.fsck.k9.controller.MessagingListener;
|
2014-11-10 19:04:39 -05:00
|
|
|
import com.fsck.k9.helper.FileHelper;
|
2011-01-06 11:56:20 -05:00
|
|
|
import com.fsck.k9.helper.MediaScannerNotifier;
|
|
|
|
import com.fsck.k9.helper.SizeFormatter;
|
|
|
|
import com.fsck.k9.mail.Message;
|
2012-02-27 15:00:44 -05:00
|
|
|
import com.fsck.k9.mail.MessagingException;
|
2011-01-06 11:56:20 -05:00
|
|
|
import com.fsck.k9.mail.Part;
|
2012-01-18 00:00:26 -05:00
|
|
|
import com.fsck.k9.mail.internet.MimeHeader;
|
2011-01-06 11:56:20 -05:00
|
|
|
import com.fsck.k9.mail.internet.MimeUtility;
|
|
|
|
import com.fsck.k9.mail.store.LocalStore.LocalAttachmentBodyPart;
|
|
|
|
import com.fsck.k9.provider.AttachmentProvider;
|
2014-10-20 20:28:38 -04:00
|
|
|
import org.apache.commons.io.IOUtils;
|
2011-01-06 11:56:20 -05:00
|
|
|
|
2014-10-20 19:39:16 -04:00
|
|
|
|
2012-02-27 15:34:18 -05:00
|
|
|
public class AttachmentView extends FrameLayout implements OnClickListener, OnLongClickListener {
|
2014-10-20 21:09:23 -04:00
|
|
|
private Context context;
|
|
|
|
private Message message;
|
2014-10-20 21:21:09 -04:00
|
|
|
private LocalAttachmentBodyPart part;
|
2014-10-20 21:09:23 -04:00
|
|
|
private Account account;
|
|
|
|
private MessagingController controller;
|
|
|
|
private MessagingListener listener;
|
2014-10-20 21:21:09 -04:00
|
|
|
private AttachmentFileDownloadCallback callback;
|
|
|
|
|
|
|
|
private Button viewButton;
|
|
|
|
private Button downloadButton;
|
|
|
|
|
2014-10-20 20:14:04 -04:00
|
|
|
private String name;
|
|
|
|
private String contentType;
|
|
|
|
private long size;
|
2012-01-26 21:07:44 -05:00
|
|
|
|
2011-04-24 00:00:10 -04:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public AttachmentView(Context context, AttributeSet attrs, int defStyle) {
|
2011-01-06 11:56:20 -05:00
|
|
|
super(context, attrs, defStyle);
|
2014-10-20 21:09:23 -04:00
|
|
|
this.context = context;
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
2014-10-20 19:39:16 -04:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public AttachmentView(Context context, AttributeSet attrs) {
|
2011-01-06 11:56:20 -05:00
|
|
|
super(context, attrs);
|
2014-10-20 21:09:23 -04:00
|
|
|
this.context = context;
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
2014-10-20 19:39:16 -04:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public AttachmentView(Context context) {
|
2011-01-06 11:56:20 -05:00
|
|
|
super(context);
|
2014-10-20 21:09:23 -04:00
|
|
|
this.context = context;
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
|
|
|
|
2014-10-20 20:14:04 -04:00
|
|
|
public void setButtonsEnabled(boolean enabled) {
|
|
|
|
viewButton.setEnabled(enabled);
|
|
|
|
downloadButton.setEnabled(enabled);
|
|
|
|
}
|
|
|
|
|
2012-01-18 00:00:26 -05:00
|
|
|
/**
|
|
|
|
* Populates this view with information about the attachment.
|
|
|
|
* <p>
|
|
|
|
* This method also decides which attachments are displayed when the "show attachments" button
|
|
|
|
* is pressed, and which attachments are only displayed after the "show more attachments"
|
|
|
|
* button was pressed.<br>
|
|
|
|
* Inline attachments with content ID and unnamed attachments fall into the second category.
|
|
|
|
* </p>
|
|
|
|
*
|
2014-10-20 21:13:58 -04:00
|
|
|
* @return {@code true} for a regular attachment. {@code false} for attachments that should be initially hidden.
|
2012-01-18 00:00:26 -05:00
|
|
|
*/
|
|
|
|
public boolean populateFromPart(Part inputPart, Message message, Account account,
|
2012-02-27 15:00:44 -05:00
|
|
|
MessagingController controller, MessagingListener listener) throws MessagingException {
|
2014-10-20 21:06:31 -04:00
|
|
|
|
2012-02-27 15:00:44 -05:00
|
|
|
part = (LocalAttachmentBodyPart) inputPart;
|
2014-10-20 21:09:23 -04:00
|
|
|
this.message = message;
|
|
|
|
this.account = account;
|
|
|
|
this.controller = controller;
|
|
|
|
this.listener = listener;
|
2014-10-20 21:06:31 -04:00
|
|
|
|
|
|
|
boolean firstClassAttachment = extractAttachmentInformation(part);
|
|
|
|
|
|
|
|
displayAttachmentInformation();
|
|
|
|
|
|
|
|
return firstClassAttachment;
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: extract this code to a helper class
|
|
|
|
private boolean extractAttachmentInformation(Part part) throws MessagingException {
|
|
|
|
boolean firstClassAttachment = true;
|
2011-01-06 11:56:20 -05:00
|
|
|
|
2014-11-09 15:57:16 -05:00
|
|
|
contentType = part.getMimeType();
|
|
|
|
String contentTypeHeader = MimeUtility.unfoldAndDecode(part.getContentType());
|
2012-02-27 15:00:44 -05:00
|
|
|
String contentDisposition = MimeUtility.unfoldAndDecode(part.getDisposition());
|
2011-01-06 11:56:20 -05:00
|
|
|
|
2014-11-09 15:57:16 -05:00
|
|
|
name = MimeUtility.getHeaderParameter(contentTypeHeader, "name");
|
2012-02-27 15:00:44 -05:00
|
|
|
if (name == null) {
|
|
|
|
name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
|
|
|
|
}
|
2012-01-18 00:00:26 -05:00
|
|
|
|
2012-02-27 15:00:44 -05:00
|
|
|
if (name == null) {
|
|
|
|
firstClassAttachment = false;
|
|
|
|
String extension = MimeUtility.getExtensionByMimeType(contentType);
|
|
|
|
name = "noname" + ((extension != null) ? "." + extension : "");
|
|
|
|
}
|
2012-01-18 00:00:26 -05:00
|
|
|
|
2012-02-27 15:00:44 -05:00
|
|
|
// Inline parts with a content-id are almost certainly components of an HTML message
|
|
|
|
// not attachments. Only show them if the user pressed the button to show more
|
|
|
|
// attachments.
|
|
|
|
if (contentDisposition != null &&
|
|
|
|
MimeUtility.getHeaderParameter(contentDisposition, null).matches("^(?i:inline)")
|
|
|
|
&& part.getHeader(MimeHeader.HEADER_CONTENT_ID) != null) {
|
|
|
|
firstClassAttachment = false;
|
|
|
|
}
|
2011-01-06 11:56:20 -05:00
|
|
|
|
2012-02-27 15:00:44 -05:00
|
|
|
String sizeParam = MimeUtility.getHeaderParameter(contentDisposition, "size");
|
|
|
|
if (sizeParam != null) {
|
|
|
|
try {
|
|
|
|
size = Integer.parseInt(sizeParam);
|
|
|
|
} catch (NumberFormatException e) { /* ignore */ }
|
|
|
|
}
|
2012-02-27 14:29:22 -05:00
|
|
|
|
2014-10-20 21:06:31 -04:00
|
|
|
return firstClassAttachment;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void displayAttachmentInformation() {
|
2012-02-27 15:00:44 -05:00
|
|
|
TextView attachmentName = (TextView) findViewById(R.id.attachment_name);
|
|
|
|
TextView attachmentInfo = (TextView) findViewById(R.id.attachment_info);
|
|
|
|
viewButton = (Button) findViewById(R.id.view);
|
|
|
|
downloadButton = (Button) findViewById(R.id.download);
|
2014-10-20 21:06:31 -04:00
|
|
|
|
2012-02-27 15:00:44 -05:00
|
|
|
if (size > K9.MAX_ATTACHMENT_DOWNLOAD_SIZE) {
|
|
|
|
viewButton.setVisibility(View.GONE);
|
|
|
|
downloadButton.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
|
2012-02-27 15:34:18 -05:00
|
|
|
viewButton.setOnClickListener(this);
|
|
|
|
downloadButton.setOnClickListener(this);
|
|
|
|
downloadButton.setOnLongClickListener(this);
|
2012-02-27 15:00:44 -05:00
|
|
|
|
|
|
|
attachmentName.setText(name);
|
2014-10-20 21:09:23 -04:00
|
|
|
attachmentInfo.setText(SizeFormatter.formatSize(context, size));
|
2014-02-16 18:10:44 -05:00
|
|
|
|
2014-10-20 20:46:46 -04:00
|
|
|
ImageView thumbnail = (ImageView) findViewById(R.id.attachment_icon);
|
|
|
|
new LoadAndDisplayThumbnailAsyncTask(thumbnail).execute();
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
|
|
|
|
2012-02-27 15:34:18 -05:00
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
switch (view.getId()) {
|
|
|
|
case R.id.view: {
|
|
|
|
onViewButtonClicked();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case R.id.download: {
|
|
|
|
onSaveButtonClicked();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onLongClick(View view) {
|
|
|
|
if (view.getId() == R.id.download) {
|
2014-10-20 20:28:38 -04:00
|
|
|
callback.pickDirectoryToSaveAttachmentTo(this);
|
2012-02-27 15:34:18 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onViewButtonClicked() {
|
2014-10-20 21:09:23 -04:00
|
|
|
if (message != null) {
|
|
|
|
controller.loadAttachment(account, message, part, new Object[] {false, this}, listener);
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onSaveButtonClicked() {
|
2014-10-20 21:16:31 -04:00
|
|
|
boolean isExternalStorageMounted = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
|
|
|
|
if (!isExternalStorageMounted) {
|
|
|
|
String message = context.getString(R.string.message_view_status_attachment_not_saved);
|
|
|
|
displayMessageToUser(message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (message != null) {
|
|
|
|
controller.loadAttachment(account, message, part, new Object[] {true, this}, listener);
|
|
|
|
}
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
|
|
|
|
2014-10-20 21:21:09 -04:00
|
|
|
public void writeFile() {
|
|
|
|
writeFile(new File(K9.getAttachmentDefaultPath()));
|
|
|
|
}
|
|
|
|
|
2011-04-24 00:00:10 -04:00
|
|
|
/**
|
2014-10-20 21:13:58 -04:00
|
|
|
* Saves the attachment as file in the given directory
|
2011-04-24 00:00:10 -04:00
|
|
|
*/
|
|
|
|
public void writeFile(File directory) {
|
2011-02-06 17:09:48 -05:00
|
|
|
try {
|
2014-11-09 23:37:22 -05:00
|
|
|
File file = writeAttachmentToStorage(directory);
|
|
|
|
|
2014-10-20 21:24:18 -04:00
|
|
|
displayAttachmentSavedMessage(file.toString());
|
2014-11-09 23:37:22 -05:00
|
|
|
|
2014-11-10 00:43:26 -05:00
|
|
|
MediaScannerNotifier.notify(context, file);
|
2011-02-06 17:09:48 -05:00
|
|
|
} catch (IOException ioe) {
|
2012-02-02 19:22:37 -05:00
|
|
|
if (K9.DEBUG) {
|
|
|
|
Log.e(K9.LOG_TAG, "Error saving attachment", ioe);
|
|
|
|
}
|
2014-10-20 21:24:18 -04:00
|
|
|
displayAttachmentNotSavedMessage();
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
|
|
|
}
|
2012-01-26 16:25:46 -05:00
|
|
|
|
2014-11-09 23:37:22 -05:00
|
|
|
private File writeAttachmentToStorage(File directory) throws IOException {
|
2014-11-10 19:04:39 -05:00
|
|
|
String filename = FileHelper.sanitizeFilename(name);
|
|
|
|
File file = FileHelper.createUniqueFile(directory, filename);
|
2014-11-09 23:37:22 -05:00
|
|
|
|
|
|
|
Uri uri = AttachmentProvider.getAttachmentUri(account, part.getAttachmentId());
|
|
|
|
InputStream in = context.getContentResolver().openInputStream(uri);
|
2011-02-06 17:09:48 -05:00
|
|
|
try {
|
2014-11-09 23:37:22 -05:00
|
|
|
OutputStream out = new FileOutputStream(file);
|
|
|
|
try {
|
|
|
|
IOUtils.copy(in, out);
|
|
|
|
out.flush();
|
|
|
|
} finally {
|
|
|
|
out.close();
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
in.close();
|
|
|
|
}
|
2014-10-20 19:50:41 -04:00
|
|
|
|
2014-11-09 23:37:22 -05:00
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void showFile() {
|
|
|
|
new ViewAttachmentAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Intent getBestViewIntentAndSaveFileIfNecessary() {
|
|
|
|
IntentAndResolvedActivitiesCount resultForContentUri = getBestViewIntentForContentUri();
|
|
|
|
if (resultForContentUri.getActivitiesCount() > 0) {
|
|
|
|
return resultForContentUri.getIntent();
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
2014-11-09 23:37:22 -05:00
|
|
|
|
|
|
|
IntentAndResolvedActivitiesCount resultForFileUri = getBestViewIntentForFileUri();
|
|
|
|
if (resultForFileUri.getActivitiesCount() > 0) {
|
|
|
|
try {
|
|
|
|
File file = writeAttachmentToStorage(new File(K9.getAttachmentDefaultPath()));
|
|
|
|
return createViewIntentForFileUri(resultForFileUri.getMimeType(), Uri.fromFile(file));
|
|
|
|
} catch (IOException e) {
|
|
|
|
if (K9.DEBUG) {
|
|
|
|
Log.e(K9.LOG_TAG, "Error while saving attachment to use file:// URI with ACTION_VIEW Intent", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return resultForContentUri.getIntent();
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
|
|
|
|
2014-11-09 23:37:22 -05:00
|
|
|
private IntentAndResolvedActivitiesCount getBestViewIntentForContentUri() {
|
2014-11-09 15:57:16 -05:00
|
|
|
Intent intent;
|
2014-11-09 23:37:22 -05:00
|
|
|
int activitiesCount;
|
2014-11-09 15:57:16 -05:00
|
|
|
|
2014-11-09 18:56:24 -05:00
|
|
|
Uri originalMimeTypeUri = AttachmentProvider.getAttachmentUriForViewing(account, part.getAttachmentId(),
|
2014-11-09 23:46:38 -05:00
|
|
|
contentType, name);
|
2014-11-09 18:56:24 -05:00
|
|
|
Intent originalMimeTypeIntent = createViewIntentForContentUri(contentType, originalMimeTypeUri);
|
2014-11-09 15:57:16 -05:00
|
|
|
int originalMimeTypeActivitiesCount = getResolvedIntentActivitiesCount(originalMimeTypeIntent);
|
|
|
|
|
|
|
|
String inferredMimeType = MimeUtility.getMimeTypeByExtension(name);
|
|
|
|
if (inferredMimeType.equals(contentType)) {
|
|
|
|
intent = originalMimeTypeIntent;
|
2014-11-09 23:37:22 -05:00
|
|
|
activitiesCount = originalMimeTypeActivitiesCount;
|
2014-11-09 15:57:16 -05:00
|
|
|
} else {
|
2014-11-09 18:56:24 -05:00
|
|
|
Uri inferredMimeTypeUri = AttachmentProvider.getAttachmentUriForViewing(account, part.getAttachmentId(),
|
2014-11-09 23:46:38 -05:00
|
|
|
inferredMimeType, name);
|
2014-11-09 18:56:24 -05:00
|
|
|
Intent inferredMimeTypeIntent = createViewIntentForContentUri(inferredMimeType, inferredMimeTypeUri);
|
2014-11-09 15:57:16 -05:00
|
|
|
int inferredMimeTypeActivitiesCount = getResolvedIntentActivitiesCount(inferredMimeTypeIntent);
|
|
|
|
|
|
|
|
if (inferredMimeTypeActivitiesCount > originalMimeTypeActivitiesCount) {
|
|
|
|
intent = inferredMimeTypeIntent;
|
2014-11-09 23:37:22 -05:00
|
|
|
activitiesCount = inferredMimeTypeActivitiesCount;
|
2014-11-09 15:57:16 -05:00
|
|
|
} else {
|
|
|
|
intent = originalMimeTypeIntent;
|
2014-11-09 23:37:22 -05:00
|
|
|
activitiesCount = originalMimeTypeActivitiesCount;
|
2014-11-09 15:57:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-09 23:37:22 -05:00
|
|
|
return new IntentAndResolvedActivitiesCount(intent, activitiesCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
private IntentAndResolvedActivitiesCount getBestViewIntentForFileUri() {
|
|
|
|
Intent intent;
|
|
|
|
int activitiesCount;
|
|
|
|
|
2014-11-10 19:04:39 -05:00
|
|
|
File dummyFile = new File(FileHelper.sanitizeFilename(name));
|
2014-11-09 23:37:22 -05:00
|
|
|
Uri fileUri = Uri.fromFile(dummyFile);
|
|
|
|
|
|
|
|
Intent originalMimeTypeIntent = createViewIntentForFileUri(contentType, fileUri);
|
|
|
|
int originalMimeTypeActivitiesCount = getResolvedIntentActivitiesCount(originalMimeTypeIntent);
|
|
|
|
|
|
|
|
String inferredMimeType = MimeUtility.getMimeTypeByExtension(name);
|
|
|
|
if (inferredMimeType.equals(contentType)) {
|
|
|
|
intent = originalMimeTypeIntent;
|
|
|
|
activitiesCount = originalMimeTypeActivitiesCount;
|
|
|
|
} else {
|
|
|
|
Intent inferredMimeTypeIntent = createViewIntentForFileUri(inferredMimeType, fileUri);
|
|
|
|
int inferredMimeTypeActivitiesCount = getResolvedIntentActivitiesCount(inferredMimeTypeIntent);
|
|
|
|
|
|
|
|
if (inferredMimeTypeActivitiesCount > originalMimeTypeActivitiesCount) {
|
|
|
|
intent = inferredMimeTypeIntent;
|
|
|
|
activitiesCount = inferredMimeTypeActivitiesCount;
|
|
|
|
} else {
|
|
|
|
intent = originalMimeTypeIntent;
|
|
|
|
activitiesCount = originalMimeTypeActivitiesCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return new IntentAndResolvedActivitiesCount(intent, activitiesCount);
|
2014-11-09 15:57:16 -05:00
|
|
|
}
|
|
|
|
|
2014-11-09 14:46:46 -05:00
|
|
|
private Intent createViewIntentForContentUri(String mimeType, Uri uri) {
|
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
|
|
intent.setDataAndType(uri, mimeType);
|
2014-11-09 23:37:22 -05:00
|
|
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
|
|
addUiIntentFlags(intent);
|
2014-11-09 14:46:46 -05:00
|
|
|
|
|
|
|
return intent;
|
|
|
|
}
|
|
|
|
|
2014-11-09 23:37:22 -05:00
|
|
|
private Intent createViewIntentForFileUri(String mimeType, Uri uri) {
|
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
|
|
intent.setDataAndType(uri, mimeType);
|
|
|
|
addUiIntentFlags(intent);
|
|
|
|
|
|
|
|
return intent;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addUiIntentFlags(Intent intent) {
|
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
|
|
|
}
|
|
|
|
|
2014-11-09 15:57:16 -05:00
|
|
|
private int getResolvedIntentActivitiesCount(Intent intent) {
|
|
|
|
PackageManager packageManager = context.getPackageManager();
|
|
|
|
|
|
|
|
List<ResolveInfo> resolveInfos =
|
|
|
|
packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
|
|
|
|
|
|
|
return resolveInfos.size();
|
|
|
|
}
|
|
|
|
|
2014-10-20 21:24:18 -04:00
|
|
|
private void displayAttachmentSavedMessage(final String filename) {
|
2014-10-20 21:09:23 -04:00
|
|
|
String message = context.getString(R.string.message_view_status_attachment_saved, filename);
|
2014-10-20 19:50:41 -04:00
|
|
|
displayMessageToUser(message);
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
|
|
|
|
2014-10-20 21:24:18 -04:00
|
|
|
private void displayAttachmentNotSavedMessage() {
|
2014-10-20 21:09:23 -04:00
|
|
|
String message = context.getString(R.string.message_view_status_attachment_not_saved);
|
2014-10-20 19:50:41 -04:00
|
|
|
displayMessageToUser(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void displayMessageToUser(String message) {
|
2014-10-20 21:09:23 -04:00
|
|
|
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|
2014-10-20 19:30:20 -04:00
|
|
|
|
2011-04-24 00:00:10 -04:00
|
|
|
public void setCallback(AttachmentFileDownloadCallback callback) {
|
|
|
|
this.callback = callback;
|
|
|
|
}
|
2014-10-20 20:46:46 -04:00
|
|
|
|
2014-10-20 21:21:09 -04:00
|
|
|
|
|
|
|
public interface AttachmentFileDownloadCallback {
|
|
|
|
/**
|
|
|
|
* This method is called to ask the user to pick a directory to save the attachment to.
|
|
|
|
* <p/>
|
|
|
|
* After the user has selected a directory, the implementation of this interface has to call
|
|
|
|
* {@link #writeFile(File)} on the object supplied as argument in order for the attachment to be saved.
|
|
|
|
*/
|
|
|
|
public void pickDirectoryToSaveAttachmentTo(AttachmentView caller);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-09 23:37:22 -05:00
|
|
|
private static class IntentAndResolvedActivitiesCount {
|
|
|
|
private Intent intent;
|
|
|
|
private int activitiesCount;
|
|
|
|
|
|
|
|
IntentAndResolvedActivitiesCount(Intent intent, int activitiesCount) {
|
|
|
|
this.intent = intent;
|
|
|
|
this.activitiesCount = activitiesCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Intent getIntent() {
|
|
|
|
return intent;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getActivitiesCount() {
|
|
|
|
return activitiesCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getMimeType() {
|
|
|
|
return intent.getType();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-20 20:46:46 -04:00
|
|
|
private class LoadAndDisplayThumbnailAsyncTask extends AsyncTask<Void, Void, Bitmap> {
|
|
|
|
private final ImageView thumbnail;
|
|
|
|
|
|
|
|
public LoadAndDisplayThumbnailAsyncTask(ImageView thumbnail) {
|
|
|
|
this.thumbnail = thumbnail;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Bitmap doInBackground(Void... asyncTaskArgs) {
|
|
|
|
return getPreviewIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
private Bitmap getPreviewIcon() {
|
|
|
|
Bitmap icon = null;
|
|
|
|
try {
|
2014-10-20 21:09:23 -04:00
|
|
|
InputStream input = context.getContentResolver().openInputStream(
|
|
|
|
AttachmentProvider.getAttachmentThumbnailUri(account,
|
2014-10-20 20:46:46 -04:00
|
|
|
part.getAttachmentId(),
|
|
|
|
62,
|
|
|
|
62));
|
|
|
|
icon = BitmapFactory.decodeStream(input);
|
|
|
|
input.close();
|
|
|
|
} catch (Exception e) {
|
|
|
|
// We don't care what happened, we just return null for the preview icon.
|
|
|
|
}
|
|
|
|
|
|
|
|
return icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void onPostExecute(Bitmap previewIcon) {
|
|
|
|
if (previewIcon != null) {
|
|
|
|
thumbnail.setImageBitmap(previewIcon);
|
|
|
|
} else {
|
|
|
|
thumbnail.setImageResource(R.drawable.attached_image_placeholder);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-11-09 23:37:22 -05:00
|
|
|
|
|
|
|
private class ViewAttachmentAsyncTask extends AsyncTask<Void, Void, Intent> {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPreExecute() {
|
|
|
|
viewButton.setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Intent doInBackground(Void... params) {
|
|
|
|
return getBestViewIntentAndSaveFileIfNecessary();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Intent intent) {
|
|
|
|
viewAttachment(intent);
|
|
|
|
viewButton.setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void viewAttachment(Intent intent) {
|
|
|
|
try {
|
|
|
|
context.startActivity(intent);
|
|
|
|
} catch (ActivityNotFoundException e) {
|
|
|
|
Log.e(K9.LOG_TAG, "Could not display attachment of type " + contentType, e);
|
|
|
|
|
|
|
|
String message = context.getString(R.string.message_view_no_viewer, contentType);
|
|
|
|
displayMessageToUser(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-01-06 11:56:20 -05:00
|
|
|
}
|