Gerando QRCode com C# e lendo com Android

É muito comum vermos QRCodes por aí, então vamos aprender como gerá-los com C# e lê-los por um app Android.

Bora?

Biblioteca ZXing

Em ambas plataformas, farei o uso do ZXing, que é uma biblioteca de processamento de códigos de barras 1D ou 2D.

Inicialmente escrita em Java, foi portada para várias linguagens, inclusive o .NET.

Como a ZXing é apenas uma biblioteca de processamento de imagens, teríamos que ter o app Barcode Scanner no celular, mas como o objetivo é deixar o leitor de QRCode embutido, irei usar uma biblioteca escrita pela Journey Apps que permite este comportamento.

Geração do QRCode

Para gerar o QRCode, vamos criar um projeto C# do tipo WinForms e instalar o ZXing pelo terminal do NuGet.

PM> Install-Package ZXing.Net
Installing 'ZXing.Net 0.14.0.1'.
Successfully installed 'ZXing.Net 0.14.0.1'.
Adding 'ZXing.Net 0.14.0.1' to ExemploQRCode.
Successfully added 'ZXing.Net 0.14.0.1' to ExemploQRCode.

Agora vamos ao formulário:

No botão Gerar o código é bem simples:

BarcodeWriter writer = new BarcodeWriter();
writer.Format = BarcodeFormat.QR_CODE;
writer.Options = new EncodingOptions()
{
	Width = imgQrCode.Width,
	Height = imgQrCode.Height,
	Margin = 2
};

imgQrCode.Image = new Bitmap(writer.Write(txtMensagem.Text));

Usando a classe BarcodeWriter, informamos apenas o formato (QRCode), largura, altura e margem, o resto é com a ZXing.

Abaixo uma imagem do QRCode gerado.

No C# já terminamos, vamos para o Android.

Leitura do QRCode

Irei assumir que você esteja usando o Android Studio, pois farei uso inclusive do Gradle.

Após criar um projeto em branco, precisamos configurar o arquivo build.gradle dentro da pasta app do projeto criado pelo Android Studio. Dentro do grupo dependencies, coloque as seguintes linhas:

compile 'com.google.zxing:core:3.2.1'
compile 'com.journeyapps:zxing-android-embedded:3.0.3@aar'

A primeira diz que iremos utilizar a ZXing versão 3.2.1. Já a segunda linha, diz que iremos usar a biblioteca feita pela Journey Apps que nos dará a possibilidade de embutir o leitor de QRCode em nosso aplicativo.

Feito isso, o Android Studio irá solicitar que faça o Gradle Sync, que nada mais é do que fazer o download das novas dependências e prepará-las para usarmos.

Para nossa activity, não precisamos de muita coisa, apenas um botão e um EditText para exibir o conteúdo do QRCode:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <Button
        android:id="@+id/btn_escanear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Escanear" />

    <TextView
        android:id="@+id/lbl_resultado"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_escanear"
        android:layout_centerHorizontal="true"
        android:text="Resultado" />

</RelativeLayout>

Na classe da activity (MainActivity.java), obtemos o botão pelo ID dele (R.id.btn_escanear) e atribuimos o evento OnClick:

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

	Button btnEscanear = (Button) findViewById(R.id.btn_escanear);
	btnEscanear.setOnClickListener(new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			IntentIntegrator integrator = new IntentIntegrator(MainActivity.this);
			integrator.initiateScan();
		}
	});
}

Note que fazemos o uso da classe IntentIntegrador, que faz o papel de chamar o Intent da câmera, ler o QRCode e nos dar o resultado através do método onActivityResult, que vamos programá-lo adiante.

A classe IntentIntegrator também nos fornece um método chamado parseActivityResult, que trata se o resultado é de uma leitura de QRCode (pode acontecer de você tratar vários tipos de resultados na mesma Activity) e converte o conteúdo do QRCode numa string.

Então vamos implementar o método onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);

	if (result != null) {
		TextView lblResultado = (TextView) findViewById(R.id.lbl_resultado);
		lblResultado.setText(result.getContents());
	}
}

Prontinho, agora só rodar e ser feliz.

Para quem quiser, criei um projeto no GitHub com o projeto do C# e do Android.

Até mais.