From 61d2f525f1dfb8312903dca92813e68ef2b380c4 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Fri, 8 Apr 2016 17:43:54 +0100 Subject: [PATCH] Fragment may have no activity when callbacks occur. --- .../keyagreement/ShowQrCodeFragment.java | 64 +++++++++++-------- .../android/util/QrCodeUtils.java | 49 ++++++-------- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java index c21c2dd6e1..22d5ad4750 100644 --- a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java +++ b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java @@ -5,10 +5,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.graphics.Bitmap; import android.hardware.Camera; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; import android.util.Base64; import android.view.Display; import android.view.LayoutInflater; @@ -21,6 +23,7 @@ import android.widget.TextView; import android.widget.Toast; import com.google.zxing.Result; +import com.google.zxing.WriterException; import org.briarproject.R; import org.briarproject.android.AndroidComponent; @@ -50,6 +53,7 @@ import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.EXTRA_STATE; import static android.bluetooth.BluetoothAdapter.STATE_ON; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; +import static android.view.View.GONE; import static android.widget.LinearLayout.HORIZONTAL; import static android.widget.LinearLayout.VERTICAL; import static android.widget.Toast.LENGTH_LONG; @@ -220,19 +224,22 @@ public class ShowQrCodeFragment extends BaseEventFragment @Override protected void onPostExecute(Camera camera) { - if (camera == null) { - Toast.makeText(getActivity(), - R.string.could_not_open_camera, - LENGTH_LONG).show(); - getActivity().finish(); - } else { - cameraView.start(camera, decoder, 0); - } + if (camera == null) + showToastAndFinish(R.string.could_not_open_camera); + else cameraView.start(camera, decoder, 0); } }; openTask.execute(); } + private void showToastAndFinish(int resid) { + FragmentActivity fa = getActivity(); + if (fa != null) { + Toast.makeText(fa, resid, LENGTH_LONG).show(); + fa.finish(); + } + } + private void releaseCamera() { LOG.info("Releasing camera"); try { @@ -245,15 +252,16 @@ public class ShowQrCodeFragment extends BaseEventFragment private void qrCodeScanned(String content) { try { // TODO use Base32 - Payload remotePayload = payloadParser.parse( - Base64.decode(content, 0)); - cameraView.setVisibility(View.GONE); + byte[] payloadBytes = Base64.decode(content, 0); + Payload remotePayload = payloadParser.parse(payloadBytes); + cameraView.setVisibility(GONE); status.setText(R.string.connecting_to_device); task.connectAndRunProtocol(remotePayload); + } catch (IllegalArgumentException e) { + // Thrown by Base64.decode() if incorrectly padded + showToastAndFinish(R.string.qr_code_invalid); } catch (IOException e) { - Toast.makeText(getActivity(), R.string.qr_code_invalid, - LENGTH_LONG).show(); - getActivity().finish(); + showToastAndFinish(R.string.qr_code_invalid); } } @@ -278,14 +286,22 @@ public class ShowQrCodeFragment extends BaseEventFragment @Override public void run() { // TODO use Base32 - String input = Base64.encodeToString( - payloadEncoder.encode(localPayload), 0); - qrCode.setImageBitmap( - QrCodeUtils.createQrCode(getActivity(), input)); - // Simple fade-in animation - AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f); - anim.setDuration(200); - qrCode.startAnimation(anim); + byte[] payloadBytes = payloadEncoder.encode(localPayload); + String base64 = Base64.encodeToString(payloadBytes, 0); + // The fragment may no longer belong to an activity + FragmentActivity fa = getActivity(); + if (fa == null) return; + try { + Bitmap bitmap = QrCodeUtils.createQrCode(fa, base64); + qrCode.setImageBitmap(bitmap); + // Simple fade-in animation + AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f); + anim.setDuration(200); + qrCode.startAnimation(anim); + } catch (WriterException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } } }); } @@ -294,9 +310,7 @@ public class ShowQrCodeFragment extends BaseEventFragment listener.runOnUiThread(new Runnable() { @Override public void run() { - Toast.makeText(getActivity(), R.string.connection_failed, - LENGTH_LONG).show(); - getActivity().finish(); + showToastAndFinish(R.string.connection_failed); } }); } diff --git a/briar-android/src/org/briarproject/android/util/QrCodeUtils.java b/briar-android/src/org/briarproject/android/util/QrCodeUtils.java index ef8ff6ec67..cb62d90be7 100644 --- a/briar-android/src/org/briarproject/android/util/QrCodeUtils.java +++ b/briar-android/src/org/briarproject/android/util/QrCodeUtils.java @@ -2,50 +2,39 @@ package org.briarproject.android.util; import android.app.Activity; import android.graphics.Bitmap; -import android.graphics.Color; import android.util.DisplayMetrics; -import com.google.zxing.BarcodeFormat; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; -import java.util.logging.Logger; - -import static java.util.logging.Level.WARNING; +import static android.graphics.Bitmap.Config.ARGB_8888; +import static android.graphics.Color.BLACK; +import static android.graphics.Color.WHITE; +import static com.google.zxing.BarcodeFormat.QR_CODE; public class QrCodeUtils { - private static final Logger LOG = - Logger.getLogger(QrCodeUtils.class.getName()); - - public static Bitmap createQrCode(Activity activity, String input) { + public static Bitmap createQrCode(Activity activity, String input) + throws WriterException { // Get narrowest screen dimension DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); int smallestDimen = Math.min(dm.widthPixels, dm.heightPixels); - try { - // Generate QR code - final BitMatrix encoded = new QRCodeWriter().encode( - input, BarcodeFormat.QR_CODE, smallestDimen, smallestDimen); - // Convert QR code to Bitmap - int width = encoded.getWidth(); - int height = encoded.getHeight(); - int[] pixels = new int[width * height]; - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - pixels[y * width + x] = - encoded.get(x, y) ? Color.BLACK : Color.WHITE; - } + // Generate QR code + BitMatrix encoded = new QRCodeWriter().encode(input, QR_CODE, + smallestDimen, smallestDimen); + // Convert QR code to Bitmap + int width = encoded.getWidth(); + int height = encoded.getHeight(); + int[] pixels = new int[width * height]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + pixels[y * width + x] = encoded.get(x, y) ? BLACK : WHITE; } - Bitmap qr = Bitmap.createBitmap(width, height, - Bitmap.Config.ARGB_8888); - qr.setPixels(pixels, 0, width, 0, 0, width, height); - return qr; - } catch (WriterException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - return null; } + Bitmap qr = Bitmap.createBitmap(width, height, ARGB_8888); + qr.setPixels(pixels, 0, width, 0, 0, width, height); + return qr; } } -- GitLab