カテゴリー
コンピューター

【Android】zxing-android-embedded を使って QR コードアプリチュートリアル♪

環境

  • Mac OS X Yosemite 10.10.3
  • Android Studio 1.2.1.1
  • Nexus 9

1.Android Studio のプロジェクトへの zxing-android-embedded ライブラリインポートと QR コードカメラの起動の確認

1−1.build.gradle (Module: app)

build.gradle (Module: app) に次を追加し、Sync Project with Gradle Files を実行します。

repositories {
    jcenter()
}

dependencies {
    compile 'com.journeyapps:zxing-android-embedded:3.0.0@aar'
    compile 'com.google.zxing:core:3.2.0'
}

マニュフェストファイル AndroidManifest.xml への変更はありませんでした。これは意外に感じましたわ。と言うのは、Android アプリでカメラアプリを作るときには <uses-permission android:name=”android.permission.CAMERA” /> と記述するのが基本と思っていたからですの。

1−2.MainActivity.java

続いて、MainActivity.java です。

onCreate メソッドに、new IntentIntegrator(this).initiateScan(); を加えて次のようにしました。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new IntentIntegrator(this).initiateScan();
    }

1−3.アプリの起動、QR カメラの確認

この状態でアプリを実行(Run ‘app’)しますと、次のように動きました。

  • アプリ起動と同時にカメラが起動した。
  • カメラは QR コード読み取りバージョンになっていた。
    • 中央にバーコードを合わせるガイド線
    • バーコード読み取りエリア外は灰色で縁取り
    • 「QRコードを画面の読み取り範囲内に写すとスキャンします」の説明書き
  • バーコード(QR コードに加え、通常のバーコードも読めた)を読み取るとカメラが終了し、activity_main.xml のレイアウトが表示された。デフォルトのままのため、空の画面に「Hello world!」と表示
  • 画面を回転させると、onCreate が実行され、QR コードカメラが起動した。

new IntentIntegrator(this).initiateScan(); と書くだけで、バーコードの読み取りと、カメラの起動元のアクティビティに戻って来ました。

zxing-android-embedded はよく練られているライブラリと感じますわ♪

なお、ここまで次のページが参考になりました。ありがとう存じます♪

1−4.おまけ。 build.gradle (Module: app) 全体

なお、build.gradle (Module: app) の全体はこのようになりました。

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "com.example.zxingtest1"
        minSdkVersion 15
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

repositories {
    jcenter()
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.1.1'

    compile 'com.journeyapps:zxing-android-embedded:3.0.0@aar'
    compile 'com.google.zxing:core:3.2.0'
}

2.QR コードを読み取り、画面に表示する簡単なアプリを作ります♪

動きとしては、次のような簡単なアプリですわ。

  • ボタンを押して QR コードカメラを起動
  • バーコードを読み取ったら元の画面に戻り、読み取り情報を表示する。

コーディング作業はものすごく短く、拍子抜けしました!MainActivity.java と、activity_main.xml を少し修正しただけですの。

MainActivity.java

  • MainActivity#onCreate で、ボタンを取得して、タップした時に QR カメラを起動する動作をイベントリスナーに登録
  • onActivityResult をオーバーライドし、その中で IntentResult#getContents を使ってバーコードの情報を取り出して表示

onCreate と onActivityResult のみ記述と思いましたが、クラスの内容をすべて載せますわね。

package com.example.zxingtest1;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;


public class MainActivity extends ActionBarActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate Start");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ボタンを取得し、タップした時の動作を指定
        Button buttonStartCamera = (Button) findViewById(R.id.buttonStartCamera);
        buttonStartCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "buttonStartCamera onClick Start");
                new IntentIntegrator(MainActivity.this).initiateScan();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult Start");
        Log.d(TAG, "requestCode: " + requestCode + " resultCode: " + resultCode + " data: " + data);
        IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        // 奇妙なことに null の場合
        if (intentResult == null) {
            Log.d(TAG, "Weird");
            super.onActivityResult(requestCode, resultCode, data);
            return;
        }

        if (intentResult.getContents() == null) {
            // 戻るボタンをタップした場合
            Log.d(TAG, "Cancelled Scan");

        } else {
            // カメラで読み取った情報をラベルに表示
            Log.d(TAG, "Scanned");
            TextView textViewScannedData = (TextView) findViewById(R.id.textViewScannedData);
            textViewScannedData.setText(intentResult.getContents());
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

activity_main.xml

こちらでは、次の2つを置いただけですの。

  • タップした時に QR カメラを起動するためのボタン
  • QR カメラで読み取ったデータを表示するためのテキストビュー
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="カメラを起動"
        android:id="@+id/buttonStartCamera" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="読み取った情報を表示します。"
        android:id="@+id/textViewScannedData"/>

</LinearLayout>

おわりに

以前、ZXing Android Embedded を勉強して、zxing を Android Studio で使うまでのメモ♪ | oki2a24 では README.md を読み解いてインポート方法の最初の一歩を確かめました。

今回は、実際に通常のバーコードや QR コードを読み取るカメラを起動し、読み取ったらアクティビティに戻ってデータを取得するところまで実践いたしました。

これで QR コードを読み取る Android アプリを作る基礎がかたまりましたの♪

想像以上に簡単で本当に拍子抜けいたしました。

といいますのも、

を拝見しますと、ライブラリとして jar ファイルを取得してディレクトリに置いて。。。それはまだ少し面倒ですけれども良いとして、リンク先のページに jar ファイルが置いておらずどうしたらよいかわかりませんでした><。他に、ソースコードではカメラの実装もしております。

調べれば調べるほどずいぶんと身につけることが多いと感じておりました。ですので実際に書いてみますとその実装量の少なさに驚きました!

ちなみに、上記のページでは(QR コードではない)通常のバーコードの読み取り精度がイマイチとありました。

わたくしが今回試したところ、精度で気になったことはありませんでしたので、きっとバージョンアップで読み取り精度もパワーアップしたのだと存じます。

また、次のページでは今回の投稿と同様の内容が紹介されておりますが、ひとつ気になったことがございます。

こちらのページでは、ZXing Android Embedded ではなく、ZXing 本体の IntentIntegrator.java と IntentResult.java を使って実現した、と書かれていることです。

今回の投稿内容を実現するには、ZXing のみでよいのかしら?ZXing Android Embedded は不要なのかしら?気になりましたの。

以上です。

コメントを残す