diff --git a/app/src/main/java/protect/card_locker/BarcodeImageWriterTask.java b/app/src/main/java/protect/card_locker/BarcodeImageWriterTask.java new file mode 100644 index 000000000..cd32e0f35 --- /dev/null +++ b/app/src/main/java/protect/card_locker/BarcodeImageWriterTask.java @@ -0,0 +1,91 @@ +package protect.card_locker; + +import android.graphics.Bitmap; +import android.os.AsyncTask; +import android.util.Log; +import android.widget.ImageView; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; + +import java.lang.ref.WeakReference; + +/** + * This task will generate a barcode and load it into an ImageView. + * Only a weak reference of the ImageView is kept, so this class will not + * prevent the ImageView from being garbage collected. + */ +class BarcodeImageWriterTask extends AsyncTask +{ + private static final String TAG = "LoyaltyCardLocker"; + + private final WeakReference imageViewReference; + private final String cardId; + private final BarcodeFormat format; + private final int imageHeight; + private final int imageWidth; + + public BarcodeImageWriterTask(ImageView imageView, String cardIdString, + BarcodeFormat barcodeFormat) + { + // Use a WeakReference to ensure the ImageView can be garbage collected + imageViewReference = new WeakReference<>(imageView); + + cardId = cardIdString; + format = barcodeFormat; + imageHeight = imageView.getHeight(); + imageWidth = imageView.getWidth(); + } + + public Bitmap doInBackground(Void... params) + { + MultiFormatWriter writer = new MultiFormatWriter(); + BitMatrix bitMatrix; + try + { + bitMatrix = writer.encode(cardId, format, imageWidth, imageHeight, null); + + final int WHITE = 0xFFFFFFFF; + final int BLACK = 0xFF000000; + + int bitMatrixWidth = bitMatrix.getWidth(); + int bitMatrixHeight = bitMatrix.getHeight(); + + int[] pixels = new int[bitMatrixWidth * bitMatrixHeight]; + + for (int y = 0; y < bitMatrixHeight; y++) + { + int offset = y * bitMatrixWidth; + for (int x = 0; x < bitMatrixWidth; x++) + { + int color = bitMatrix.get(x, y) ? BLACK : WHITE; + pixels[offset + x] = color; + } + } + Bitmap bitmap = Bitmap.createBitmap(bitMatrixWidth, bitMatrixHeight, + Bitmap.Config.ARGB_8888); + bitmap.setPixels(pixels, 0, bitMatrixWidth, 0, 0, bitMatrixWidth, bitMatrixHeight); + return bitmap; + } + catch (WriterException | IllegalArgumentException e) + { + Log.e(TAG, "Failed to generate barcode", e); + } + + return null; + } + + protected void onPostExecute(Bitmap result) + { + ImageView imageView = imageViewReference.get(); + if(imageView == null) + { + // The ImageView no longer exists, nothing to do + return; + } + + imageView.setImageBitmap(result); + } +} \ No newline at end of file diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index 015a76d7d..3cf30d3ae 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -2,7 +2,6 @@ package protect.card_locker; import android.content.Intent; -import android.graphics.Bitmap; import android.os.Bundle; import android.support.design.widget.Snackbar; import android.support.v7.app.ActionBar; @@ -17,9 +16,6 @@ import android.widget.EditText; import android.widget.ImageView; import com.google.zxing.BarcodeFormat; -import com.google.zxing.MultiFormatWriter; -import com.google.zxing.WriterException; -import com.google.zxing.common.BitMatrix; import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; @@ -149,52 +145,14 @@ public class LoyaltyCardViewActivity extends AppCompatActivity if(cardIdField.getText().length() > 0 && barcodeTypeField.getText().length() > 0) { - MultiFormatWriter writer = new MultiFormatWriter(); - BitMatrix result; - try - { - String formatString = barcodeTypeField.getText().toString(); - BarcodeFormat format = BarcodeFormat.valueOf(formatString); - if(format == null) - { - throw new IllegalArgumentException("Unrecognized barcode format: " + formatString); - } + String formatString = barcodeTypeField.getText().toString(); + final BarcodeFormat format = BarcodeFormat.valueOf(formatString); + final String cardIdString = cardIdField.getText().toString(); - int generateWidth = 100; - int generateHeight = 100; + new BarcodeImageWriterTask(barcodeImage, cardIdString, format).execute(); - String cardIdString = cardIdField.getText().toString(); - - Log.i(TAG, "Card: " + cardIdString); - - result = writer.encode(cardIdString, format, generateWidth, generateHeight, null); - - final int WHITE = 0xFFFFFFFF; - final int BLACK = 0xFF000000; - - int width = result.getWidth(); - int height = result.getHeight(); - int[] pixels = new int[width * height]; - for (int y = 0; y < height; y++) - { - int offset = y * width; - for (int x = 0; x < width; x++) - { - pixels[offset + x] = result.get(x, y) ? BLACK : WHITE; - } - } - Bitmap bitmap = Bitmap.createBitmap(width, height, - Bitmap.Config.ARGB_8888); - bitmap.setPixels(pixels, 0, width, 0, 0, width, height); - barcodeImage.setImageBitmap(bitmap); - - barcodeIdLayout.setVisibility(View.VISIBLE); - barcodeImageLayout.setVisibility(View.VISIBLE); - } - catch (WriterException | IllegalArgumentException e) - { - Log.e(TAG, "Failed to generate barcode", e); - } + barcodeIdLayout.setVisibility(View.VISIBLE); + barcodeImageLayout.setVisibility(View.VISIBLE); } View.OnClickListener captureCallback = new View.OnClickListener() @@ -332,4 +290,4 @@ public class LoyaltyCardViewActivity extends AppCompatActivity } } } -} +} \ No newline at end of file