Ler e Gerar QR-Code usando a BlackBerry API
Bom dia!
Hoje vamos conhecer a API utilizada para manipulação de QR-Codes na BlackBerry API. Portanto, após a leitura deste post, você estará apto a desenvolver uma aplicação que leia e gere códigos de barras bi-dimensionais (QR-Code).
O código a seguir foi baseado no tutorial de PBernhardt publicado na Comunidade de Suporte BlackBerry.
O código é de fácil entendimento e está todo comentado. Quaisquer dúvidas, entre em contato conosco através da sessão de comentários deste post ou pelo email blackberrydevgroup@gmail.com . Ficaremos felizes em poder auxiliá-lo.
Siga-nos no Twitter: @BlackberryDevBR
Bons estudos!!!
—–
package mypackage;
import java.util.Hashtable;
import java.util.Vector;
import net.rim.blackberry.api.browser.Browser;
import net.rim.blackberry.api.browser.BrowserSession;
import net.rim.device.api.barcodelib.BarcodeBitmap;
import net.rim.device.api.barcodelib.BarcodeDecoder;
import net.rim.device.api.barcodelib.BarcodeDecoderListener;
import net.rim.device.api.barcodelib.BarcodeScanner;
import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.KeyListener;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Keypad;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.XYEdges;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.FullScreen;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.decor.BorderFactory;
import net.rim.device.api.ui.toolbar.ToolbarButtonField;
import net.rim.device.api.ui.toolbar.ToolbarManager;
import net.rim.device.api.util.StringProvider;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.encoder.Encoder;
import com.google.zxing.qrcode.encoder.QRCode;
/***
* Barcode API Sample
*
* Esta aplicação demonstra o uso mais comum da API de código de barras: 1)
* Criar e exibir um código QR, 2) Digitalização de um código QR e abrir o browser
* apontando para essa URL. Poderia ser facilmente modificado para fazer a varredura / criar
* outros tipos de códigos de barras, ou fazer outras coisas com o código de barras digitalizado / criado.
*
* Tradução: @BlackBerryDevBR
*
* @author PBernhardt
*
*
*/
001. public class BarcodeAPISample extends UiApplication {
002.
003. //Isto controla o tamanho do código de barras.
004. private static final int BARCODE_WIDTH = 300;
005.
006. // O aplicativo em sí
007. private static BarcodeAPISample _app;
008.
009. // Erros serão registrados aqui, será um log de erros.
010. private LabelField _logField;
011.
012. // A tela principal que sustenta a barra de ferramentas e código de barras exibido.
013. private MainScreen _mainScreen;
014.
015. // O código de barras é mostrado aqui.
016. private BitmapField _barcodeField;
017.
018. // O texto armazenado aqui será convertido em QR-Code para ser apresentado ao usuário.
019. private EditField _barcodeTextField;
020.
021. // Este controla scanneia o código de barras.
022. private BarcodeScanner _scanner;
023.
024. // Essa tela é onde o viewfinder ou o scanner de código de barras é exibido.
025. private FullScreen _barcodeScreen;
026.
027. public BarcodeAPISample() {
028. // Nova tela
029. _mainScreen = new MainScreen();
030.
031. // Criar o campo de log para ser utilizado no construtor.
032. _logField = new LabelField(“Log: “);
033.
034. // Cria-se o local para a imagem de código de barras e adicioná-la à tela principal
035. _barcodeField = new BitmapField(new Bitmap(BARCODE_WIDTH, BARCODE_WIDTH), Field.FIELD_HCENTER);
036. _barcodeField.setBorder(BorderFactory.createBevelBorder(new XYEdges(2, 2, 2, 2)));
037. _mainScreen.add(_barcodeField);
038.
039. // Cria-se e adiciona-se o campo que armazenará o conteúdo do código de barras.
040. _barcodeTextField = new EditField(“Texto do QR-Code: “, “http://blackberrygroup.wordpress.com”);
041. _mainScreen.add(_barcodeTextField);
042.
043. // Adiciona-se os botões “Gerar Código” e “Scannear”.
044. /**
045. * Este é um exemplo rápido dos novos pacotes (em 6.0)
046. * net.rim.device.api.command e net.rim.device.api.ui.toolbar.
047. * Tudo que faz é chamar a displayBarcode () ou scanBarcode ()
048. * ao clicar no botão correspondente. Para mais detalhes sobre este pacote,
049. * consulte o JavaDocs ou em outro local do Centro de Recursos do desenvolvedor.
050. *
051. * Tradução: @BlackBerryDevBR
052. *
053. */
054. ToolbarManager toolbar = new ToolbarManager();
055.
056. ToolbarButtonField displayBarcodeToolbarButtonField = new ToolbarButtonField(new StringProvider(“Gerar Código”));
057. displayBarcodeToolbarButtonField.setCommand(new Command(new CommandHandler() {
058. public void execute(ReadOnlyCommandMetadata arg0, Object arg1) {
059. displayBarcode();
060. }
061. }));
062. toolbar.add(displayBarcodeToolbarButtonField);
063.
064. ToolbarButtonField scanBarcodeToolbarButtonField = new ToolbarButtonField(new StringProvider(“Scannear”));
065. scanBarcodeToolbarButtonField.setCommand(new Command(new CommandHandler() {
066. public void execute(ReadOnlyCommandMetadata arg0, Object arg1) {
067. scanBarcode();
068.
069. }
070. }));
071. toolbar.add(scanBarcodeToolbarButtonField);
072.
073. _mainScreen.setToolbar(toolbar);
074.
075. // Adiciona o campo log ao “fundo”.
076. _mainScreen.add(_logField);
077.
078. pushScreen(_mainScreen);
079. }
080.
081. // Cria-se o aplicativo e dispara seus eventos utilizando o eventDispatcher().
082. public static void main(String[] args) {
083. _app = new BarcodeAPISample();
084. _app.enterEventDispatcher();
085.
086. }
087.
088. /**
089. * displayBarcode
090. *
091. * Este método receberá o texto do _barcodeTextField e o
092. * converterá em QR-Code, para então exibi-lo na tela.
093. *
094. * Tradução: @BlackBerryDevBR
095. */
096. private void displayBarcode() {
097. try {
098. QRCode qrCode = new QRCode();
099.
100. // Aqui o texto é codificado com um nível baixo (7%) de correção de erros.
101. Encoder.encode(_barcodeTextField.getText(), ErrorCorrectionLevel.L, qrCode);
102.
103. // Aqui é montada a matriz de dados e em seguida convertida em bitmap.
104. ByteMatrix barcode = qrCode.getMatrix();
105. Bitmap bitmap = BarcodeBitmap.createBitmap(barcode, BARCODE_WIDTH);
106.
107. _barcodeField.setBitmap(bitmap);
108.
109. } catch (Exception e) {
110. log(“Exception: ” + e);
111. }
112. }
113.
114. private void scanBarcode() {
115. // Aqui é montar o scanner de código de barras. É feito um teste para
116. // verificar se nenhum código de barras foi digitalizado anteriormente.
117. if (_barcodeScreen == null) {
118.
119. // Primeiro criamos uma hashtable para manter
120. // todas as dicas que podemos dar a API sobre como queremos
121. // digitalizar um código de barras para então
122. // melhorar a velocidade e precisão do scanner.
123. Hashtable hints = new Hashtable();
124.
125. // Adicionamos o primeiro formato ao vetor “formats”.
126. // Poderíamos adicionar mais de um formato, mas seria muito mais lento.
127. Vector formats = new Vector();
128. formats.addElement(BarcodeFormat.QR_CODE);
129. hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
130.
131. // Também usaremos a bandeira “TRY_HARDER” para nos certificarmos
132. // de que obteremos uma digitalização precisa.
133. hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
134.
135. // Criamos um novo decodificador usando as dicas.
136. BarcodeDecoder decoder = new BarcodeDecoder(hints);
137.
138. // Finalmente, podemos criar o scanner real com um decodificador e
139. // um ouvinte que vai lidar com os dados armazenados no código de barras.
140. // Então nós colocamos na nossa tela.
141. try {
142. _scanner = new BarcodeScanner(decoder, new MyBarcodeDecoderListener());
143. _barcodeScreen = new MyBarcodeScannerViewScreen(_scanner);
144.
145. } catch (Exception e) {
146. log(“Não foi possível inicializar scanner de código de barras: ” + e);
147. return;
148. }
149. }
150.
151. // Ao chegarmos aqui, toda a infra-estrutura do código de
152. // barras deve ser criada, então tudo o que temos a fazer
153. // é começar a digitalizar e exibir o na tela.
154. try {
155. _scanner.startScan();
156. _app.pushScreen(_barcodeScreen);
157. } catch (Exception e) {
158. log(“Não foi possível iniciar scanneamento: ” + e);
159. }
160.
161. }
162.
163. /***
164. * MyBarcodeDecoderListener
165. *
166. * Esta implementação, BarcodeDecoverListener, tenta abrir todos os
167. * dados codificados em um código de barras no navegador.
168. *
169. * Tradução: @BlackBerryDevBR
170. *
171. * @author PBernhardt
172. *
173. **/
174. private class MyBarcodeDecoderListener implements BarcodeDecoderListener {
175.
176. public void barcodeDecoded(final String rawText) {
177.
178. // Primeiro, daremos um pop na tela para remove-la da pilha
179. // para podermos ver o aplicativo principal.
180. _app.invokeLater(new Runnable() {
181. public void run() {
182. _app.popScreen(_barcodeScreen);
183.
184. }
185. });
186.
187. // Vamos usar um StringBuffer para criar a nossa mensagem fazendo a concatenação de Strings.
188. final StringBuffer message = new StringBuffer(“Gostaria de abrir o conteúdo \”");
189. message.append(rawText);
190. message.append(“\” no navegador?”);
191. log(message.toString());
192. _barcodeScreen.invalidate();
193.
194. // Aqui é questionado ao usuário se ele pretende abrir no browser a URL digitalizada.
195. _app.invokeLater(new Runnable() {
196. public void run() {
197. if (Dialog.ask(Dialog.D_YES_NO, message.toString()) == Dialog.YES) {
198.
199. // Aqui é obtido o sessionBrowserSession padrão.
200. BrowserSession browserSession = Browser.getDefaultSession();
201. // Abre-se a URL obtida anteriormente.
202. browserSession.displayPage(rawText);
203. }
204. }
205. });
206. }
207.
208. }
209.
210. /***
211. * MyBarcodeScannerViewScreen
212. *
213. * Esta tela de visualização é simplesmente uma extensão de MainScreen
214. * que irá apresentar nosso scanner na tela e, se o usuário decidir abortar
215. * o scanneamento, poderá pará-lo através do botão voltar.
216. *
217. * Tradução: @BlackBerryDevBR
218. *
219. * @author PBernhardt
220. *
221. */
222. private class MyBarcodeScannerViewScreen extends MainScreen {
223.
224. public MyBarcodeScannerViewScreen(BarcodeScanner scanner) {
225. super();
226. try {
227. // Obtem o visor e o adiciona à tela.
228. _scanner.getVideoControl().setDisplayFullScreen(true);
229. Field viewFinder = _scanner.getViewfinder();
230. this.add(viewFinder);
231.
232. // Criar e adicionar nosso ouvinte chave para a tela.
233. this.addKeyListener(new MyKeyListener());
234.
235. } catch (Exception e) {
236. log(“Erro ao criar a tela de exibição: ” + e);
237. }
238.
239. }
240.
241. /***
242. * MyKeyListener
243. *
244. * Este KeyListener vai parar a digitalização atual
245. * quando o botão for pressionado, e depois colocar a tela na pilha.
246. *
247. * Tradução: @BlackBerryDevBR
248. *
249. * @author PBernhardt
250. *
251. */
252. private class MyKeyListener implements KeyListener {
253.
254. public boolean keyDown(int keycode, int time) {
255.
256. // Primeiro converter o código de acesso em um evento chave,
257. // levando em conta seus modificadores.
258. int key = Keypad.key(keycode);
259.
260. // A partir daí, podemos verificar a tecla “escape”.
261. // Com isso, podemos parar o scan e dar um pop na tela
262. // para remove-la da pilha.
263. if (key == Keypad.KEY_ESCAPE) {
264. try {
265. _scanner.stopScan();
266. } catch (Exception e) {
267. log(“Erro ao parar o scanneamento: ” + e);
268. }
269. _app.invokeLater(new Runnable() {
270. public void run() {
271. _app.popScreen(_barcodeScreen);
272.
273. }
274. });
275.
276. return true;
277.
278. }
279. // Caso contrário, vamos retornar false para não consumir o evento keyDown.
280. return false;
281. }
282.
283. // Iremos atuar apenas com o evento keyDown.
284. public boolean keyChar(char key, int status, int time) {
285. return false;
286. }
287.
288. public boolean keyRepeat(int keycode, int time) {
289. return false;
290. }
291.
292. public boolean keyStatus(int keycode, int time) {
293. return false;
294. }
295.
296. public boolean keyUp(int keycode, int time) {
297. return false;
298. }
299.
300. }
301. }
302.
303. public void log(final String msg) {
304. invokeLater(new Runnable() {
305. public void run() {
306. _logField.setText(_logField.getText() + “\n” + msg);
307. System.out.println(msg);
308. }
309. });
400. }
401.}