Support audio attachments through GalleryMediaChooser am: 2716c26c23 am: 3359f4dee2
Change-Id: I3dd27f67c3cba49c84d7e50e579ca62d0121087d
This commit is contained in:
@@ -21,12 +21,67 @@
|
||||
android:background="@color/gallery_image_default_background"
|
||||
android:clickable="true">
|
||||
|
||||
<!-- Thumbnail for image and video contents. -->
|
||||
<com.android.messaging.ui.AsyncImageView
|
||||
android:id="@+id/image"
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<!-- Additional info such as icon, name and etc. -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/additional_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone" >
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@id/file_info" >
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/gallery_icon_size"
|
||||
android:layout_height="@dimen/gallery_icon_size"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="fitCenter"
|
||||
android:background="@color/background_item_transparent"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
|
||||
<!-- File info for audio contents only -->
|
||||
<LinearLayout
|
||||
android:id="@+id/file_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_type"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="right"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Caption" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -44,13 +99,4 @@
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/gallery_checkbox_content_description" />
|
||||
|
||||
<!-- Play button image for video contents only -->
|
||||
<ImageView
|
||||
android:id="@+id/video_thumbnail_play_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@color/background_item_transparent"
|
||||
android:src="@drawable/ic_video_play_light"
|
||||
android:visibility="gone" />
|
||||
</com.android.messaging.ui.mediapicker.GalleryGridItemView>
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
<!-- Flings faster than this length / sec will go from fullscreen straight to closed -->
|
||||
<dimen name="mediapicker_big_fling_threshold">1000dp</dimen>
|
||||
<dimen name="gallery_image_cell_size">110dp</dimen>
|
||||
<dimen name="gallery_icon_size">40dp</dimen>
|
||||
<dimen name="single_attachment_min_dimen">50dp</dimen>
|
||||
<dimen name="single_attachment_max_height">150dp</dimen>
|
||||
<dimen name="multiple_attachment_preview_height">130dp</dimen>
|
||||
|
||||
@@ -35,7 +35,11 @@ public class GalleryBoundCursorLoader extends BoundCursorLoader {
|
||||
private static final String SORT_ORDER = MediaColumns.DATE_MODIFIED + " DESC";
|
||||
private static final String SELECTION = createSelection(
|
||||
MessagePartData.ACCEPTABLE_GALLERY_MEDIA_TYPES,
|
||||
new Integer[] {FileColumns.MEDIA_TYPE_IMAGE, FileColumns.MEDIA_TYPE_VIDEO});
|
||||
new Integer[] {
|
||||
FileColumns.MEDIA_TYPE_IMAGE,
|
||||
FileColumns.MEDIA_TYPE_VIDEO,
|
||||
FileColumns.MEDIA_TYPE_AUDIO
|
||||
});
|
||||
|
||||
public GalleryBoundCursorLoader(final String bindingId, final Context context) {
|
||||
super(bindingId, context, STORAGE_URI, GalleryGridItemData.MEDIA_PROJECTION, SELECTION,
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.android.messaging.datamodel.media.UriImageRequestDescriptor;
|
||||
import com.android.messaging.datamodel.media.VideoThumbnailRequestDescriptor;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.ContentType;
|
||||
import com.android.messaging.util.UriUtil;
|
||||
|
||||
/**
|
||||
* Provides data for GalleryGridItemView
|
||||
@@ -40,7 +41,8 @@ public class GalleryGridItemData {
|
||||
MediaColumns.WIDTH,
|
||||
MediaColumns.HEIGHT,
|
||||
MediaColumns.MIME_TYPE,
|
||||
MediaColumns.DATE_MODIFIED};
|
||||
MediaColumns.DATE_MODIFIED,
|
||||
MediaColumns.DISPLAY_NAME};
|
||||
|
||||
public static final String[] SPECIAL_ITEM_COLUMNS = new String[] {
|
||||
BaseColumns._ID
|
||||
@@ -54,6 +56,7 @@ public class GalleryGridItemData {
|
||||
private static final int INDEX_HEIGHT = 3;
|
||||
private static final int INDEX_MIME_TYPE = 4;
|
||||
private static final int INDEX_DATE_MODIFIED = 5;
|
||||
private static final int INDEX_DISPLAY_NAME = 6;
|
||||
|
||||
/** A special item's id for picking a media from document picker */
|
||||
public static final String ID_DOCUMENT_PICKER_ITEM = "-1";
|
||||
@@ -62,6 +65,8 @@ public class GalleryGridItemData {
|
||||
private String mContentType;
|
||||
private boolean mIsDocumentPickerItem;
|
||||
private long mDateSeconds;
|
||||
private String mFileName;
|
||||
private Uri mAudioUri;
|
||||
|
||||
public GalleryGridItemData() {
|
||||
}
|
||||
@@ -73,37 +78,44 @@ public class GalleryGridItemData {
|
||||
mImageData = null;
|
||||
mContentType = null;
|
||||
} else {
|
||||
int sourceWidth = cursor.getInt(INDEX_WIDTH);
|
||||
int sourceHeight = cursor.getInt(INDEX_HEIGHT);
|
||||
|
||||
// Guard against bad data
|
||||
if (sourceWidth <= 0) {
|
||||
sourceWidth = ImageRequest.UNSPECIFIED_SIZE;
|
||||
}
|
||||
if (sourceHeight <= 0) {
|
||||
sourceHeight = ImageRequest.UNSPECIFIED_SIZE;
|
||||
}
|
||||
|
||||
mContentType = cursor.getString(INDEX_MIME_TYPE);
|
||||
final String filePath = cursor.getString(INDEX_DATA_PATH);
|
||||
final String dateModified = cursor.getString(INDEX_DATE_MODIFIED);
|
||||
mDateSeconds = !TextUtils.isEmpty(dateModified) ? Long.parseLong(dateModified) : -1;
|
||||
if (ContentType.isVideoType(mContentType)) {
|
||||
mImageData = new VideoThumbnailRequestDescriptor(
|
||||
cursor.getLong(INDEX_ID),
|
||||
desiredWidth,
|
||||
desiredHeight,
|
||||
sourceWidth,
|
||||
sourceHeight);
|
||||
} else {
|
||||
mImageData = new FileImageRequestDescriptor(
|
||||
cursor.getString(INDEX_DATA_PATH),
|
||||
desiredWidth,
|
||||
desiredHeight,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
true /* canUseThumbnail */,
|
||||
true /* allowCompression */,
|
||||
true /* isStatic */);
|
||||
if (ContentType.isAudioType(mContentType)) {
|
||||
mImageData = null;
|
||||
mAudioUri = UriUtil.getUriForResourceFile(filePath);
|
||||
mFileName = cursor.getString(INDEX_DISPLAY_NAME);
|
||||
} else { // For image and video types
|
||||
int sourceWidth = cursor.getInt(INDEX_WIDTH);
|
||||
int sourceHeight = cursor.getInt(INDEX_HEIGHT);
|
||||
|
||||
// Guard against bad data
|
||||
if (sourceWidth <= 0) {
|
||||
sourceWidth = ImageRequest.UNSPECIFIED_SIZE;
|
||||
}
|
||||
if (sourceHeight <= 0) {
|
||||
sourceHeight = ImageRequest.UNSPECIFIED_SIZE;
|
||||
}
|
||||
|
||||
if (ContentType.isVideoType(mContentType)) {
|
||||
mImageData = new VideoThumbnailRequestDescriptor(
|
||||
cursor.getLong(INDEX_ID),
|
||||
desiredWidth,
|
||||
desiredHeight,
|
||||
sourceWidth,
|
||||
sourceHeight);
|
||||
} else {
|
||||
mImageData = new FileImageRequestDescriptor(
|
||||
filePath,
|
||||
desiredWidth,
|
||||
desiredHeight,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
true /* canUseThumbnail */,
|
||||
true /* allowCompression */,
|
||||
true /* isStatic */);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +125,7 @@ public class GalleryGridItemData {
|
||||
}
|
||||
|
||||
public Uri getImageUri() {
|
||||
return mImageData.uri;
|
||||
return ContentType.isAudioType(mContentType) ? mAudioUri : mImageData.uri;
|
||||
}
|
||||
|
||||
public UriImageRequestDescriptor getImageRequestDescriptor() {
|
||||
@@ -122,8 +134,10 @@ public class GalleryGridItemData {
|
||||
|
||||
public MessagePartData constructMessagePartData(final Rect startRect) {
|
||||
Assert.isTrue(!mIsDocumentPickerItem);
|
||||
return new MediaPickerMessagePartData(startRect, mContentType,
|
||||
mImageData.uri, mImageData.sourceWidth, mImageData.sourceHeight);
|
||||
return ContentType.isAudioType(mContentType)
|
||||
? new MediaPickerMessagePartData(startRect, mContentType, mAudioUri, 0, 0)
|
||||
: new MediaPickerMessagePartData(startRect, mContentType, mImageData.uri,
|
||||
mImageData.sourceWidth, mImageData.sourceHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,4 +150,8 @@ public class GalleryGridItemData {
|
||||
public String getContentType() {
|
||||
return mContentType;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return mFileName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,12 @@ public class MessagePartData implements Parcelable {
|
||||
// Acceptable video types
|
||||
ContentType.VIDEO_3GP, ContentType.VIDEO_3GPP, ContentType.VIDEO_3G2,
|
||||
ContentType.VIDEO_H263, ContentType.VIDEO_M4V, ContentType.VIDEO_MP4,
|
||||
ContentType.VIDEO_MPEG, ContentType.VIDEO_MPEG4, ContentType.VIDEO_WEBM
|
||||
ContentType.VIDEO_MPEG, ContentType.VIDEO_MPEG4, ContentType.VIDEO_WEBM,
|
||||
// Acceptable audio types
|
||||
ContentType.AUDIO_MP3, ContentType.AUDIO_MP4, ContentType.AUDIO_MIDI,
|
||||
ContentType.AUDIO_MID, ContentType.AUDIO_AMR, ContentType.AUDIO_X_WAV,
|
||||
ContentType.AUDIO_AAC, ContentType.AUDIO_X_MIDI, ContentType.AUDIO_X_MID,
|
||||
ContentType.AUDIO_X_MP3
|
||||
};
|
||||
|
||||
private static final String[] sProjection = {
|
||||
|
||||
@@ -30,7 +30,7 @@ import com.android.messaging.util.ImageUtils;
|
||||
import com.android.messaging.util.SafeAsyncTask;
|
||||
|
||||
/**
|
||||
* Wraps around the functionalities to allow the user to pick an image/video from the document
|
||||
* Wraps around the functionalities to allow the user to pick an image/video/audio from the document
|
||||
* picker. Instances of this class must be tied to a Fragment which is able to delegate activity
|
||||
* result callbacks.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.messaging.ui.mediapicker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
@@ -25,6 +26,9 @@ import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
@@ -54,6 +58,11 @@ public class GalleryGridItemView extends FrameLayout {
|
||||
GalleryGridItemData mData;
|
||||
private AsyncImageView mImageView;
|
||||
private CheckBox mCheckBox;
|
||||
private RelativeLayout mAdditionalInfo;
|
||||
private ImageView mIcon;
|
||||
private LinearLayout mFileInfo;
|
||||
private TextView mFileName;
|
||||
private TextView mFileType;
|
||||
private HostInterface mHostInterface;
|
||||
private final OnClickListener mOnClickListener = new OnClickListener() {
|
||||
@Override
|
||||
@@ -70,9 +79,14 @@ public class GalleryGridItemView extends FrameLayout {
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mImageView = (AsyncImageView) findViewById(R.id.image);
|
||||
mImageView = (AsyncImageView) findViewById(R.id.thumbnail);
|
||||
mCheckBox = (CheckBox) findViewById(R.id.checkbox);
|
||||
mCheckBox.setOnClickListener(mOnClickListener);
|
||||
mAdditionalInfo = (RelativeLayout) findViewById(R.id.additional_info);
|
||||
mIcon = (ImageView) findViewById(R.id.icon);
|
||||
mFileInfo = (LinearLayout) findViewById(R.id.file_info);
|
||||
mFileName = (TextView) findViewById(R.id.file_name);
|
||||
mFileType = (TextView) findViewById(R.id.file_type);
|
||||
setOnClickListener(mOnClickListener);
|
||||
final OnLongClickListener longClickListener = new OnLongClickListener() {
|
||||
@Override
|
||||
@@ -136,32 +150,59 @@ public class GalleryGridItemView extends FrameLayout {
|
||||
}
|
||||
|
||||
private void updateImageView() {
|
||||
ImageView playButton = (ImageView) findViewById(R.id.video_thumbnail_play_button);
|
||||
if (mData.isDocumentPickerItem()) {
|
||||
mImageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
setBackgroundColor(ConversationDrawables.get().getConversationThemeColor());
|
||||
mImageView.setImageResourceId(null);
|
||||
mImageView.setImageResource(R.drawable.ic_photo_library_light);
|
||||
playButton.setVisibility(GONE);
|
||||
mImageView.setContentDescription(getResources().getString(
|
||||
R.string.pick_image_from_document_library_content_description));
|
||||
mIcon.setImageResource(R.drawable.ic_photo_library_light);
|
||||
mIcon.clearColorFilter();
|
||||
mImageView.setVisibility(GONE);
|
||||
mIcon.setVisibility(VISIBLE);
|
||||
mFileInfo.setVisibility(GONE);
|
||||
mAdditionalInfo.setVisibility(VISIBLE);
|
||||
} else {
|
||||
mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
setBackgroundColor(getResources().getColor(R.color.gallery_image_default_background));
|
||||
mImageView.setImageResourceId(mData.getImageRequestDescriptor());
|
||||
if (ContentType.isVideoType(mData.getContentType())) {
|
||||
playButton.setVisibility(VISIBLE);
|
||||
} else {
|
||||
playButton.setVisibility(GONE);
|
||||
final String contentType = mData.getContentType();
|
||||
if (ContentType.isAudioType(contentType)) {
|
||||
final Context context = getContext();
|
||||
setBackgroundColor(
|
||||
getResources().getColor(R.color.gallery_image_default_background));
|
||||
mIcon.setImageDrawable(
|
||||
context.getContentResolver()
|
||||
.getTypeInfo(contentType)
|
||||
.getIcon()
|
||||
.loadDrawable(context));
|
||||
mIcon.setColorFilter(
|
||||
ConversationDrawables.get().getConversationThemeColor(),
|
||||
PorterDuff.Mode.SRC_IN);
|
||||
mFileName.setText(mData.getFileName());
|
||||
String[] type = contentType.split("/");
|
||||
mFileType.setText(type[1].toUpperCase() + " " + type[0]);
|
||||
mImageView.setVisibility(GONE);
|
||||
mIcon.setVisibility(VISIBLE);
|
||||
mFileInfo.setVisibility(VISIBLE);
|
||||
mAdditionalInfo.setVisibility(VISIBLE);
|
||||
} else { // For image and video types
|
||||
mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
setBackgroundColor(
|
||||
getResources().getColor(R.color.gallery_image_default_background));
|
||||
mImageView.setImageResourceId(mData.getImageRequestDescriptor());
|
||||
mImageView.setVisibility(VISIBLE);
|
||||
if (ContentType.isVideoType(mData.getContentType())) {
|
||||
mIcon.setImageResource(R.drawable.ic_video_play_light);
|
||||
mIcon.clearColorFilter();
|
||||
mIcon.setVisibility(VISIBLE);
|
||||
} else {
|
||||
mIcon.setVisibility(GONE);
|
||||
}
|
||||
mFileInfo.setVisibility(GONE);
|
||||
mAdditionalInfo.setVisibility(VISIBLE);
|
||||
final long dateSeconds = mData.getDateSeconds();
|
||||
final boolean isValidDate = (dateSeconds > 0);
|
||||
final int templateId = isValidDate ?
|
||||
R.string.mediapicker_gallery_image_item_description :
|
||||
R.string.mediapicker_gallery_image_item_description_no_date;
|
||||
String contentDescription = String.format(getResources().getString(templateId),
|
||||
dateSeconds * TimeUnit.SECONDS.toMillis(1));
|
||||
mImageView.setContentDescription(contentDescription);
|
||||
}
|
||||
final long dateSeconds = mData.getDateSeconds();
|
||||
final boolean isValidDate = (dateSeconds > 0);
|
||||
final int templateId = isValidDate ?
|
||||
R.string.mediapicker_gallery_image_item_description :
|
||||
R.string.mediapicker_gallery_image_item_description_no_date;
|
||||
String contentDescription = String.format(getResources().getString(templateId),
|
||||
dateSeconds * TimeUnit.SECONDS.toMillis(1));
|
||||
mImageView.setContentDescription(contentDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.OsUtil;
|
||||
|
||||
/**
|
||||
* Chooser which allows the user to select one or more existing images or videos
|
||||
* Chooser which allows the user to select one or more existing images or videos or audios.
|
||||
*/
|
||||
class GalleryMediaChooser extends MediaChooser implements
|
||||
GalleryGridView.GalleryGridViewListener, MediaPickerDataListener {
|
||||
@@ -54,7 +54,9 @@ class GalleryMediaChooser extends MediaChooser implements
|
||||
|
||||
@Override
|
||||
public int getSupportedMediaTypes() {
|
||||
return MediaPicker.MEDIA_TYPE_IMAGE | MediaPicker.MEDIA_TYPE_VIDEO;
|
||||
return (MediaPicker.MEDIA_TYPE_IMAGE
|
||||
| MediaPicker.MEDIA_TYPE_VIDEO
|
||||
| MediaPicker.MEDIA_TYPE_AUDIO);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -55,7 +55,7 @@ public class GalleryGridItemViewTest extends ViewTest<GalleryGridItemView> {
|
||||
final String imageUrl,
|
||||
final boolean showCheckbox,
|
||||
final boolean isSelected) {
|
||||
final AsyncImageView imageView = (AsyncImageView) view.findViewById(R.id.image);
|
||||
final AsyncImageView imageView = (AsyncImageView) view.findViewById(R.id.thumbnail);
|
||||
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
|
||||
|
||||
assertNotNull(imageView);
|
||||
|
||||
Reference in New Issue
Block a user