2 * Copyright (C) 2008 ZXing authors
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.google.zxing.client.android;
19 import android.app.Activity;
20 import android.content.Intent;
21 import android.graphics.Bitmap;
22 import android.os.Bundle;
23 import android.os.Handler;
24 import android.os.Message;
25 import android.provider.Contacts;
26 import android.util.Log;
27 import com.google.zxing.BarcodeFormat;
28 import com.google.zxing.MultiFormatWriter;
29 import com.google.zxing.WriterException;
30 import com.google.zxing.common.ByteMatrix;
32 public final class QRCodeEncoder {
34 private static final String TAG = "QRCodeEncoder";
36 private final Activity mActivity;
37 private String mContents;
38 private String mDisplayContents;
39 private String mTitle;
41 public QRCodeEncoder(Activity activity, Intent intent) {
43 if (!encodeContents(intent)) {
44 throw new IllegalArgumentException("No valid data to encode.");
48 public void requestBarcode(Handler handler, int pixelResolution) {
49 Thread encodeThread = new EncodeThread(mContents, handler, pixelResolution);
53 public String getContents() {
57 public String getDisplayContents() {
58 return mDisplayContents;
61 public String getTitle() {
65 // TODO: The string encoding should live in the core ZXing library.
66 private boolean encodeContents(Intent intent) {
67 if (intent == null) return false;
68 String type = intent.getStringExtra(Intents.Encode.TYPE);
69 if (type == null || type.length() == 0) return false;
71 if (type.equals(Contents.Type.TEXT)) {
72 String string = intent.getStringExtra(Intents.Encode.DATA);
73 if (string != null && string.length() > 0) {
75 mDisplayContents = string;
76 mTitle = mActivity.getString(R.string.contents_text);
78 } else if (type.equals(Contents.Type.EMAIL)) {
79 String string = intent.getStringExtra(Intents.Encode.DATA);
80 if (string != null && string.length() > 0) {
81 mContents = "mailto:" + string;
82 mDisplayContents = string;
83 mTitle = mActivity.getString(R.string.contents_email);
85 } else if (type.equals(Contents.Type.PHONE)) {
86 String string = intent.getStringExtra(Intents.Encode.DATA);
87 if (string != null && string.length() > 0) {
88 mContents = "tel:" + string;
89 mDisplayContents = string;
90 mTitle = mActivity.getString(R.string.contents_phone);
92 } else if (type.equals(Contents.Type.SMS)) {
93 String string = intent.getStringExtra(Intents.Encode.DATA);
94 if (string != null && string.length() > 0) {
95 mContents = "sms:" + string;
96 mDisplayContents = string;
97 mTitle = mActivity.getString(R.string.contents_sms);
99 } else if (type.equals(Contents.Type.CONTACT)) {
100 Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
101 if (bundle != null) {
102 String name = bundle.getString(Contacts.Intents.Insert.NAME);
103 if (name != null && name.length() > 0) {
104 mContents = "MECARD:N:" + name + ";";
105 mDisplayContents = name;
106 String address = bundle.getString(Contacts.Intents.Insert.POSTAL);
107 if (address != null && address.length() > 0) {
108 mContents += "ADR:" + address + ";";
109 mDisplayContents += "\n" + address;
111 String phone = bundle.getString(Contacts.Intents.Insert.PHONE);
112 if (phone != null && phone.length() > 0) {
113 mContents += "TEL:" + phone + ";";
114 mDisplayContents += "\n" + phone;
116 String email = bundle.getString(Contacts.Intents.Insert.EMAIL);
117 if (email != null && email.length() > 0) {
118 mContents += "EMAIL:" + email + ";";
119 mDisplayContents += "\n" + email;
122 mTitle = mActivity.getString(R.string.contents_contact);
125 } else if (type.equals(Contents.Type.LOCATION)) {
126 Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
127 if (bundle != null) {
128 float latitude = bundle.getFloat("LAT", Float.MAX_VALUE);
129 float longitude = bundle.getFloat("LONG", Float.MAX_VALUE);
130 if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {
131 mContents = "geo:" + latitude + "," + longitude;
132 mDisplayContents = latitude + "," + longitude;
133 mTitle = mActivity.getString(R.string.contents_location);
137 return mContents != null && mContents.length() > 0;
140 private final static class EncodeThread extends Thread {
142 private final String mContents;
143 private final Handler mHandler;
144 private final int mPixelResolution;
146 public EncodeThread(String contents, Handler handler, int pixelResolution) {
147 mContents = contents;
149 mPixelResolution = pixelResolution;
152 public final void run() {
154 ByteMatrix result = new MultiFormatWriter().encode(mContents, BarcodeFormat.QR_CODE,
155 mPixelResolution, mPixelResolution);
156 int width = result.width();
157 int height = result.height();
158 byte[][] array = result.getArray();
159 int[] pixels = new int[width * height];
160 for (int y = 0; y < height; y++) {
161 for (int x = 0; x < width; x++) {
162 int grey = array[y][x] & 0xff;
163 pixels[y * width + x] = (0xff << 24) | (grey << 16) | (grey << 8) | grey;
167 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
168 bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
169 Message message = Message.obtain(mHandler, R.id.encode_succeeded);
170 message.obj = bitmap;
171 message.sendToTarget();
172 } catch (WriterException e) {
173 Log.e(TAG, e.toString());
174 Message message = Message.obtain(mHandler, R.id.encode_failed);
175 message.sendToTarget();
176 } catch (IllegalArgumentException e) {
177 Log.e(TAG, e.toString());
178 Message message = Message.obtain(mHandler, R.id.encode_failed);
179 message.sendToTarget();