04bca1101f8a1aaff24cb2da44ed76f75093f97e
[zxing.git] / android / src / com / google / zxing / client / android / QRCodeEncoder.java
1 /*
2  * Copyright (C) 2008 ZXing authors
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.google.zxing.client.android;
18
19 import android.app.Activity;
20 import android.content.Intent;
21 import android.graphics.Bitmap;
22 import android.graphics.BitmapFactory;
23 import android.os.Bundle;
24 import android.os.Handler;
25 import android.os.Message;
26 import android.provider.Contacts;
27 import android.util.Log;
28 import org.apache.http.HttpEntity;
29 import org.apache.http.HttpResponse;
30 import org.apache.http.client.methods.HttpGet;
31
32 import java.net.URI;
33
34 public class QRCodeEncoder {
35
36   private static final String TAG = "QRCodeEncoder";
37   private static final String CHART_SERVER_URL = "//chart.apis.google.com/chart?cht=qr&chs=";
38
39   private Activity mActivity;
40   private String mContents;
41   private String mDisplayContents;
42   private String mTitle;
43   private NetworkThread mNetworkThread;
44   private String mUserAgent;
45
46   public QRCodeEncoder(Activity activity, Intent intent) {
47     mActivity = activity;
48     if (!encodeContents(intent)) {
49       throw new IllegalArgumentException("No valid data to encode.");
50     }
51     mUserAgent = mActivity.getString(R.string.zxing_user_agent);
52   }
53
54   // Once the core ZXing library supports encoding, we'll be able to generate the bitmap
55   // synchronously. For now, it's a network request, so it's handled on a thread.
56   public void requestBarcode(Handler handler, int pixelResolution) {
57     mNetworkThread = new NetworkThread(mContents, handler, pixelResolution);
58     mNetworkThread.start();
59   }
60
61   public String getContents() {
62     return mContents;
63   }
64
65   public String getDisplayContents() {
66     return mDisplayContents;
67   }
68
69   public String getTitle() {
70     return mTitle;
71   }
72
73   // Perhaps the string encoding should live in the core ZXing library too.
74   private boolean encodeContents(Intent intent) {
75     if (intent == null) return false;
76     String type = intent.getStringExtra(Intents.Encode.TYPE);
77     if (type == null || type.length() == 0) return false;
78
79     if (type.equals(Contents.Type.TEXT)) {
80       String string = intent.getStringExtra(Intents.Encode.DATA);
81       if (string != null && string.length() > 0) {
82         mContents = string;
83         mDisplayContents = string;
84         mTitle = mActivity.getString(R.string.contents_text);
85       }
86     } else if (type.equals(Contents.Type.EMAIL)) {
87       String string = intent.getStringExtra(Intents.Encode.DATA);
88       if (string != null && string.length() > 0) {
89         mContents = "mailto:" + string;
90         mDisplayContents = string;
91         mTitle = mActivity.getString(R.string.contents_email);
92       }
93     } else if (type.equals(Contents.Type.PHONE)) {
94       String string = intent.getStringExtra(Intents.Encode.DATA);
95       if (string != null && string.length() > 0) {
96         mContents = "tel:" + string;
97         mDisplayContents = string;
98         mTitle = mActivity.getString(R.string.contents_phone);
99       }
100     } else if (type.equals(Contents.Type.SMS)) {
101       String string = intent.getStringExtra(Intents.Encode.DATA);
102       if (string != null && string.length() > 0) {
103         mContents = "sms:" + string;
104         mDisplayContents = string;
105         mTitle = mActivity.getString(R.string.contents_sms);
106       }
107     } else if (type.equals(Contents.Type.CONTACT)) {
108       Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
109       if (bundle != null) {
110         String name = bundle.getString(Contacts.Intents.Insert.NAME);
111         if (name != null && name.length() > 0) {
112           mContents = "MECARD:N:" + name + ";";
113           mDisplayContents = name;
114           String address = bundle.getString(Contacts.Intents.Insert.POSTAL);
115           if (address != null && address.length() > 0) {
116             mContents += "ADR:" + address + ";";
117             mDisplayContents += "\n" + address;
118           }
119           String phone = bundle.getString(Contacts.Intents.Insert.PHONE);
120           if (phone != null && phone.length() > 0) {
121             mContents += "TEL:" + phone + ";";
122             mDisplayContents += "\n" + phone;
123           }
124           String email = bundle.getString(Contacts.Intents.Insert.EMAIL);
125           if (email != null && email.length() > 0) {
126             mContents += "EMAIL:" + email + ";";
127             mDisplayContents += "\n" + email;
128           }
129           mContents += ";";
130           mTitle = mActivity.getString(R.string.contents_contact);
131         }
132       }
133     } else if (type.equals(Contents.Type.LOCATION)) {
134       Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
135       if (bundle != null) {
136         float latitude = bundle.getFloat("LAT", Float.MAX_VALUE);
137         float longitude = bundle.getFloat("LONG", Float.MAX_VALUE);
138         if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {
139           mContents = "geo:" + latitude + "," + longitude;
140           mDisplayContents = latitude + "," + longitude;
141           mTitle = mActivity.getString(R.string.contents_location);
142         }
143       }
144     }
145     return mContents != null && mContents.length() > 0;
146   }
147
148   private class NetworkThread extends Thread {
149
150     private String mContents;
151     private Handler mHandler;
152     private int mPixelResolution;
153
154     public NetworkThread(String contents, Handler handler, int pixelResolution) {
155       mContents = contents;
156       mHandler = handler;
157       mPixelResolution = pixelResolution;
158     }
159
160     public void run() {
161       String url = CHART_SERVER_URL + mPixelResolution + "x" + mPixelResolution + "&chl=" +
162           mContents;
163       AndroidHttpClient client = null;
164       try {
165         URI uri = new URI("http", url, null);
166         HttpGet get = new HttpGet(uri);
167         client = AndroidHttpClient.newInstance(mUserAgent);
168         HttpResponse response = client.execute(get);
169         HttpEntity entity = response.getEntity();
170         Bitmap image = BitmapFactory.decodeStream(entity.getContent());
171         if (image != null) {
172           Message message = Message.obtain(mHandler, R.id.encode_succeeded);
173           message.obj = image;
174           message.sendToTarget();
175         } else {
176           Log.e(TAG, "Could not decode png from the network");
177           Message message = Message.obtain(mHandler, R.id.encode_failed);
178           message.sendToTarget();
179         }
180       } catch (Exception e) {
181         Log.e(TAG, e.toString());
182         Message message = Message.obtain(mHandler, R.id.encode_failed);
183         message.sendToTarget();
184       } finally {
185         if (client != null) {
186           client.close();
187         }
188       }
189     }
190   }
191
192 }