Merge "Split out AttachmentInfo into its own top-level class" into honeycomb
This commit is contained in:
commit
238b9f2826
127
src/com/android/email/AttachmentInfo.java
Normal file
127
src/com/android/email/AttachmentInfo.java
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.email;
|
||||||
|
|
||||||
|
import com.android.email.mail.internet.MimeUtility;
|
||||||
|
import com.android.email.provider.AttachmentProvider;
|
||||||
|
import com.android.email.provider.EmailContent.Attachment;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates commonly used attachment information related to suitability for viewing and saving,
|
||||||
|
* based on the attachment's filename and mime type.
|
||||||
|
*/
|
||||||
|
public class AttachmentInfo {
|
||||||
|
public final String mName;
|
||||||
|
public final String mContentType;
|
||||||
|
public final long mSize;
|
||||||
|
public final long mId;
|
||||||
|
public final boolean mAllowView;
|
||||||
|
public final boolean mAllowSave;
|
||||||
|
|
||||||
|
public AttachmentInfo(Context context, Attachment attachment) {
|
||||||
|
mSize = attachment.mSize;
|
||||||
|
mContentType = AttachmentProvider.inferMimeType(attachment.mFileName, attachment.mMimeType);
|
||||||
|
mName = attachment.mFileName;
|
||||||
|
mId = attachment.mId;
|
||||||
|
boolean canView = true;
|
||||||
|
boolean canSave = true;
|
||||||
|
|
||||||
|
// Check for acceptable / unacceptable attachments by MIME-type
|
||||||
|
if ((!MimeUtility.mimeTypeMatches(mContentType, Email.ACCEPTABLE_ATTACHMENT_VIEW_TYPES)) ||
|
||||||
|
(MimeUtility.mimeTypeMatches(mContentType, Email.UNACCEPTABLE_ATTACHMENT_VIEW_TYPES))) {
|
||||||
|
canView = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for unacceptable attachments by filename extension
|
||||||
|
String extension = AttachmentProvider.getFilenameExtension(mName);
|
||||||
|
if (!TextUtils.isEmpty(extension) &&
|
||||||
|
Utility.arrayContains(Email.UNACCEPTABLE_ATTACHMENT_EXTENSIONS, extension)) {
|
||||||
|
canView = false;
|
||||||
|
canSave = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for installable attachments by filename extension
|
||||||
|
extension = AttachmentProvider.getFilenameExtension(mName);
|
||||||
|
if (!TextUtils.isEmpty(extension) &&
|
||||||
|
Utility.arrayContains(Email.INSTALLABLE_ATTACHMENT_EXTENSIONS, extension)) {
|
||||||
|
int sideloadEnabled;
|
||||||
|
sideloadEnabled = Settings.Secure.getInt(context.getContentResolver(),
|
||||||
|
Settings.Secure.INSTALL_NON_MARKET_APPS, 0 /* sideload disabled */);
|
||||||
|
canView = false;
|
||||||
|
canSave &= (sideloadEnabled == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for file size exceeded
|
||||||
|
// The size limit is overridden when on a wifi connection - any size is OK
|
||||||
|
if (mSize > Email.MAX_ATTACHMENT_DOWNLOAD_SIZE) {
|
||||||
|
ConnectivityManager cm = (ConnectivityManager)
|
||||||
|
context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
NetworkInfo network = cm.getActiveNetworkInfo();
|
||||||
|
if (network == null || network.getType() != ConnectivityManager.TYPE_WIFI) {
|
||||||
|
canView = false;
|
||||||
|
canSave = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if any activities can view this attachment
|
||||||
|
// If not, we can't view it
|
||||||
|
Intent intent = getAttachmentIntent(context, 0);
|
||||||
|
PackageManager pm = context.getPackageManager();
|
||||||
|
List<ResolveInfo> activityList = pm.queryIntentActivities(intent, 0);
|
||||||
|
if (activityList.isEmpty()) {
|
||||||
|
canView = false;
|
||||||
|
canSave = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAllowView = canView;
|
||||||
|
mAllowSave = canSave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an <code>Intent</code> to load the given attachment.
|
||||||
|
*/
|
||||||
|
public Intent getAttachmentIntent(Context context, long accountId) {
|
||||||
|
Uri attachmentUri = AttachmentProvider.getAttachmentUri(accountId, mId);
|
||||||
|
Uri contentUri = AttachmentProvider.resolveAttachmentIdToContentUri(
|
||||||
|
context.getContentResolver(), attachmentUri);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setData(contentUri);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
| Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An attachment is eligible for download if it can either be viewed or saved (or both)
|
||||||
|
* @return whether the attachment is eligible for download
|
||||||
|
*/
|
||||||
|
public boolean eligibleForDownload() {
|
||||||
|
return mAllowView || mAllowSave;
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.email.activity;
|
package com.android.email.activity;
|
||||||
|
|
||||||
|
import com.android.email.AttachmentInfo;
|
||||||
import com.android.email.Controller;
|
import com.android.email.Controller;
|
||||||
import com.android.email.ControllerResultUiThreadWrapper;
|
import com.android.email.ControllerResultUiThreadWrapper;
|
||||||
import com.android.email.Email;
|
import com.android.email.Email;
|
||||||
@ -26,7 +27,6 @@ import com.android.email.Utility;
|
|||||||
import com.android.email.mail.Address;
|
import com.android.email.mail.Address;
|
||||||
import com.android.email.mail.MessagingException;
|
import com.android.email.mail.MessagingException;
|
||||||
import com.android.email.mail.internet.EmailHtmlUtil;
|
import com.android.email.mail.internet.EmailHtmlUtil;
|
||||||
import com.android.email.mail.internet.MimeUtility;
|
|
||||||
import com.android.email.provider.AttachmentProvider;
|
import com.android.email.provider.AttachmentProvider;
|
||||||
import com.android.email.provider.EmailContent.Attachment;
|
import com.android.email.provider.EmailContent.Attachment;
|
||||||
import com.android.email.provider.EmailContent.Body;
|
import com.android.email.provider.EmailContent.Body;
|
||||||
@ -45,15 +45,11 @@ import android.content.ContentUris;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.Loader;
|
import android.content.Loader;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.media.MediaScannerConnection;
|
import android.media.MediaScannerConnection;
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -61,7 +57,6 @@ import android.os.Environment;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.provider.ContactsContract.QuickContact;
|
import android.provider.ContactsContract.QuickContact;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
@ -85,7 +80,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -212,28 +206,6 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
*/
|
*/
|
||||||
private static final float[] ZOOM_SCALE_ARRAY = new float[] {0.8f, 0.9f, 1.0f, 1.2f, 1.5f};
|
private static final float[] ZOOM_SCALE_ARRAY = new float[] {0.8f, 0.9f, 1.0f, 1.2f, 1.5f};
|
||||||
|
|
||||||
/**
|
|
||||||
* Encapsulates known information about a single attachment.
|
|
||||||
*
|
|
||||||
* TODO: This should have methods to encapsulate the entire state graph of loading, canceling,
|
|
||||||
* viewing, and saving.
|
|
||||||
*/
|
|
||||||
private static class AttachmentInfo {
|
|
||||||
public String name;
|
|
||||||
public String contentType;
|
|
||||||
public long size;
|
|
||||||
public long attachmentId;
|
|
||||||
public Button viewButton;
|
|
||||||
public Button saveButton;
|
|
||||||
public Button loadButton;
|
|
||||||
public Button cancelButton;
|
|
||||||
public ImageView iconView;
|
|
||||||
public ProgressBar progressView;
|
|
||||||
public boolean allowView;
|
|
||||||
public boolean allowSave;
|
|
||||||
public boolean isLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Callback {
|
public interface Callback {
|
||||||
/** Called when the fragment is about to show up, or show a different message. */
|
/** Called when the fragment is about to show up, or show a different message. */
|
||||||
public void onMessageViewShown(int mailboxType);
|
public void onMessageViewShown(int mailboxType);
|
||||||
@ -695,7 +667,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSaveAttachment(AttachmentInfo info) {
|
private void onSaveAttachment(MessageViewAttachmentInfo info) {
|
||||||
if (!Utility.isExternalStorageMounted()) {
|
if (!Utility.isExternalStorageMounted()) {
|
||||||
/*
|
/*
|
||||||
* Abort early if there's no place to save the attachment. We don't want to spend
|
* Abort early if there's no place to save the attachment. We don't want to spend
|
||||||
@ -704,7 +676,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
Utility.showToast(getActivity(), R.string.message_view_status_attachment_not_saved);
|
Utility.showToast(getActivity(), R.string.message_view_status_attachment_not_saved);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Attachment attachment = Attachment.restoreAttachmentWithId(mContext, info.attachmentId);
|
Attachment attachment = Attachment.restoreAttachmentWithId(mContext, info.mId);
|
||||||
Uri attachmentUri = AttachmentProvider.getAttachmentUri(mAccountId, attachment.mId);
|
Uri attachmentUri = AttachmentProvider.getAttachmentUri(mAccountId, attachment.mId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -733,8 +705,8 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onViewAttachment(AttachmentInfo info) {
|
private void onViewAttachment(MessageViewAttachmentInfo info) {
|
||||||
Intent intent = getAttachmentIntent(info);
|
Intent intent = info.getAttachmentIntent(mContext, mAccountId);
|
||||||
try {
|
try {
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
@ -742,21 +714,8 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an <code>Intent</code> to load the given attachment.
|
|
||||||
*/
|
|
||||||
private Intent getAttachmentIntent(AttachmentInfo info) {
|
|
||||||
Uri attachmentUri = AttachmentProvider.getAttachmentUri(mAccountId, info.attachmentId);
|
|
||||||
Uri contentUri = AttachmentProvider.resolveAttachmentIdToContentUri(
|
|
||||||
mContext.getContentResolver(), attachmentUri);
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
intent.setData(contentUri);
|
|
||||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
|
|
||||||
| Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onLoadAttachment(final AttachmentInfo attachment) {
|
private void onLoadAttachment(final MessageViewAttachmentInfo attachment) {
|
||||||
attachment.loadButton.setVisibility(View.GONE);
|
attachment.loadButton.setVisibility(View.GONE);
|
||||||
// If there's nothing in the download queue, we'll probably start right away so wait a
|
// If there's nothing in the download queue, we'll probably start right away so wait a
|
||||||
// second before showing the cancel button
|
// second before showing the cancel button
|
||||||
@ -776,7 +735,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Void result) {
|
protected void onPostExecute(Void result) {
|
||||||
// If the timeout completes and the attachment has not loaded, show cancel
|
// If the timeout completes and the attachment has not loaded, show cancel
|
||||||
if (!attachment.isLoaded) {
|
if (!attachment.loaded) {
|
||||||
attachment.cancelButton.setVisibility(View.VISIBLE);
|
attachment.cancelButton.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -787,12 +746,12 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
ProgressBar bar = attachment.progressView;
|
ProgressBar bar = attachment.progressView;
|
||||||
bar.setVisibility(View.VISIBLE);
|
bar.setVisibility(View.VISIBLE);
|
||||||
bar.setIndeterminate(true);
|
bar.setIndeterminate(true);
|
||||||
mController.loadAttachment(attachment.attachmentId, mMessageId, mAccountId);
|
mController.loadAttachment(attachment.mId, mMessageId, mAccountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onCancelAttachment(AttachmentInfo attachment) {
|
private void onCancelAttachment(MessageViewAttachmentInfo attachment) {
|
||||||
// Don't change button states if we couldn't cancel the download
|
// Don't change button states if we couldn't cancel the download
|
||||||
if (AttachmentDownloadService.cancelQueuedAttachment(attachment.attachmentId)) {
|
if (AttachmentDownloadService.cancelQueuedAttachment(attachment.mId)) {
|
||||||
attachment.loadButton.setVisibility(View.VISIBLE);
|
attachment.loadButton.setVisibility(View.VISIBLE);
|
||||||
attachment.cancelButton.setVisibility(View.GONE);
|
attachment.cancelButton.setVisibility(View.GONE);
|
||||||
ProgressBar bar = attachment.progressView;
|
ProgressBar bar = attachment.progressView;
|
||||||
@ -806,15 +765,15 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
* @param attachmentId the attachment that was just downloaded
|
* @param attachmentId the attachment that was just downloaded
|
||||||
*/
|
*/
|
||||||
private void doFinishLoadAttachment(long attachmentId) {
|
private void doFinishLoadAttachment(long attachmentId) {
|
||||||
AttachmentInfo info = findAttachmentInfo(attachmentId);
|
MessageViewAttachmentInfo info = findAttachmentInfo(attachmentId);
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
info.isLoaded = true;
|
info.loaded = true;
|
||||||
|
|
||||||
info.loadButton.setVisibility(View.GONE);
|
info.loadButton.setVisibility(View.GONE);
|
||||||
info.cancelButton.setVisibility(View.GONE);
|
info.cancelButton.setVisibility(View.GONE);
|
||||||
|
|
||||||
boolean showSave = info.allowSave && !TextUtils.isEmpty(info.name);
|
boolean showSave = info.enableSave && !TextUtils.isEmpty(info.mName);
|
||||||
boolean showView = info.allowView;
|
boolean showView = info.enableView;
|
||||||
info.saveButton.setVisibility(showSave ? View.VISIBLE : View.GONE);
|
info.saveButton.setVisibility(showSave ? View.VISIBLE : View.GONE);
|
||||||
info.viewButton.setVisibility(showView ? View.VISIBLE : View.GONE);
|
info.viewButton.setVisibility(showView ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
@ -859,16 +818,16 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
onClickSender();
|
onClickSender();
|
||||||
break;
|
break;
|
||||||
case R.id.load:
|
case R.id.load:
|
||||||
onLoadAttachment((AttachmentInfo) view.getTag());
|
onLoadAttachment((MessageViewAttachmentInfo) view.getTag());
|
||||||
break;
|
break;
|
||||||
case R.id.save:
|
case R.id.save:
|
||||||
onSaveAttachment((AttachmentInfo) view.getTag());
|
onSaveAttachment((MessageViewAttachmentInfo) view.getTag());
|
||||||
break;
|
break;
|
||||||
case R.id.view:
|
case R.id.view:
|
||||||
onViewAttachment((AttachmentInfo) view.getTag());
|
onViewAttachment((MessageViewAttachmentInfo) view.getTag());
|
||||||
break;
|
break;
|
||||||
case R.id.cancel:
|
case R.id.cancel:
|
||||||
onCancelAttachment((AttachmentInfo) view.getTag());
|
onCancelAttachment((MessageViewAttachmentInfo) view.getTag());
|
||||||
break;
|
break;
|
||||||
case R.id.show_message:
|
case R.id.show_message:
|
||||||
setCurrentTab(TAB_MESSAGE);
|
setCurrentTab(TAB_MESSAGE);
|
||||||
@ -1116,7 +1075,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
return BitmapFactory.decodeStream(
|
return BitmapFactory.decodeStream(
|
||||||
mContext.getContentResolver().openInputStream(
|
mContext.getContentResolver().openInputStream(
|
||||||
AttachmentProvider.getAttachmentThumbnailUri(
|
AttachmentProvider.getAttachmentThumbnailUri(
|
||||||
mAccountId, attachment.attachmentId,
|
mAccountId, attachment.mId,
|
||||||
PREVIEW_ICON_WIDTH,
|
PREVIEW_ICON_WIDTH,
|
||||||
PREVIEW_ICON_HEIGHT)));
|
PREVIEW_ICON_HEIGHT)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -1127,8 +1086,9 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
|
|
||||||
private void updateAttachmentThumbnail(long attachmentId) {
|
private void updateAttachmentThumbnail(long attachmentId) {
|
||||||
for (int i = 0, count = mAttachments.getChildCount(); i < count; i++) {
|
for (int i = 0, count = mAttachments.getChildCount(); i < count; i++) {
|
||||||
AttachmentInfo attachment = (AttachmentInfo) mAttachments.getChildAt(i).getTag();
|
MessageViewAttachmentInfo attachment =
|
||||||
if (attachment.attachmentId == attachmentId) {
|
(MessageViewAttachmentInfo) mAttachments.getChildAt(i).getTag();
|
||||||
|
if (attachment.mId == attachmentId) {
|
||||||
Bitmap previewIcon = getPreviewIcon(attachment);
|
Bitmap previewIcon = getPreviewIcon(attachment);
|
||||||
if (previewIcon != null) {
|
if (previewIcon != null) {
|
||||||
attachment.iconView.setImageBitmap(previewIcon);
|
attachment.iconView.setImageBitmap(previewIcon);
|
||||||
@ -1138,21 +1098,37 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclass of AttachmentInfo which includes our views and buttons related to attachment
|
||||||
|
* handling, as well as our determination of suitability for viewing (based on availability of
|
||||||
|
* a viewer app) and saving (based upon the presence of external storage)
|
||||||
|
*/
|
||||||
|
static class MessageViewAttachmentInfo extends AttachmentInfo {
|
||||||
|
Button viewButton;
|
||||||
|
Button saveButton;
|
||||||
|
Button loadButton;
|
||||||
|
Button cancelButton;
|
||||||
|
ImageView iconView;
|
||||||
|
ProgressBar progressView;
|
||||||
|
boolean enableView;
|
||||||
|
boolean enableSave;
|
||||||
|
boolean loaded;
|
||||||
|
|
||||||
|
private MessageViewAttachmentInfo(Context context, Attachment attachment) {
|
||||||
|
super(context, attachment);
|
||||||
|
enableView = mAllowView;
|
||||||
|
enableSave = mAllowSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy data from a cursor-refreshed attachment into the UI. Called from UI thread.
|
* Copy data from a cursor-refreshed attachment into the UI. Called from UI thread.
|
||||||
*
|
*
|
||||||
* @param attachment A single attachment loaded from the provider
|
* @param attachment A single attachment loaded from the provider
|
||||||
*/
|
*/
|
||||||
private void addAttachment(Attachment attachment) {
|
private void addAttachment(Attachment attachment) {
|
||||||
AttachmentInfo attachmentInfo = new AttachmentInfo();
|
MessageViewAttachmentInfo attachmentInfo =
|
||||||
attachmentInfo.size = attachment.mSize;
|
new MessageViewAttachmentInfo(mContext, attachment);
|
||||||
attachmentInfo.contentType =
|
|
||||||
AttachmentProvider.inferMimeType(attachment.mFileName, attachment.mMimeType);
|
|
||||||
attachmentInfo.name = attachment.mFileName;
|
|
||||||
attachmentInfo.attachmentId = attachment.mId;
|
|
||||||
attachmentInfo.allowView = true;
|
|
||||||
attachmentInfo.allowSave = true;
|
|
||||||
attachmentInfo.isLoaded = false;
|
|
||||||
|
|
||||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||||
View view = inflater.inflate(R.layout.message_view_attachment, null);
|
View view = inflater.inflate(R.layout.message_view_attachment, null);
|
||||||
@ -1166,60 +1142,20 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
Button attachmentCancel = (Button)view.findViewById(R.id.cancel);
|
Button attachmentCancel = (Button)view.findViewById(R.id.cancel);
|
||||||
ProgressBar attachmentProgress = (ProgressBar)view.findViewById(R.id.progress);
|
ProgressBar attachmentProgress = (ProgressBar)view.findViewById(R.id.progress);
|
||||||
|
|
||||||
// Check for acceptable / unacceptable attachments by MIME-type
|
// Check whether the attachment already exists
|
||||||
String contentType = attachmentInfo.contentType;
|
if (Utility.attachmentExists(mContext, attachment)) {
|
||||||
if ((!MimeUtility.mimeTypeMatches(contentType, Email.ACCEPTABLE_ATTACHMENT_VIEW_TYPES)) ||
|
attachmentInfo.loaded = true;
|
||||||
(MimeUtility.mimeTypeMatches(contentType, Email.UNACCEPTABLE_ATTACHMENT_VIEW_TYPES))) {
|
|
||||||
attachmentInfo.allowView = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for unacceptable attachments by filename extension; hide both buttons
|
|
||||||
String extension = AttachmentProvider.getFilenameExtension(attachmentInfo.name);
|
|
||||||
if (!TextUtils.isEmpty(extension) &&
|
|
||||||
Utility.arrayContains(Email.UNACCEPTABLE_ATTACHMENT_EXTENSIONS, extension)) {
|
|
||||||
attachmentInfo.allowView = false;
|
|
||||||
attachmentInfo.allowSave = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for installable attachments by filename extension; hide both buttons
|
|
||||||
extension = AttachmentProvider.getFilenameExtension(attachmentInfo.name);
|
|
||||||
if (!TextUtils.isEmpty(extension) &&
|
|
||||||
Utility.arrayContains(Email.INSTALLABLE_ATTACHMENT_EXTENSIONS, extension)) {
|
|
||||||
int sideloadEnabled;
|
|
||||||
sideloadEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
|
|
||||||
Settings.Secure.INSTALL_NON_MARKET_APPS, 0 /* sideload disabled */);
|
|
||||||
// TODO Allow showing an "install" button
|
|
||||||
attachmentInfo.allowView = false;
|
|
||||||
attachmentInfo.allowSave = (sideloadEnabled == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// File size exceeded; Hide both buttons
|
|
||||||
// The size limit is overridden when on a wifi connection - any size is OK
|
|
||||||
if (attachmentInfo.size > Email.MAX_ATTACHMENT_DOWNLOAD_SIZE) {
|
|
||||||
ConnectivityManager cm = (ConnectivityManager)
|
|
||||||
mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
NetworkInfo network = cm.getActiveNetworkInfo();
|
|
||||||
if (network == null || network.getType() != ConnectivityManager.TYPE_WIFI) {
|
|
||||||
attachmentInfo.allowView = false;
|
|
||||||
attachmentInfo.allowSave = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No activity to view the attachment; Hide both buttons
|
|
||||||
if (!isAttachmentViewerInstalled(attachmentInfo)) {
|
|
||||||
attachmentInfo.allowView = false;
|
|
||||||
attachmentInfo.allowSave = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't enable the "save" button if we've got no place to save the file
|
// Don't enable the "save" button if we've got no place to save the file
|
||||||
if (!Utility.isExternalStorageMounted()) {
|
if (!Utility.isExternalStorageMounted()) {
|
||||||
attachmentInfo.allowSave = false;
|
attachmentInfo.enableSave = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attachmentInfo.allowView) {
|
if (!attachmentInfo.enableView) {
|
||||||
attachmentView.setVisibility(View.GONE);
|
attachmentView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if (!attachmentInfo.allowSave) {
|
if (!attachmentInfo.enableSave) {
|
||||||
attachmentSave.setVisibility(View.GONE);
|
attachmentSave.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1230,7 +1166,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
attachmentInfo.iconView = attachmentIcon;
|
attachmentInfo.iconView = attachmentIcon;
|
||||||
attachmentInfo.progressView = attachmentProgress;
|
attachmentInfo.progressView = attachmentProgress;
|
||||||
|
|
||||||
if (!attachmentInfo.allowView && !attachmentInfo.allowSave) {
|
if (!attachmentInfo.enableView && !attachmentInfo.enableSave) {
|
||||||
// This attachment may never be viewed or saved, so block everything
|
// This attachment may never be viewed or saved, so block everything
|
||||||
attachmentProgress.setVisibility(View.GONE);
|
attachmentProgress.setVisibility(View.GONE);
|
||||||
attachmentView.setVisibility(View.GONE);
|
attachmentView.setVisibility(View.GONE);
|
||||||
@ -1238,19 +1174,17 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
attachmentLoad.setVisibility(View.GONE);
|
attachmentLoad.setVisibility(View.GONE);
|
||||||
attachmentCancel.setVisibility(View.GONE);
|
attachmentCancel.setVisibility(View.GONE);
|
||||||
// TODO: Maybe show a little icon to denote blocked download
|
// TODO: Maybe show a little icon to denote blocked download
|
||||||
} else if (Utility.attachmentExists(mContext, attachment)) {
|
} else if (attachmentInfo.loaded) {
|
||||||
// If the attachment is loaded, show 100% progress
|
// If the attachment is loaded, show 100% progress
|
||||||
// Note that for POP3 messages, the user will only see "Open" and "Save",
|
// Note that for POP3 messages, the user will only see "Open" and "Save",
|
||||||
// because the entire message is loaded before being shown.
|
// because the entire message is loaded before being shown.
|
||||||
attachmentInfo.isLoaded = true;
|
|
||||||
|
|
||||||
// Hide "Load", show "View" and "Save"
|
// Hide "Load", show "View" and "Save"
|
||||||
attachmentProgress.setVisibility(View.VISIBLE);
|
attachmentProgress.setVisibility(View.VISIBLE);
|
||||||
attachmentProgress.setProgress(100);
|
attachmentProgress.setProgress(100);
|
||||||
if (attachmentInfo.allowSave) {
|
if (attachmentInfo.enableSave) {
|
||||||
attachmentSave.setVisibility(View.VISIBLE);
|
attachmentSave.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
if (attachmentInfo.allowView) {
|
if (attachmentInfo.enableView) {
|
||||||
attachmentView.setVisibility(View.VISIBLE);
|
attachmentView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
attachmentLoad.setVisibility(View.GONE);
|
attachmentLoad.setVisibility(View.GONE);
|
||||||
@ -1290,23 +1224,13 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
attachmentCancel.setOnClickListener(this);
|
attachmentCancel.setOnClickListener(this);
|
||||||
attachmentCancel.setTag(attachmentInfo);
|
attachmentCancel.setTag(attachmentInfo);
|
||||||
|
|
||||||
attachmentName.setText(attachmentInfo.name);
|
attachmentName.setText(attachmentInfo.mName);
|
||||||
attachmentInfoView.setText(Utility.formatSize(mContext, attachmentInfo.size));
|
attachmentInfoView.setText(Utility.formatSize(mContext, attachmentInfo.mSize));
|
||||||
|
|
||||||
mAttachments.addView(view);
|
mAttachments.addView(view);
|
||||||
mAttachments.setVisibility(View.VISIBLE);
|
mAttachments.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not there is an Activity installed that can handle the given attachment.
|
|
||||||
*/
|
|
||||||
private boolean isAttachmentViewerInstalled(AttachmentInfo info) {
|
|
||||||
Intent intent = getAttachmentIntent(info);
|
|
||||||
PackageManager pm = mContext.getPackageManager();
|
|
||||||
List<ResolveInfo> activityList = pm.queryIntentActivities(intent, 0);
|
|
||||||
return (activityList.size() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload the UI from a provider cursor. {@link LoadMessageTask#onPostExecute} calls it.
|
* Reload the UI from a provider cursor. {@link LoadMessageTask#onPostExecute} calls it.
|
||||||
*
|
*
|
||||||
@ -1488,18 +1412,18 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
private View findAttachmentView(long attachmentId) {
|
private View findAttachmentView(long attachmentId) {
|
||||||
for (int i = 0, count = mAttachments.getChildCount(); i < count; i++) {
|
for (int i = 0, count = mAttachments.getChildCount(); i < count; i++) {
|
||||||
View view = mAttachments.getChildAt(i);
|
View view = mAttachments.getChildAt(i);
|
||||||
AttachmentInfo attachment = (AttachmentInfo) view.getTag();
|
MessageViewAttachmentInfo attachment = (MessageViewAttachmentInfo) view.getTag();
|
||||||
if (attachment.attachmentId == attachmentId) {
|
if (attachment.mId == attachmentId) {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AttachmentInfo findAttachmentInfo(long attachmentId) {
|
private MessageViewAttachmentInfo findAttachmentInfo(long attachmentId) {
|
||||||
View view = findAttachmentView(attachmentId);
|
View view = findAttachmentView(attachmentId);
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
return (AttachmentInfo)view.getTag();
|
return (MessageViewAttachmentInfo)view.getTag();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1566,7 +1490,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AttachmentInfo attachment = findAttachmentInfo(attachmentId);
|
MessageViewAttachmentInfo attachment = findAttachmentInfo(attachmentId);
|
||||||
if (attachment == null) {
|
if (attachment == null) {
|
||||||
// Called before LoadAttachmentsTask finishes.
|
// Called before LoadAttachmentsTask finishes.
|
||||||
// (Possible if you quickly close & re-open a message)
|
// (Possible if you quickly close & re-open a message)
|
||||||
@ -1582,7 +1506,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
} else {
|
} else {
|
||||||
error = mContext.getString(
|
error = mContext.getString(
|
||||||
R.string.message_view_load_attachment_failed_toast,
|
R.string.message_view_load_attachment_failed_toast,
|
||||||
attachment.name);
|
attachment.mName);
|
||||||
}
|
}
|
||||||
mCallback.onLoadMessageError(error);
|
mCallback.onLoadMessageError(error);
|
||||||
}
|
}
|
||||||
@ -1590,7 +1514,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showAttachmentProgress(long attachmentId, int progress) {
|
private void showAttachmentProgress(long attachmentId, int progress) {
|
||||||
AttachmentInfo attachment = findAttachmentInfo(attachmentId);
|
MessageViewAttachmentInfo attachment = findAttachmentInfo(attachmentId);
|
||||||
if (attachment != null) {
|
if (attachment != null) {
|
||||||
ProgressBar bar = attachment.progressView;
|
ProgressBar bar = attachment.progressView;
|
||||||
if (progress == 0) {
|
if (progress == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user