load image previews asynchronously

// FREEBIE
This commit is contained in:
Jake McGinty 2014-12-03 09:25:32 +00:00
parent a88fbba49f
commit 15613894f0
3 changed files with 71 additions and 16 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/gray95"> android:background="@color/gray95">
@ -11,4 +12,24 @@
android:contentDescription="@string/media_preview_activity__image_content_description" android:contentDescription="@string/media_preview_activity__image_content_description"
android:visibility="gone"/> android:visibility="gone"/>
<TextView android:id="@+id/loading_indicator"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:text="···"
android:textSize="30sp"
android:textColor="@color/gray10"
android:visibility="gone"
tools:ignore="HardcodedText" />
<TextView android:id="@+id/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#ff600000"
android:textColor="#ffffffff"
android:textSize="15sp"
android:padding="10dp"
android:visibility="gone" />
</RelativeLayout> </RelativeLayout>

View File

@ -763,6 +763,7 @@
<!-- MediaPreviewActivity --> <!-- MediaPreviewActivity -->
<string name="MediaPreviewActivity_you">You</string> <string name="MediaPreviewActivity_you">You</string>
<string name="MediaPreviewActivity_cant_display">Failed to preview this image</string>
<!-- media_preview --> <!-- media_preview -->
<string name="media_preview__save_title">Save</string> <string name="media_preview__save_title">Save</string>

View File

@ -19,8 +19,10 @@ package org.thoughtcrime.securesms;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.BitmapFactory; import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.opengl.GLES20;
import android.os.AsyncTask;
import android.os.Build.VERSION; import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES; import android.os.Build.VERSION_CODES;
import android.os.Bundle; import android.os.Bundle;
@ -31,12 +33,15 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.providers.PartProvider; import org.thoughtcrime.securesms.providers.PartProvider;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.SaveAttachmentTask; import org.thoughtcrime.securesms.util.SaveAttachmentTask;
@ -61,6 +66,8 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity {
private MasterSecret masterSecret; private MasterSecret masterSecret;
private View loadingView;
private TextView errorText;
private ImageView image; private ImageView image;
private PhotoViewAttacher imageAttacher; private PhotoViewAttacher imageAttacher;
private Uri mediaUri; private Uri mediaUri;
@ -119,18 +126,10 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity {
finish(); finish();
} }
try { Log.w(TAG, "Loading Part URI: " + mediaUri);
Log.w(TAG, "Loading Part URI: " + mediaUri);
final InputStream is = getInputStream(mediaUri, masterSecret); if (mediaType != null && mediaType.startsWith("image/")) {
displayImage();
if (mediaType != null && mediaType.startsWith("image/")) {
displayImage(is);
}
} catch (IOException ioe) {
Log.w(TAG, ioe);
Toast.makeText(getApplicationContext(), "Could not read the media", Toast.LENGTH_LONG).show();
finish();
} }
} }
@ -148,14 +147,48 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity {
} }
private void initializeResources() { private void initializeResources() {
loadingView = findViewById(R.id.loading_indicator);
errorText = (TextView) findViewById(R.id.error);
image = (ImageView) findViewById(R.id.image); image = (ImageView) findViewById(R.id.image);
imageAttacher = new PhotoViewAttacher(image); imageAttacher = new PhotoViewAttacher(image);
} }
private void displayImage(final InputStream is) { private void displayImage() {
image.setImageBitmap(BitmapFactory.decodeStream(is)); new AsyncTask<Void,Void,Bitmap>() {
image.setVisibility(View.VISIBLE); @Override
imageAttacher.update(); protected Bitmap doInBackground(Void... params) {
try {
int[] maxTextureSizeParams = new int[1];
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeParams, 0);
int maxTextureSize = Math.max(maxTextureSizeParams[0], 2048);
Log.w(TAG, "reported GL_MAX_TEXTURE_SIZE: " + maxTextureSize);
return BitmapUtil.createScaledBitmap(getInputStream(mediaUri, masterSecret),
getInputStream(mediaUri, masterSecret),
maxTextureSize, maxTextureSize);
} catch (IOException | BitmapDecodingException e) {
return null;
}
}
@Override
protected void onPreExecute() {
loadingView.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
loadingView.setVisibility(View.GONE);
if (bitmap == null) {
errorText.setText(R.string.MediaPreviewActivity_cant_display);
errorText.setVisibility(View.VISIBLE);
} else {
image.setImageBitmap(bitmap);
image.setVisibility(View.VISIBLE);
imageAttacher.update();
}
}
}.execute();
} }
private void saveToDisk() { private void saveToDisk() {