diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9a900e199..59b46dad5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -37,6 +37,12 @@ android:theme="@style/AppTheme.NoActionBar" android:configChanges="orientation|screenSize" android:windowSoftInputMode="stateHidden"/> + SUPPORTED_BARCODE_TYPES = Collections.unmodifiableList( + Arrays.asList( + BarcodeFormat.AZTEC.name(), + BarcodeFormat.CODE_39.name(), + BarcodeFormat.CODE_128.name(), + BarcodeFormat.CODABAR.name(), + BarcodeFormat.DATA_MATRIX.name(), + BarcodeFormat.EAN_8.name(), + BarcodeFormat.EAN_13.name(), + BarcodeFormat.ITF.name(), + BarcodeFormat.PDF_417.name(), + BarcodeFormat.QR_CODE.name(), + BarcodeFormat.UPC_A.name() + )); + + private Map barcodeViewMap; + private LinkedList barcodeGeneratorTasks = new LinkedList<>(); + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + setContentView(R.layout.barcode_selector_activity); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + ActionBar actionBar = getSupportActionBar(); + if(actionBar != null) + { + actionBar.setDisplayHomeAsUpEnabled(true); + } + + barcodeViewMap = ImmutableMap.builder() + .put(BarcodeFormat.AZTEC.name(), R.id.aztecBarcode) + .put(BarcodeFormat.CODE_39.name(), R.id.code39Barcode) + .put(BarcodeFormat.CODE_128.name(), R.id.code128Barcode) + .put(BarcodeFormat.CODABAR.name(), R.id.codabarBarcode) + .put(BarcodeFormat.DATA_MATRIX.name(), R.id.datamatrixBarcode) + .put(BarcodeFormat.EAN_8.name(), R.id.ean8Barcode) + .put(BarcodeFormat.EAN_13.name(), R.id.ean13Barcode) + .put(BarcodeFormat.ITF.name(), R.id.itfBarcode) + .put(BarcodeFormat.PDF_417.name(), R.id.pdf417Barcode) + .put(BarcodeFormat.QR_CODE.name(), R.id.qrcodeBarcode) + .put(BarcodeFormat.UPC_A.name(), R.id.upcaBarcode) + .build(); + + EditText cardId = (EditText) findViewById(R.id.cardId); + cardId.addTextChangedListener(new TextWatcher() + { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) + { + // Noting to do + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) + { + Log.d(TAG, "Entered text: " + s); + + // Stop any async tasks which may not have been started yet + for(AsyncTask task : barcodeGeneratorTasks) + { + task.cancel(false); + } + barcodeGeneratorTasks.clear(); + + // Update barcodes + for(String key : barcodeViewMap.keySet()) + { + ImageView image = (ImageView)findViewById(barcodeViewMap.get(key)); + createBarcodeOption(image, key, s.toString()); + } + } + + @Override + public void afterTextChanged(Editable s) + { + // Noting to do + } + }); + } + + private void createBarcodeOption(final ImageView image, final String formatType, final String cardId) + { + final BarcodeFormat format = BarcodeFormat.valueOf(formatType); + if(format == null) + { + Log.w(TAG, "Unsupported barcode format: " + formatType); + return; + } + + image.setImageBitmap(null); + image.setVisibility(View.GONE); + image.setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(View v) + { + Log.d(TAG, "Selected barcode type " + formatType); + Intent result = new Intent(); + result.putExtra(BARCODE_FORMAT, formatType); + result.putExtra(BARCODE_CONTENTS, cardId); + BarcodeSelectorActivity.this.setResult(RESULT_OK, result); + finish(); + } + }); + + if(image.getHeight() == 0) + { + // The size of the ImageView is not yet available as it has not + // yet been drawn. Wait for it to be drawn so the size is available. + image.getViewTreeObserver().addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() + { + @Override + public void onGlobalLayout() + { + Log.d(TAG, "Global layout finished, type: + " + formatType + ", width: " + image.getWidth()); + if (Build.VERSION.SDK_INT < 16) + { + image.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } + else + { + image.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + + Log.d(TAG, "Generating barcode for type " + formatType); + BarcodeImageWriterTask task = new BarcodeImageWriterTask(image, cardId, format); + barcodeGeneratorTasks.add(task); + task.execute(); + } + }); + } + else + { + Log.d(TAG, "Generating barcode for type " + formatType); + BarcodeImageWriterTask task = new BarcodeImageWriterTask(image, cardId, format); + barcodeGeneratorTasks.add(task); + task.execute(); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) + { + if (item.getItemId() == android.R.id.home) + { + setResult(Activity.RESULT_CANCELED); + finish(); + return true; + } + + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index 621f63c9a..3b8f72a9c 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -1,6 +1,7 @@ package protect.card_locker; +import android.app.Activity; import android.content.Intent; import android.os.Build; import android.os.Bundle; @@ -21,31 +22,12 @@ import com.google.zxing.BarcodeFormat; import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; - public class LoyaltyCardViewActivity extends AppCompatActivity { private static final String TAG = "CardLocker"; - // These are all the barcode types that the zxing library - // is able to generate a barcode for, and thus should be - // the only barcodes which we should attempt to scan. - Collection supportedBarcodeTypes = Collections.unmodifiableList(Arrays.asList( - BarcodeFormat.AZTEC.name(), - BarcodeFormat.CODE_39.name(), - BarcodeFormat.CODE_128.name(), - BarcodeFormat.CODABAR.name(), - BarcodeFormat.DATA_MATRIX.name(), - BarcodeFormat.EAN_8.name(), - BarcodeFormat.EAN_13.name(), - BarcodeFormat.ITF.name(), - BarcodeFormat.PDF_417.name(), - BarcodeFormat.QR_CODE.name(), - BarcodeFormat.UPC_A.name() - )); + private static final int SELECT_BARCODE_REQUEST = 1; @Override protected void onCreate(Bundle savedInstanceState) @@ -85,6 +67,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity final View barcodeCaptureLayout = findViewById(R.id.barcodeCaptureLayout); final Button captureButton = (Button) findViewById(R.id.captureButton); + final Button enterButton = (Button) findViewById(R.id.enterButton); final Button saveButton = (Button) findViewById(R.id.saveButton); final Button cancelButton = (Button) findViewById(R.id.cancelButton); @@ -192,7 +175,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity public void onClick(View v) { IntentIntegrator integrator = new IntentIntegrator(LoyaltyCardViewActivity.this); - integrator.setDesiredBarcodeFormats(supportedBarcodeTypes); + integrator.setDesiredBarcodeFormats(BarcodeSelectorActivity.SUPPORTED_BARCODE_TYPES); String prompt = getResources().getString(R.string.scanCardBarcode); integrator.setPrompt(prompt); @@ -202,6 +185,16 @@ public class LoyaltyCardViewActivity extends AppCompatActivity captureButton.setOnClickListener(captureCallback); + enterButton.setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(View v) + { + Intent i = new Intent(getApplicationContext(), BarcodeSelectorActivity.class); + startActivityForResult(i, SELECT_BARCODE_REQUEST); + } + }); + saveButton.setOnClickListener(new View.OnClickListener() { @Override @@ -305,24 +298,37 @@ public class LoyaltyCardViewActivity extends AppCompatActivity @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { + String contents = null; + String format = null; + IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (result != null) { - String contents = result.getContents(); - String format = result.getFormatName(); - if(contents != null && contents.isEmpty() == false && - format != null && format.isEmpty() == false) - { - Log.i(TAG, "Read Contents from scan: " + contents); - Log.i(TAG, "Read Format: " + format); + Log.i(TAG, "Received barcode information from capture"); + contents = result.getContents(); + format = result.getFormatName(); + } - final EditText cardIdField = (EditText) findViewById(R.id.cardId); - cardIdField.setText(contents); - final EditText barcodeTypeField = (EditText) findViewById(R.id.barcodeType); - barcodeTypeField.setText(format); - onResume(); - } + if(requestCode == SELECT_BARCODE_REQUEST && resultCode == Activity.RESULT_OK) + { + Log.i(TAG, "Received barcode information from capture"); + + contents = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_CONTENTS); + format = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_FORMAT); + } + + if(contents != null && contents.isEmpty() == false && + format != null && format.isEmpty() == false) + { + Log.i(TAG, "Read barcode id: " + contents); + Log.i(TAG, "Read format: " + format); + + final EditText cardIdField = (EditText) findViewById(R.id.cardId); + cardIdField.setText(contents); + final EditText barcodeTypeField = (EditText) findViewById(R.id.barcodeType); + barcodeTypeField.setText(format); + onResume(); } } } \ No newline at end of file diff --git a/app/src/main/res/layout/barcode_selector_activity.xml b/app/src/main/res/layout/barcode_selector_activity.xml new file mode 100644 index 000000000..e5884af2e --- /dev/null +++ b/app/src/main/res/layout/barcode_selector_activity.xml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/loyalty_card_view_activity.xml b/app/src/main/res/layout/loyalty_card_view_activity.xml index 13cb6113c..c42b02138 100644 --- a/app/src/main/res/layout/loyalty_card_view_activity.xml +++ b/app/src/main/res/layout/loyalty_card_view_activity.xml @@ -136,6 +136,11 @@ android:layout_height="wrap_content" android:text="@string/capture" android:layout_weight="1.0"/> +