Merge commit '7cdd6899fbe820af852974cd0b7025b72bfe242a' into kraken * commit '7cdd6899fbe820af852974cd0b7025b72bfe242a': Better handling for untyped attachments
This commit is contained in:
commit
1e037acda7
@ -1004,15 +1004,11 @@ public class MessageView extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
AttachmentInfo attachmentInfo = new AttachmentInfo();
|
AttachmentInfo attachmentInfo = new AttachmentInfo();
|
||||||
attachmentInfo.size = attachment.mSize;
|
attachmentInfo.size = attachment.mSize;
|
||||||
attachmentInfo.contentType = attachment.mMimeType;
|
attachmentInfo.contentType =
|
||||||
|
AttachmentProvider.inferMimeType(attachment.mFileName, attachment.mMimeType);
|
||||||
attachmentInfo.name = attachment.mFileName;
|
attachmentInfo.name = attachment.mFileName;
|
||||||
attachmentInfo.attachmentId = attachment.mId;
|
attachmentInfo.attachmentId = attachment.mId;
|
||||||
|
|
||||||
// TODO: remove this when EAS writes mime types
|
|
||||||
if (attachmentInfo.contentType == null || attachmentInfo.contentType.length() == 0) {
|
|
||||||
attachmentInfo.contentType = "application/octet-stream";
|
|
||||||
}
|
|
||||||
|
|
||||||
LayoutInflater inflater = getLayoutInflater();
|
LayoutInflater inflater = getLayoutInflater();
|
||||||
View view = inflater.inflate(R.layout.message_view_attachment, null);
|
View view = inflater.inflate(R.layout.message_view_attachment, null);
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ import android.graphics.Bitmap;
|
|||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.webkit.MimeTypeMap;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -75,8 +77,12 @@ public class AttachmentProvider extends ContentProvider {
|
|||||||
public static final String SIZE = "_size";
|
public static final String SIZE = "_size";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] PROJECTION_MIME_TYPE = new String[] { AttachmentColumns.MIME_TYPE };
|
private static final String[] MIME_TYPE_PROJECTION = new String[] {
|
||||||
private String[] PROJECTION_QUERY = new String[] { AttachmentColumns.FILENAME,
|
AttachmentColumns.MIME_TYPE, AttachmentColumns.FILENAME };
|
||||||
|
private static final int MIME_TYPE_COLUMN_MIME_TYPE = 0;
|
||||||
|
private static final int MIME_TYPE_COLUMN_FILENAME = 1;
|
||||||
|
|
||||||
|
private static final String[] PROJECTION_QUERY = new String[] { AttachmentColumns.FILENAME,
|
||||||
AttachmentColumns.SIZE, AttachmentColumns.CONTENT_URI };
|
AttachmentColumns.SIZE, AttachmentColumns.CONTENT_URI };
|
||||||
|
|
||||||
public static Uri getAttachmentUri(long accountId, long id) {
|
public static Uri getAttachmentUri(long accountId, long id) {
|
||||||
@ -152,11 +158,14 @@ public class AttachmentProvider extends ContentProvider {
|
|||||||
return "image/png";
|
return "image/png";
|
||||||
} else {
|
} else {
|
||||||
uri = ContentUris.withAppendedId(Attachment.CONTENT_URI, Long.parseLong(id));
|
uri = ContentUris.withAppendedId(Attachment.CONTENT_URI, Long.parseLong(id));
|
||||||
Cursor c = getContext().getContentResolver().query(uri, PROJECTION_MIME_TYPE,
|
Cursor c = getContext().getContentResolver().query(uri, MIME_TYPE_PROJECTION,
|
||||||
null, null, null);
|
null, null, null);
|
||||||
try {
|
try {
|
||||||
if (c.moveToFirst()) {
|
if (c.moveToFirst()) {
|
||||||
return c.getString(0);
|
String mimeType = c.getString(MIME_TYPE_COLUMN_MIME_TYPE);
|
||||||
|
String fileName = c.getString(MIME_TYPE_COLUMN_FILENAME);
|
||||||
|
mimeType = inferMimeType(fileName, mimeType);
|
||||||
|
return mimeType;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.close();
|
c.close();
|
||||||
@ -165,6 +174,48 @@ public class AttachmentProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to convert unknown or unmapped attachments to something useful based on filename
|
||||||
|
* extensions. Imperfect, but helps.
|
||||||
|
*
|
||||||
|
* If the given mime type is non-empty and anything other than "application/octet-stream",
|
||||||
|
* just return it. (This is the most common case.)
|
||||||
|
* If the filename has a recognizable extension and it converts to a mime type, return that.
|
||||||
|
* If the filename has an unrecognized extension, return "application/extension"
|
||||||
|
* Otherwise return "application/octet-stream".
|
||||||
|
*
|
||||||
|
* @param fileName The given filename
|
||||||
|
* @param mimeType The given mime type
|
||||||
|
* @return A likely mime type for the attachment
|
||||||
|
*/
|
||||||
|
public static String inferMimeType(String fileName, String mimeType) {
|
||||||
|
// If the given mime type appears to be non-empty and non-generic - return it
|
||||||
|
if (!TextUtils.isEmpty(mimeType) &&
|
||||||
|
!"application/octet-stream".equalsIgnoreCase(mimeType)) {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find an extension in the filename
|
||||||
|
if (!TextUtils.isEmpty(fileName)) {
|
||||||
|
int lastDot = fileName.lastIndexOf('.');
|
||||||
|
String extension = null;
|
||||||
|
if ((lastDot > 0) && (lastDot < fileName.length() - 1)) {
|
||||||
|
extension = fileName.substring(lastDot + 1).toLowerCase();
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(extension)) {
|
||||||
|
// Extension found. Look up mime type, or synthesize if none found.
|
||||||
|
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||||
|
if (mimeType == null) {
|
||||||
|
mimeType = "application/" + extension;
|
||||||
|
}
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback case - no good guess could be made.
|
||||||
|
return "application/octet-stream";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open an attachment file. There are two "modes" - "raw", which returns an actual file,
|
* Open an attachment file. There are two "modes" - "raw", which returns an actual file,
|
||||||
* and "thumbnail", which attempts to generate a thumbnail image.
|
* and "thumbnail", which attempts to generate a thumbnail image.
|
||||||
|
@ -199,6 +199,9 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
|||||||
long attachment1Id = 1;
|
long attachment1Id = 1;
|
||||||
long attachment2Id = 2;
|
long attachment2Id = 2;
|
||||||
long attachment3Id = 3;
|
long attachment3Id = 3;
|
||||||
|
long attachment4Id = 4;
|
||||||
|
long attachment5Id = 5;
|
||||||
|
long attachment6Id = 6;
|
||||||
|
|
||||||
Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
|
Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
|
||||||
|
|
||||||
@ -223,6 +226,21 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
|||||||
newAttachment3.mMimeType = "text/plain";
|
newAttachment3.mMimeType = "text/plain";
|
||||||
attachment3Id = addAttachmentToDb(account1, newAttachment3);
|
attachment3Id = addAttachmentToDb(account1, newAttachment3);
|
||||||
|
|
||||||
|
Attachment newAttachment4 = ProviderTestUtils.setupAttachment(message1Id, "file4.doc", 100,
|
||||||
|
false, mMockContext);
|
||||||
|
newAttachment4.mMimeType = "application/octet-stream";
|
||||||
|
attachment4Id = addAttachmentToDb(account1, newAttachment4);
|
||||||
|
|
||||||
|
Attachment newAttachment5 = ProviderTestUtils.setupAttachment(message1Id, "file5.xyz", 100,
|
||||||
|
false, mMockContext);
|
||||||
|
newAttachment5.mMimeType = "application/octet-stream";
|
||||||
|
attachment5Id = addAttachmentToDb(account1, newAttachment5);
|
||||||
|
|
||||||
|
Attachment newAttachment6 = ProviderTestUtils.setupAttachment(message1Id, "file6", 100,
|
||||||
|
false, mMockContext);
|
||||||
|
newAttachment6.mMimeType = "";
|
||||||
|
attachment6Id = addAttachmentToDb(account1, newAttachment6);
|
||||||
|
|
||||||
// Check the returned filetypes
|
// Check the returned filetypes
|
||||||
Uri uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
|
Uri uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
|
||||||
type = mMockResolver.getType(uri);
|
type = mMockResolver.getType(uri);
|
||||||
@ -230,6 +248,15 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
|||||||
uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id);
|
uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id);
|
||||||
type = mMockResolver.getType(uri);
|
type = mMockResolver.getType(uri);
|
||||||
assertEquals("text/plain", type);
|
assertEquals("text/plain", type);
|
||||||
|
uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment4Id);
|
||||||
|
type = mMockResolver.getType(uri);
|
||||||
|
assertEquals("application/msword", type);
|
||||||
|
uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment5Id);
|
||||||
|
type = mMockResolver.getType(uri);
|
||||||
|
assertEquals("application/xyz", type);
|
||||||
|
uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment6Id);
|
||||||
|
type = mMockResolver.getType(uri);
|
||||||
|
assertEquals("application/octet-stream", type);
|
||||||
|
|
||||||
// Check the returned filetypes for the thumbnails
|
// Check the returned filetypes for the thumbnails
|
||||||
uri = AttachmentProvider.getAttachmentThumbnailUri(account1.mId, attachment2Id, 62, 62);
|
uri = AttachmentProvider.getAttachmentThumbnailUri(account1.mId, attachment2Id, 62, 62);
|
||||||
@ -240,6 +267,45 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
|||||||
assertEquals("image/png", type);
|
assertEquals("image/png", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test static inferMimeType()
|
||||||
|
* From the method doc:
|
||||||
|
* If the given mime type is non-empty and anything other than "application/octet-stream",
|
||||||
|
* just return it. (This is the most common case.)
|
||||||
|
* If the filename has a recognizable extension and it converts to a mime type, return that.
|
||||||
|
* If the filename has an unrecognized extension, return "application/extension"
|
||||||
|
* Otherwise return "application/octet-stream".
|
||||||
|
*/
|
||||||
|
public void testInferMimeType() {
|
||||||
|
final String DEFAULT = "application/octet-stream";
|
||||||
|
final String FILE_PDF = "myfile.false.pdf";
|
||||||
|
final String FILE_ABC = "myfile.false.abc";
|
||||||
|
final String FILE_NO_EXT = "myfile";
|
||||||
|
|
||||||
|
// If the given mime type is non-empty and anything other than "application/octet-stream",
|
||||||
|
// just return it. (This is the most common case.)
|
||||||
|
assertEquals("mime/type", AttachmentProvider.inferMimeType(null, "mime/type"));
|
||||||
|
assertEquals("mime/type", AttachmentProvider.inferMimeType("", "mime/type"));
|
||||||
|
assertEquals("mime/type", AttachmentProvider.inferMimeType(FILE_PDF, "mime/type"));
|
||||||
|
|
||||||
|
// If the filename has a recognizable extension and it converts to a mime type, return that.
|
||||||
|
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, null));
|
||||||
|
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, ""));
|
||||||
|
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, DEFAULT));
|
||||||
|
|
||||||
|
// If the filename has an unrecognized extension, return "application/extension"
|
||||||
|
assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, null));
|
||||||
|
assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, ""));
|
||||||
|
assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, DEFAULT));
|
||||||
|
|
||||||
|
// Otherwise return "application/octet-stream".
|
||||||
|
assertEquals(DEFAULT, AttachmentProvider.inferMimeType(FILE_NO_EXT, null));
|
||||||
|
assertEquals(DEFAULT, AttachmentProvider.inferMimeType(FILE_NO_EXT, ""));
|
||||||
|
assertEquals(DEFAULT, AttachmentProvider.inferMimeType(FILE_NO_EXT, DEFAULT));
|
||||||
|
assertEquals(DEFAULT, AttachmentProvider.inferMimeType(null, null));
|
||||||
|
assertEquals(DEFAULT, AttachmentProvider.inferMimeType("", ""));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test openFile()
|
* test openFile()
|
||||||
* - regular file
|
* - regular file
|
||||||
|
Loading…
Reference in New Issue
Block a user