Mittwoch, 10. September 2014

Mein erstes Mal: Meine (Android-)App kann (EAN-)Codes scannen und verarbeiten! (mit Menu-Exkurs)

Vorweg: Als ich 2010 meine App geschrieben habe, habe ich mein "Menü" programmatisch erzeugt. Beim Codereview habe ich nun entdeckt, dass man zur Erzeugung des Menüs ein XML verwenden kann. Da das in meinen Augen übersichtlicher ist, habe ich meinen Code in ein wiederverwendbares XML umgezogen, das ich aus allen Activities heraus aufrufen kann. Soweit scheint auch noch alles zu funktionieren.

Das Item-Element im menu.xml für den Aufruf des Barcodescanners:
<?xml version="1.0" encoding="utf-8"?>
<menu 
 xmlns:android=
  "http://schemas.android.com/apk/res/android">
  [...]
  <item
    android:id="@+id/menuitem_scan_product"
    android:icon="@drawable/barcode_36"
    android:title="@string/menu_scanProduct"
    android:visible="false">
  </item>
</menu>

Dieses XML rufe ich in der onCreateOptionsMenu auf:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
  MenuInflater menuInflater = getMenuInflater();
  menuInflater.inflate(R.menu.menu, menu);
  return true;
}

In der onPrepareOptionsMenu blende ich den Menüeintrag ein (mein XML hat natürlich mehrere Items, die ich je nach Activity einblenden kann):
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
  final boolean scanAvailable 
    = FreeOffUtils.isIntentAvailable(context,
      "com.google.zxing.client.android.SCAN");

  MenuItem item = menu.findItem(R.id.menuitem_scan_product);
  item.setVisible(true);
  item.setEnabled(scanAvailable);
  
  return super.onPrepareOptionsMenu(menu);
}

Vorsichtshalber deaktiviere ich den Menüeintrag mit setEnabled(scanAvailable), wenn auf dem Smartphone kein entsprechendes Programm installiert ist:
public static boolean isIntentAvailable(Context context, 
 String action) {
  final PackageManager packageManager 
    = context.getPackageManager();
  final Intent intent = new Intent(action);

  List<resolveinfo> list 
    = packageManager.queryIntentActivities(intent,
      PackageManager.MATCH_DEFAULT_ONLY);

  return list.size() > 0;
}

In onOptionsItemSelected wird der Aufruf verarbeitet:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
  Intent intent;

  switch (item.getItemId()) {
  case R.id.menuitem_scan_product:
    intent = new Intent("com.google.zxing.client.android.SCAN");
    intent
      .putExtra("com.google.zxing.client.android.SCAN.SCAN_MODE",
        "QR_CODE_MODE");
    this.startActivityForResult(intent, 0);
    break;
  [...]
}

Wichtig ist hier der Aufruf startActivityForResult(intent, 0), da die Scan-Activity nach "getaner Arbeit" onActivityResult der Activity aufruft, von der aus sie gestartet wurde. So kann hier der eingelesene EAN Code verarbeitet werden:
@Override
public void onActivityResult(int requestCode, int resultCode, 
 Intent intent) {
  if (requestCode == 0) {
    if (resultCode == Activity.RESULT_OK) {
      String contents 
        = intent.getStringExtra("SCAN_RESULT");
      String format 
        = intent.getStringExtra("SCAN_RESULT_FORMAT");
      [...]
    }
  } 
}

Der requestCode entspricht hier der 0, die im Aufruf startActivityForResult übergeben wurde.

Beim ersten Aufruf muss man eine entsprechende App auswählen.


Wie immer kann man sich entscheiden, diese auch zukünftig für diesen Vorgang verwenden zu wollen - oder jedes Mal wieder "frisch" zu wählen.


Schon öffnet sich der Scanner:


Und - mit entsprechendem Code "dahinter" - wird das Produkt gefunden:



Keine Kommentare:

Kommentar veröffentlichen

Hinweis: Nur ein Mitglied dieses Blogs kann Kommentare posten.