diff --git a/Android/AccountList/AccountList.java b/Android/AccountList/AccountList.java
index 3e54ebc7..8bde72df 100644
--- a/Android/AccountList/AccountList.java
+++ b/Android/AccountList/AccountList.java
@@ -7,6 +7,7 @@
import android.accounts.Account;
import android.accounts.AccountManager;
+import org.apache.cordova.DroidGap;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
@@ -18,7 +19,7 @@ public PluginResult execute(String action, JSONArray args, String callbackId) {
try {
JSONObject obj = args.getJSONObject(0);
- AccountManager am = AccountManager.get(this.ctx.getContext());
+ AccountManager am = AccountManager.get(cordova.getActivity());
Account[] accounts;
if (obj.has("type"))
diff --git a/Android/AccountList/accountlist.js b/Android/AccountList/accountlist.js
index 388a6c59..e6d7a493 100644
--- a/Android/AccountList/accountlist.js
+++ b/Android/AccountList/accountlist.js
@@ -1,13 +1,23 @@
-var AccountList = function() {};
-
-AccountList.prototype.get = function(params, success, fail) {
- return PhoneGap.exec( function(args) {
- success(args);
- }, function(args) {
- fail(args);
- }, 'AccountList', '', [params]);
-};
+var AccountList = function(gap) {
-PhoneGap.addConstructor(function() {
- PhoneGap.addPlugin('AccountList', new AccountList());
-});
\ No newline at end of file
+ AccountList.prototype.get = function(params, success, fail) {
+ return gap.exec( function(args) {
+ success(args);
+ }, function(args) {
+ fail(args);
+ }, 'AccountList', '', [params]);
+ };
+
+ gap.addConstructor(function () {
+ if (gap.addPlugin) {
+ gap.addPlugin("AccountList", new AccountList());
+ } else {
+ if (!window.plugins) {
+ window.plugins = {};
+ }
+
+ window.plugins.ccountList = new AccountList();
+ }
+ });
+
+})(window.cordova || window.Cordova || window.PhoneGap);
diff --git a/Android/ActionBarSherlockTabBar/REPO MOVED.txt b/Android/ActionBarSherlockTabBar/REPO MOVED.txt
new file mode 100644
index 00000000..ededc5b1
--- /dev/null
+++ b/Android/ActionBarSherlockTabBar/REPO MOVED.txt
@@ -0,0 +1 @@
+This plugin is now located at https://github.com/AndiDog/phonegap-android-actionbarsherlock-tabbar-plugin
\ No newline at end of file
diff --git a/Android/Analytics/2.0/README.md b/Android/Analytics/2.0/README.md
index 2398f064..21306e32 100644
--- a/Android/Analytics/2.0/README.md
+++ b/Android/Analytics/2.0/README.md
@@ -30,7 +30,7 @@ Using this plugin requires [PhoneGap Cordova library for Android](http://phonega
5. In your res/xml/config.xml file add the following line:
-
+ <plugin name="GoogleAnalyticsTracker" value="com.phonegap.plugins.analytics.GoogleAnalyticsTracker" />
## Using the plugin ##
@@ -86,7 +86,25 @@ Sample use:
Sample use:
window.plugins.analytics.trackEvent("category", "action", "event", 1, function(){alert("Track: success");}, function(){alert("Track: failure");});
+
+
+/**
+ * Set a custom variable on Google Analytics
+ * @param index The slot for the custom variable
+ * @param label The name for the custom variable
+ * @param value The value for the custom variable
+ * @param scope The scope for the custom variable (optional)
+
+ * @param successCallback The success callback
+ * @param failureCallback The error callback
+ */
+
+ setCustomVar(index, label, value, scope, successCallback, failureCallback);
+
+
+Sample use:
+ window.plugins.analytics.setCustomVar(1, "type", "android", null, function(){alert("SetVar: success");}, function(){alert("SetVar: failure");});
Please keep in mind that these methods, as in any other plugin, are ready to be invoked only after '[deviceready](http://docs.phonegap.com/phonegap_events_events.md.html#deviceready)' event has been fired
Good practice will be manual dispatch and stop session. Add this code to your main activity:
diff --git a/Android/Analytics/2.0/src/com/phonegap/plugins/analytics/GoogleAnalyticsTracker.java b/Android/Analytics/2.0/src/com/phonegap/plugins/analytics/GoogleAnalyticsTracker.java
index 4697f60f..c700844d 100644
--- a/Android/Analytics/2.0/src/com/phonegap/plugins/analytics/GoogleAnalyticsTracker.java
+++ b/Android/Analytics/2.0/src/com/phonegap/plugins/analytics/GoogleAnalyticsTracker.java
@@ -55,6 +55,7 @@ public PluginResult execute(String action, JSONArray data, String callbackId) {
} else if (SET_CUSTOM_VARIABLE.equals(action)){
try {
setCustomVar(data.getInt(0), data.getString(1), data.getString(2), data.getInt(3));
+ result = new PluginResult(Status.OK);
} catch (JSONException e) {
result = new PluginResult(Status.JSON_EXCEPTION);
}
@@ -77,6 +78,7 @@ private void trackEvent(String category, String action, String label, int value)
}
private void setCustomVar(int index, String label, String value, int scope) {
- tracker.setCustomVar(index, label, value, scope);
+ if(scope > 0) tracker.setCustomVar(index, label, value, scope);
+ else tracker.setCustomVar(index, label, value);
}
}
\ No newline at end of file
diff --git a/Android/Analytics/2.0/www/analytics.js b/Android/Analytics/2.0/www/analytics.js
index 0e415641..8c31841c 100644
--- a/Android/Analytics/2.0/www/analytics.js
+++ b/Android/Analytics/2.0/www/analytics.js
@@ -68,6 +68,17 @@ Analytics.prototype.trackEvent = function(category, action, label, value, succes
]);
};
+/**
+ * Set a custom variable on Google Analytics
+ * @param index The slot for the custom variable
+ * @param label The name for the custom variable
+ * @param value The value for the custom variable
+ * @param scope The scope for the custom variable (optional)
+
+ * @param successCallback The success callback
+ * @param failureCallback The error callback
+ */
+
Analytics.prototype.setCustomVar = function(index, label, value, scope, successCallback, failureCallback){
return cordova.exec(
successCallback,
diff --git a/Android/AppPreferences/1.8.1/assets/www/applicationPreferences.js b/Android/AppPreferences/1.8.1/assets/www/applicationPreferences.js
deleted file mode 100644
index 05b9ae3a..00000000
--- a/Android/AppPreferences/1.8.1/assets/www/applicationPreferences.js
+++ /dev/null
@@ -1,29 +0,0 @@
-var AppPreferences = function () {};
-
-var AppPreferencesError = function(code, message) {
- this.code = code || null;
- this.message = message || '';
-};
-
-AppPreferencesError.NO_PROPERTY = 0;
-AppPreferencesError.NO_PREFERENCE_ACTIVITY = 1;
-
-AppPreferences.prototype.get = function(key,success,fail) {
- cordova.exec(success,fail,"applicationPreferences","get",[key]);
-};
-
-AppPreferences.prototype.set = function(key,value,success,fail) {
- cordova.exec(success,fail,"applicationPreferences","set",[key, value]);
-};
-
-AppPreferences.prototype.load = function(success,fail) {
- cordova.exec(success,fail,"applicationPreferences","load",[]);
-};
-
-AppPreferences.prototype.show = function(activity,success,fail) {
- cordova.exec(success,fail,"applicationPreferences","show",[activity]);
-};
-
-cordova.addConstructor(function() {
- cordova.addPlugin("applicationPreferences", new AppPreferences());
-});
\ No newline at end of file
diff --git a/Android/AppPreferences/1.8.1/src/com/simonmacdonald/prefs/AppPreferences.java b/Android/AppPreferences/1.8.1/src/com/simonmacdonald/prefs/AppPreferences.java
deleted file mode 100644
index de63d4a5..00000000
--- a/Android/AppPreferences/1.8.1/src/com/simonmacdonald/prefs/AppPreferences.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.simonmacdonald.prefs;
-
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.cordova.api.Plugin;
-import org.apache.cordova.api.PluginResult;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-public class AppPreferences extends Plugin {
-
- private static final String LOG_TAG = "AppPrefs";
- private static final int NO_PROPERTY = 0;
- private static final int NO_PREFERENCE_ACTIVITY = 1;
-
- @Override
- public PluginResult execute(String action, JSONArray args, String callbackId) {
- PluginResult.Status status = PluginResult.Status.OK;
- String result = "";
-
- SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.ctx.getContext());
-
- try {
- if (action.equals("get")) {
- String key = args.getString(0);
- if (sharedPrefs.contains(key)) {
- Object obj = sharedPrefs.getAll().get(key);
- return new PluginResult(status, obj.toString());
- } else {
- return createErrorObj(NO_PROPERTY, "No such property called " + key);
- }
- } else if (action.equals("set")) {
- String key = args.getString(0);
- String value = args.getString(1);
- if (sharedPrefs.contains(key)) {
- Editor editor = sharedPrefs.edit();
- if ("true".equals(value.toLowerCase()) || "false".equals(value.toLowerCase())) {
- editor.putBoolean(key, Boolean.parseBoolean(value));
- } else {
- editor.putString(key, value);
- }
- return new PluginResult(status, editor.commit());
- } else {
- return createErrorObj(NO_PROPERTY, "No such property called " + key);
- }
- } else if (action.equals("load")) {
- JSONObject obj = new JSONObject();
- Map prefs = sharedPrefs.getAll();
- Iterator it = prefs.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry pairs = (Map.Entry)it.next();
- obj.put(pairs.getKey().toString(), pairs.getValue().toString());
- }
- return new PluginResult(status, obj);
- } else if (action.equals("show")) {
- String activityName = args.getString(0);
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(this.ctx.getContext(), activityName);
- try {
- this.ctx.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- return createErrorObj(NO_PREFERENCE_ACTIVITY, "No preferences activity called " + activityName);
- }
- }
- } catch (JSONException e) {
- status = PluginResult.Status.JSON_EXCEPTION;
- }
- return new PluginResult(status, result);
- }
-
- private PluginResult createErrorObj(int code, String message) throws JSONException {
- JSONObject errorObj = new JSONObject();
- errorObj.put("code", code);
- errorObj.put("message", message);
- return new PluginResult(PluginResult.Status.ERROR, errorObj);
- }
-
-}
diff --git a/Android/AppPreferences/2.0.0/assets/www/applicationPreferences.js b/Android/AppPreferences/2.0.0/assets/www/applicationPreferences.js
deleted file mode 100644
index 9db81d68..00000000
--- a/Android/AppPreferences/2.0.0/assets/www/applicationPreferences.js
+++ /dev/null
@@ -1,31 +0,0 @@
-cordova.define("cordova/plugin/applicationpreferences", function(require, exports, module) {
- var exec = require("cordova/exec");
- var AppPreferences = function () {};
-
- var AppPreferencesError = function(code, message) {
- this.code = code || null;
- this.message = message || '';
- };
-
- AppPreferencesError.NO_PROPERTY = 0;
- AppPreferencesError.NO_PREFERENCE_ACTIVITY = 1;
-
- AppPreferences.prototype.get = function(key,success,fail) {
- cordova.exec(success,fail,"applicationPreferences","get",[key]);
- };
-
- AppPreferences.prototype.set = function(key,value,success,fail) {
- cordova.exec(success,fail,"applicationPreferences","set",[key, value]);
- };
-
- AppPreferences.prototype.load = function(success,fail) {
- cordova.exec(success,fail,"applicationPreferences","load",[]);
- };
-
- AppPreferences.prototype.show = function(activity,success,fail) {
- cordova.exec(success,fail,"applicationPreferences","show",[activity]);
- };
-
- var appPreferences = new AppPreferences();
- module.exports = appPreferences;
-});
diff --git a/Android/AppPreferences/2.0.0/src/com/simonmacdonald/prefs/AppPreferences.java b/Android/AppPreferences/2.0.0/src/com/simonmacdonald/prefs/AppPreferences.java
deleted file mode 100644
index 152f55d7..00000000
--- a/Android/AppPreferences/2.0.0/src/com/simonmacdonald/prefs/AppPreferences.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.simonmacdonald.prefs;
-
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.cordova.api.Plugin;
-import org.apache.cordova.api.PluginResult;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-public class AppPreferences extends Plugin {
-
- private static final String LOG_TAG = "AppPrefs";
- private static final int NO_PROPERTY = 0;
- private static final int NO_PREFERENCE_ACTIVITY = 1;
-
- @Override
- public PluginResult execute(String action, JSONArray args, String callbackId) {
- PluginResult.Status status = PluginResult.Status.OK;
- String result = "";
-
- SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.cordova.getActivity());
-
- try {
- if (action.equals("get")) {
- String key = args.getString(0);
- if (sharedPrefs.contains(key)) {
- Object obj = sharedPrefs.getAll().get(key);
- return new PluginResult(status, obj.toString());
- } else {
- return createErrorObj(NO_PROPERTY, "No such property called " + key);
- }
- } else if (action.equals("set")) {
- String key = args.getString(0);
- String value = args.getString(1);
- if (sharedPrefs.contains(key)) {
- Editor editor = sharedPrefs.edit();
- if ("true".equals(value.toLowerCase()) || "false".equals(value.toLowerCase())) {
- editor.putBoolean(key, Boolean.parseBoolean(value));
- } else {
- editor.putString(key, value);
- }
- return new PluginResult(status, editor.commit());
- } else {
- return createErrorObj(NO_PROPERTY, "No such property called " + key);
- }
- } else if (action.equals("load")) {
- JSONObject obj = new JSONObject();
- Map prefs = sharedPrefs.getAll();
- Iterator it = prefs.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry pairs = (Map.Entry)it.next();
- obj.put(pairs.getKey().toString(), pairs.getValue().toString());
- }
- return new PluginResult(status, obj);
- } else if (action.equals("show")) {
- String activityName = args.getString(0);
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(this.cordova.getActivity(), activityName);
- try {
- this.cordova.getActivity().startActivity(intent);
- } catch (ActivityNotFoundException e) {
- return createErrorObj(NO_PREFERENCE_ACTIVITY, "No preferences activity called " + activityName);
- }
- }
- } catch (JSONException e) {
- status = PluginResult.Status.JSON_EXCEPTION;
- }
- return new PluginResult(status, result);
- }
-
- private PluginResult createErrorObj(int code, String message) throws JSONException {
- JSONObject errorObj = new JSONObject();
- errorObj.put("code", code);
- errorObj.put("message", message);
- return new PluginResult(PluginResult.Status.ERROR, errorObj);
- }
-
-}
diff --git a/Android/AppPreferences/README.md b/Android/AppPreferences/README.md
index 15fd2dcd..8b6089aa 100644
--- a/Android/AppPreferences/README.md
+++ b/Android/AppPreferences/README.md
@@ -1,105 +1,2 @@
-# Application Preferences plugin for Phonegap #
-Originally by Simon MacDonald (@macdonst)
-
-## Adding the Plugin to your project ##
-
-1) To install the plugin, move applicationPreferences.js to your project's www folder and include a reference to it in your html files.
-
-``
-
-2) Create a folder called 'com/simonmacdonald/prefs' within your project's src folder.
-3) And copy the AppPreferences.java file into that new folder.
-
-`mkdir /src/com/simonmacdonald/prefs`
-
-`cp ./src/com/simonmacdonald/prefs/AppPreferences.java /src/com/simonmacdonald/prefs`
-
-4) In your res/xml/plugins.xml file add the following line:
-
- ``
-
-## Using the plugin ##
-The plugin creates the object `window.plugins.applicationPreferences`
-
-### get ###
-
-In order to get the value a property you would call the get method.
-
- /**
- * Get the value of the named property.
- *
- * @param key
- */
- get(key, success, fail)
-
-Sample use:
-
- window.plugins.applicationPreference.get("key", success, fail);
-
-### set ###
-
-In order to set the value a property you would call the set method.
-
- /**
- * Set the value of the named property.
- *
- * @param key
- * @param value
- */
- set(key, value, success, fail)
-
-Sample use:
-
- window.plugins.applicationPreference.set("key", "value", success, fail);
-
-### load ###
-
-In order to get all the properties you can call the load method. The success callback of the load method will be called with a JSONObject which contains all the preferences.
-
- /**
- * Get all the preference values.
- *
- */
- load(success, fail)
-
-Sample use:
-
- window.plugins.applicationPreference.load(success, fail);
-
-### show ###
-
-If you want to load the PreferenceActivity of your application that displays all the preferences you can call the show method with the class name.
-
- /**
- * Get all the preference values.
- *
- */
- show(activity, success, fail)
-
-Sample use:
-
- window.plugins.applicationPreference.show("com.simonmacdonald.prefs.PreferenceActivity", success, fail);
-
-## Licence ##
-
-The MIT License
-
-Copyright (c) 2012 Simon MacDonald
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
+# Moved to #
+https://github.com/macdonst/AppPreferences
\ No newline at end of file
diff --git a/Android/Asset2SD/README.md b/Android/Asset2SD/README.md
new file mode 100644
index 00000000..7833ce20
--- /dev/null
+++ b/Android/Asset2SD/README.md
@@ -0,0 +1 @@
+# Asset2SD plugin for Phonegap #
By Gautam Chaudhary
Phonegap plugin for Android for copying files from app assets to device SD Card.
The repository for this plugin is located at https://github.com/gkcgautam/Asset2SD
\ No newline at end of file
diff --git a/Android/AugmentedReality-Wikitude/README.md b/Android/AugmentedReality-Wikitude/README.md
new file mode 100644
index 00000000..a4bed477
--- /dev/null
+++ b/Android/AugmentedReality-Wikitude/README.md
@@ -0,0 +1,6 @@
+# Augmented Reality meets PhoneGap - Wikitude
+
+
+##This plugin moved to another git, please visit [Wikitude's PhoneGap Git](https://github.com/Wikitude/wikitude-phonegap "AR Plugin PhoneGap")
+
+[https://github.com/Wikitude/wikitude-phonegap](https://github.com/Wikitude/wikitude-phonegap "AR Plugin PhoneGap")
\ No newline at end of file
diff --git a/Android/BackgroundService/1.8.1/MyService.java b/Android/BackgroundService/1.8.1/MyService.java
new file mode 100644
index 00000000..cb39447f
--- /dev/null
+++ b/Android/BackgroundService/1.8.1/MyService.java
@@ -0,0 +1,78 @@
+package com.yournamespace.yourappname;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.util.Log;
+
+import com.red_folder.phonegap.plugin.backgroundservice.BackgroundService;
+
+public class MyService extends BackgroundService {
+
+ private final static String TAG = MyService.class.getSimpleName();
+
+ private String mHelloTo = "World";
+
+ @Override
+ protected JSONObject doWork() {
+ JSONObject result = new JSONObject();
+
+ try {
+ SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
+ String now = df.format(new Date(System.currentTimeMillis()));
+
+ String msg = "Hello " + this.mHelloTo + " - its currently " + now;
+ result.put("Message", msg);
+
+ Log.d(TAG, msg);
+ } catch (JSONException e) {
+ }
+
+ return result;
+ }
+
+ @Override
+ protected JSONObject getConfig() {
+ JSONObject result = new JSONObject();
+
+ try {
+ result.put("HelloTo", this.mHelloTo);
+ } catch (JSONException e) {
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void setConfig(JSONObject config) {
+ try {
+ if (config.has("HelloTo"))
+ this.mHelloTo = config.getString("HelloTo");
+ } catch (JSONException e) {
+ }
+
+ }
+
+ @Override
+ protected JSONObject initialiseLatestResult() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ protected void onTimerEnabled() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void onTimerDisabled() {
+ // TODO Auto-generated method stub
+
+ }
+
+
+}
diff --git a/Android/BackgroundService/1.8.1/README.md b/Android/BackgroundService/1.8.1/README.md
new file mode 100644
index 00000000..03ce8cf3
--- /dev/null
+++ b/Android/BackgroundService/1.8.1/README.md
@@ -0,0 +1,73 @@
+# Background Service Plugin for Phonegap #
+
+A plugin (and framework code) that allows the development and operation of an Android Background Service.
+
+The example MyService Background Service will write a Hello message to the LogCat every minute. The MyService is designed as sample code.
+
+## Adding the plugin to your project ##
+
+Copy the files to the following locations:
+
+* libs\backgroundserviceplugin.jar
+* src\com\yournamespace\yourappname\MyService.java
+* assets\www\backgroundService.js
+* assets\www\myService.js
+* assets\www\index.html
+
+Add the following to res\xml\plugins.xml
+
+```
+
+```
+
+Add the following to AndroidManifest.xml
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+## Change Log ##
+
+* 14th November 2012 - Fix for service not stopping if the app has been closed then re-opened
+
+
+## Further Information ##
+
+Further information on the plugin can be found at:
+
+* http://red-folder.blogspot.co.uk/2012/09/phonegap-android-background-service.html
+* http://red-folder.blogspot.com/2012/09/phonegap-android-background-service_11.html
+
+The below is a tutorial to create your own Twitter service:
+
+* http://red-folder.blogspot.com/2012/09/phonegap-service-tutorial-part-1.html
+* http://red-folder.blogspot.com/2012/09/phonegap-service-tutorial-part-2.html
+* http://red-folder.blogspot.com/2012/09/phonegap-service-tutorial-part-3.html
+
+Please let me know your thoughts and comments.
+
+## Licence ##
+
+The MIT License
+
+Copyright (c) 2012 Red Folder Consultancy Ltd
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
diff --git a/Android/BackgroundService/1.8.1/backgroundService.js b/Android/BackgroundService/1.8.1/backgroundService.js
new file mode 100644
index 00000000..e6be7158
--- /dev/null
+++ b/Android/BackgroundService/1.8.1/backgroundService.js
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2012 Red Folder Consultancy Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Constructor
+ */
+function BackgroundService(serviceName) {
+ var ServiceName = serviceName;
+
+ this.getServiceName = function() {
+ return ServiceName;
+ };
+};
+
+/**
+ * All methods attempt to return the following data in both the success and failure callbacks
+ * Front end development should take into account any all or all of these values may be null
+ *
+ * Following returned in the JSONObject:
+ * Boolean Success - was the call a success
+ * int ErrorCode - Error code if an error occurred, else will be zero
+ * String ErrorMessage - Text representation of the error code
+ * Boolean ServiceRunning - True if the Service is running
+ * Boolean TimerEnabled - True if the Timer is enabled
+ * Boolean RegisteredForBootStart - True if the Service is registered for boot start
+ * JSONObject Configuration - A JSONObject of the configuration of the service (contents dependant on the service)
+ * JSONObject LastestResult - A JSONObject of the last result of the service (contents dependant on the service)
+ */
+
+/**
+ * Starts the Service
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.startService = function(successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'startService',
+ [this.getServiceName()]);
+};
+
+/**
+ * Stops the Service
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.stopService = function(successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'stopService',
+ [this.getServiceName()]);
+};
+
+/**
+ * Enables the Service Timer
+ *
+ * @param milliseconds The milliseconds used for the timer
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.enableTimer = function(milliseconds, successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'enableTimer',
+ [this.getServiceName(), milliseconds]);
+};
+
+/**
+ * Disabled the Service Timer
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.disableTimer = function(successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'disableTimer',
+ [this.getServiceName()]);
+};
+
+/**
+ * Sets the configuration for the service
+ *
+ * @oaran configuration JSONObject to be sent to the service
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.setConfiguration = function(configuration, successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'setConfiguration',
+ [this.getServiceName(), configuration]);
+};
+
+/**
+ * Registers the service for Boot Start
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.registerForBootStart = function(successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'registerForBootStart',
+ [this.getServiceName()]);
+};
+
+/**
+ * Deregisters the service for Boot Start
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.deregisterForBootStart = function(successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'deregisterForBootStart',
+ [this.getServiceName()]);
+};
+
+/**
+ * Get the current status of the service.
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.isRegisteredForBootStart = function(successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'isRegisteredForBootStart',
+ [this.getServiceName()]);
+};
+
+
+/**
+ * Returns the status of the service
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+BackgroundService.prototype.getStatus = function(successCallback, failureCallback) {
+ return cordova.exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'getStatus',
+ [this.getServiceName()]);
+};
+
diff --git a/Android/BackgroundService/1.8.1/backgroundserviceplugin.jar b/Android/BackgroundService/1.8.1/backgroundserviceplugin.jar
new file mode 100644
index 00000000..e72e0e7a
Binary files /dev/null and b/Android/BackgroundService/1.8.1/backgroundserviceplugin.jar differ
diff --git a/Android/BackgroundService/1.8.1/index.html b/Android/BackgroundService/1.8.1/index.html
new file mode 100644
index 00000000..d50a9144
--- /dev/null
+++ b/Android/BackgroundService/1.8.1/index.html
@@ -0,0 +1,219 @@
+
+
+
+
+ MyService
+
+
+
+
+
+
+
+
+
+
+
MyService
+
+
+
+
Service
+
+
+
+
+
Timer
+
+
+
+
+
Boot
+
+
+
+
+
+
Configuration
+
+
+
Hello To
+
+
+
+
+
+
+
+
Latest Result
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Android/BackgroundService/1.8.1/myService.js b/Android/BackgroundService/1.8.1/myService.js
new file mode 100644
index 00000000..3849f361
--- /dev/null
+++ b/Android/BackgroundService/1.8.1/myService.js
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012 Red Folder Consultancy Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ///////////////////
+(function(){
+// ///////////////////
+
+// get local ref to global PhoneGap/Cordova/cordova object for exec function
+var cordovaRef = window.PhoneGap || window.Cordova || window.cordova; // old to new fallbacks
+
+
+cordovaRef.addConstructor(function() {
+ cordovaRef.addPlugin("myService", new BackgroundService('com.yournamespace.yourappname.MyService'));
+});
+
+// ///////////////////
+})();
+// ///////////////////
diff --git a/Android/BackgroundService/2.0.0/MyService.java b/Android/BackgroundService/2.0.0/MyService.java
new file mode 100644
index 00000000..cb39447f
--- /dev/null
+++ b/Android/BackgroundService/2.0.0/MyService.java
@@ -0,0 +1,78 @@
+package com.yournamespace.yourappname;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.util.Log;
+
+import com.red_folder.phonegap.plugin.backgroundservice.BackgroundService;
+
+public class MyService extends BackgroundService {
+
+ private final static String TAG = MyService.class.getSimpleName();
+
+ private String mHelloTo = "World";
+
+ @Override
+ protected JSONObject doWork() {
+ JSONObject result = new JSONObject();
+
+ try {
+ SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
+ String now = df.format(new Date(System.currentTimeMillis()));
+
+ String msg = "Hello " + this.mHelloTo + " - its currently " + now;
+ result.put("Message", msg);
+
+ Log.d(TAG, msg);
+ } catch (JSONException e) {
+ }
+
+ return result;
+ }
+
+ @Override
+ protected JSONObject getConfig() {
+ JSONObject result = new JSONObject();
+
+ try {
+ result.put("HelloTo", this.mHelloTo);
+ } catch (JSONException e) {
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void setConfig(JSONObject config) {
+ try {
+ if (config.has("HelloTo"))
+ this.mHelloTo = config.getString("HelloTo");
+ } catch (JSONException e) {
+ }
+
+ }
+
+ @Override
+ protected JSONObject initialiseLatestResult() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ protected void onTimerEnabled() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void onTimerDisabled() {
+ // TODO Auto-generated method stub
+
+ }
+
+
+}
diff --git a/Android/BackgroundService/2.0.0/README.md b/Android/BackgroundService/2.0.0/README.md
new file mode 100644
index 00000000..74dcb835
--- /dev/null
+++ b/Android/BackgroundService/2.0.0/README.md
@@ -0,0 +1,72 @@
+# Background Service Plugin for Phonegap #
+
+A plugin (and framework code) that allows the development and operation of an Android Background Service.
+
+The example MyService Background Service will write a Hello message to the LogCat every minute. The MyService is designed as sample code.
+
+## Adding the plugin to your project ##
+
+Copy the files to the following locations:
+
+* libs\backgroundserviceplugin-2.0.0.jar
+* src\com\yournamespace\yourappname\MyService.java
+* assets\www\backgroundService-2.0.0.js
+* assets\www\myService-2.0.0.js
+* assets\www\index-2.0.0.html
+
+Add the following to res\xml\config.xml
+
+```
+
+```
+
+Add the following to AndroidManifest.xml
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+## Change Log ##
+
+* 14th November 2012 - Fix for service not stopping if the app has been closed then re-opened
+
+## Further Information ##
+
+Further information on the plugin can be found at:
+
+* http://red-folder.blogspot.co.uk/2012/09/phonegap-android-background-service.html
+* http://red-folder.blogspot.com/2012/09/phonegap-android-background-service_11.html
+
+The below is a tutorial to create your own Twitter service:
+
+* http://red-folder.blogspot.com/2012/09/phonegap-service-tutorial-part-1.html
+* http://red-folder.blogspot.com/2012/09/phonegap-service-tutorial-part-2.html
+* http://red-folder.blogspot.com/2012/09/phonegap-service-tutorial-part-3.html
+
+Please let me know your thoughts and comments.
+
+## Licence ##
+
+The MIT License
+
+Copyright (c) 2012 Red Folder Consultancy Ltd
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
diff --git a/Android/BackgroundService/2.0.0/backgroundService-2.0.0.js b/Android/BackgroundService/2.0.0/backgroundService-2.0.0.js
new file mode 100644
index 00000000..ae70e2cf
--- /dev/null
+++ b/Android/BackgroundService/2.0.0/backgroundService-2.0.0.js
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2012 Red Folder Consultancy Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Constructor
+ */
+function CreateBackgroundService(serviceName, require, exports, module) {
+ var exec = require("cordova/exec");
+
+ var BackgroundService = function (serviceName) {
+ var ServiceName = serviceName
+ this.getServiceName = function() {
+ return ServiceName;
+ };
+ };
+
+ var BackgroundServiceError = function (code, message) {
+ this.code = code || null;
+ this.message = message || null;
+ };
+
+ /**
+ * All methods attempt to return the following data in both the success and failure callbacks
+ * Front end development should take into account any all or all of these values may be null
+ *
+ * Following returned in the JSONObject:
+ * Boolean Success - was the call a success
+ * int ErrorCode - Error code if an error occurred, else will be zero
+ * String ErrorMessage - Text representation of the error code
+ * Boolean ServiceRunning - True if the Service is running
+ * Boolean TimerEnabled - True if the Timer is enabled
+ * Boolean RegisteredForBootStart - True if the Service is registered for boot start
+ * JSONObject Configuration - A JSONObject of the configuration of the service (contents dependant on the service)
+ * JSONObject LastestResult - A JSONObject of the last result of the service (contents dependant on the service)
+ */
+
+ /**
+ * Starts the Service
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.startService = function(successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'startService',
+ [this.getServiceName()]);
+ };
+
+ /**
+ * Stops the Service
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.stopService = function(successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'stopService',
+ [this.getServiceName()]);
+ };
+
+ /**
+ * Enables the Service Timer
+ *
+ * @param milliseconds The milliseconds used for the timer
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.enableTimer = function(milliseconds, successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'enableTimer',
+ [this.getServiceName(), milliseconds]);
+ };
+
+ /**
+ * Disabled the Service Timer
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.disableTimer = function(successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'disableTimer',
+ [this.getServiceName()]);
+ };
+
+ /**
+ * Sets the configuration for the service
+ *
+ * @oaran configuration JSONObject to be sent to the service
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.setConfiguration = function(configuration, successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'setConfiguration',
+ [this.getServiceName(), configuration]);
+ };
+
+ /**
+ * Registers the service for Boot Start
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.registerForBootStart = function(successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'registerForBootStart',
+ [this.getServiceName()]);
+ };
+
+ /**
+ * Deregisters the service for Boot Start
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.deregisterForBootStart = function(successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'deregisterForBootStart',
+ [this.getServiceName()]);
+ };
+
+ /**
+ * Get the current status of the service.
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.isRegisteredForBootStart = function(successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'isRegisteredForBootStart',
+ [this.getServiceName()]);
+ };
+
+
+ /**
+ * Returns the status of the service
+ *
+ * @param successCallback The callback which will be called if the method is successful
+ * @param failureCallback The callback which will be called if the method encounters an error
+ */
+ BackgroundService.prototype.getStatus = function(successCallback, failureCallback) {
+ return exec( successCallback,
+ failureCallback,
+ 'BackgroundServicePlugin',
+ 'getStatus',
+ [this.getServiceName()]);
+ };
+
+ var backgroundService = new BackgroundService(serviceName);
+ module.exports = backgroundService;
+};
diff --git a/Android/BackgroundService/2.0.0/backgroundserviceplugin-2.0.0.jar b/Android/BackgroundService/2.0.0/backgroundserviceplugin-2.0.0.jar
new file mode 100644
index 00000000..a9cd9eac
Binary files /dev/null and b/Android/BackgroundService/2.0.0/backgroundserviceplugin-2.0.0.jar differ
diff --git a/Android/BackgroundService/2.0.0/index-2.0.0.html b/Android/BackgroundService/2.0.0/index-2.0.0.html
new file mode 100644
index 00000000..e49998d1
--- /dev/null
+++ b/Android/BackgroundService/2.0.0/index-2.0.0.html
@@ -0,0 +1,215 @@
+
+
+
+
+ MyService
+
+
+
+
+
+
+
+
+
+
+
MyService
+
+
+
+
Service
+
+
+
+
+
Timer
+
+
+
+
+
Boot
+
+
+
+
+
+
Configuration
+
+
+
Hello To
+
+
+
+
+
+
+
+
Latest Result
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Android/BackgroundService/2.0.0/myService-2.0.0.js b/Android/BackgroundService/2.0.0/myService-2.0.0.js
new file mode 100644
index 00000000..02341b16
--- /dev/null
+++ b/Android/BackgroundService/2.0.0/myService-2.0.0.js
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012 Red Folder Consultancy Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cordova.define( 'cordova/plugin/myService', function(require, exports, module) {
+ CreateBackgroundService('com.yournamespace.yourappname.MyService', require, exports, module);
+ });
diff --git a/Android/BackgroundService/README.md b/Android/BackgroundService/README.md
new file mode 100644
index 00000000..b93303be
--- /dev/null
+++ b/Android/BackgroundService/README.md
@@ -0,0 +1,25 @@
+# Background Service Plugin for Phonegap #
+
+A plugin (and framework code) that allows the development and operation of an Android Background Service.
+
+The example MyService Background Service will write a Hello message to the LogCat every minute. The MyService is designed as sample code.
+
+## Repository Location ##
+
+The location for this repository has been moved to https://github.com/Red-Folder/Cordova-Plugin-BackgroundService
+
+This was moved based on the Plugin recommendations here -> http://shazronatadobe.wordpress.com/2012/11/07/cordova-plugins-put-them-in-your-own-repo-2/
+
+
+## Licence ##
+
+The MIT License
+
+Copyright (c) 2012 Red Folder Consultancy Ltd
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/Android/BarcodeScanner/1.8.1/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java b/Android/BarcodeScanner/1.8.1/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java
index 29786360..77b42adf 100644
--- a/Android/BarcodeScanner/1.8.1/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java
+++ b/Android/BarcodeScanner/1.8.1/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java
@@ -110,7 +110,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
//Log.d(LOG_TAG, "This should never happen");
}
this.success(new PluginResult(PluginResult.Status.OK, obj), this.callback);
- } if (resultCode == Activity.RESULT_CANCELED) {
+ } else if (resultCode == Activity.RESULT_CANCELED) {
JSONObject obj = new JSONObject();
try {
obj.put("text", "");
diff --git a/Android/BarcodeScanner/2.0.0/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java b/Android/BarcodeScanner/2.0.0/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java
index b18c0cb8..c451b457 100644
--- a/Android/BarcodeScanner/2.0.0/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java
+++ b/Android/BarcodeScanner/2.0.0/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java
@@ -121,7 +121,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
//Log.d(LOG_TAG, "This should never happen");
}
this.success(new PluginResult(PluginResult.Status.OK, obj), this.callback);
- } if (resultCode == Activity.RESULT_CANCELED) {
+ } else if (resultCode == Activity.RESULT_CANCELED) {
JSONObject obj = new JSONObject();
try {
obj.put(TEXT, "");
@@ -149,4 +149,4 @@ public void encode(String type, String data) {
this.cordova.getActivity().startActivity(intentEncode);
}
-}
\ No newline at end of file
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/.classpath b/Android/BarcodeScanner/2.2.0/LibraryProject/.classpath
new file mode 100644
index 00000000..a4763d1e
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/.project b/Android/BarcodeScanner/2.2.0/LibraryProject/.project
new file mode 100644
index 00000000..43ee6b5b
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/.project
@@ -0,0 +1,33 @@
+
+
+ CaptureActivity
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/AndroidManifest.xml b/Android/BarcodeScanner/2.2.0/LibraryProject/AndroidManifest.xml
new file mode 100644
index 00000000..a4a2541f
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/AndroidManifest.xml
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/ant.properties b/Android/BarcodeScanner/2.2.0/LibraryProject/ant.properties
new file mode 100644
index 00000000..c0f6ae50
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/ant.properties
@@ -0,0 +1,21 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked in Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
+application-package=com.google.zxing.client.android
+external-libs-folder=libs
+key.store=../../release.keystore
+key.alias=release
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/about1d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/about1d.html
new file mode 100644
index 00000000..5d1551e1
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/about1d.html
@@ -0,0 +1,15 @@
+
+
+
+
+Über 1D-Barcodes (Strichcodes)
+
+
+
+
Die altbekannten Strichcodes, wie solche auf Produktverpackungen, werden auch eindimensionale Barcodes genannt. Es gibt einige verbreitete Arten, wie den UPC (Universal Product Code) und den EAN (European Article Number). Die meisten schauen so aus:
+
+
Diese Strichcodes enthalten eine einmalige Nummer, welche ein Produkt, wie ein Buch oder eine CD, beschreiben. Man kann nach dieser Nummer im Internet suchen, um Preise oder Beurteilungen zu finden.
+
Wenn man den Code eines Buches einscannt, kann man den Inhalt des Buches nach Wörtern oder Sätzen durchsuchen und alle Seiten finden, in denen dieses Wort vorkam:
+
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/about2d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/about2d.html
new file mode 100644
index 00000000..a7f4d277
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/about2d.html
@@ -0,0 +1,26 @@
+
+
+
+
+Über 2D-Barcodes
+
+
+
+
Der Barcode Scanner kann auch zweidimensionale Barcodes, wie den QR-Code und den DataMatrix-Code einlesen. Die Barcodes in diesem Beispiel enthalten einen Hyperlink auf die Projekt-Homepage von ZXing:
+
+
+
+
+
Ein QR-Code kann auch eine Visitenkarte mit Kontaktinformationen wie Telefonnummern und E-Mail-Adressen enthalten. Wird ein solcher Code eingescannt, dann wird eine Auswahl an Aktionen angezeigt:
+
+
Neben URLs und Kontaktdaten können QR-Codes auch folgendes enthalten:
+
+
Kalendereinträge, die man dem Kalender hinzufügen kann
+
Telefonnummern, die man anrufen oder abspeichern kann
+
SMS-Nachrichten, die man verschicken kann
+
E-Mail-Adressen, denen man eine Nachricht schreiben kann
+
Geographische Koordinaten, die zu der man die Karte öffnen kann
+
Einfachen Text, den man lesen oder in die Zwischenablage kopieren kann
+
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/index.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/index.html
new file mode 100644
index 00000000..f0bd0613
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+Barcode Scanner-Hilfe
+
+
+
+
Der Barcode Scanner verwendet die Kamera ihres Handys, um Barcodes zu lesen und Produktinformationen wie Preise und Bewertungen zu suchen.
+
+
Er liest auch 2D-Barcodes wie den QR-Code und DataMatrix. Diese Barcodes können z.B. Links zu Webseiten enthalten oder Kontaktinformationen wie Telefonnummern und E-Mail-Adressen und vieles mehr.
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/scanning.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/scanning.html
new file mode 100644
index 00000000..59d23a0b
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/scanning.html
@@ -0,0 +1,19 @@
+
+
+
+
+Tips fürs scannen
+
+
+
+
Der Scanner durchsucht kontinuierlich den rechteckigen Bereich auf dem Bildschirm. Dabei muss der Barcode vollständig im rechteckigen Sucher erscheinen:
+
+
Für 1D-Barcodes, auch Strichcodes genannt, welche sich auf allen Handelsprodukten befinden, benötigt man ein Handy mit Autofokus. Ohne diesen können nur QR-Codes und DataMatrix-Codes eingescannt werden.
+
Wenn ein Barcode eingelesen wurde, piepst das Handy und es wird das Ergebnis des Scans angezeigt, sowie eine Beschreibung des Barcode-Inhalts, und verschiedene Möglichkeiten wie weiter verfahren werden soll.
+
Falls das Einscannen nicht richtig funktioniert, versuchen Sie das Handy ruhiger zu halten. Wenn das Bild unscharf ist, vergrößern oder verkleinern Sie den Abstand zum Barcode.
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/sharing.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/sharing.html
new file mode 100644
index 00000000..daf7078c
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/sharing.html
@@ -0,0 +1,14 @@
+
+
+
+
+So erstellen Sie einen QR-Code
+
+
+
+
Der Barcode Scanner kann nicht nur QR-Codes einlesen, sondern auch selbst erzeugen und auf dem Bildschirm anzeigen. Diesen QR-Code können Sie dann einem Freund zeigen, der den Code mit seinen Handy einscannen kann.
+
+
Um diese Funktion zu nutzen, einfach auf dem Hauptbildschirm auf die Menü-Taste drücken, und auf Senden tippen. Dann wählen, ob Sie einen Kontakt, ein Lesezeichen, eine Anwendung oder den Inhalt der Zwischenablage senden wollen und der QR-Code wird automatisch generiert. Wenn Sie fertig sind, drücken Sie die Zurücktaste.
+
Um QR-Codes auf Ihrem Computer zu erzeugen, testen Sie den ZXing QR Code Generator, er basiert auf dem selben Quelltext wie dieses Programm: http://zxing.appspot.com/generator/
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/whatsnew.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/whatsnew.html
new file mode 100644
index 00000000..aedeeac5
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-de/whatsnew.html
@@ -0,0 +1,15 @@
+
+
+
+
+Neues in dieser Version von Barcode Scanner
+
+
+
+
Neu in der Version 4.3.1:
+
+
Belichtungssteuerung deaktivierbar, wenn diese auf Ihrem Gerät Probleme verursacht
+
Einige weitere kleine Fehler behoben
+
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/about1d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/about1d.html
new file mode 100644
index 00000000..d809b931
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/about1d.html
@@ -0,0 +1,15 @@
+
+
+
+
+About 1D barcodes
+
+
+
+
Traditional barcodes, such as those printed on product packaging, are also known as one dimensional barcodes. There are several types commonly used, including UPC and EAN. Most look similar to this:
+
+
These 1D barcodes contain a unique code which typically describes a product, like a CD or a book. You can look this code up on the internet to find prices, reviews, and more.
+
If you scan a book, you can also search the contents of the book for a word or phrase, and find all the pages where it appears:
+
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/about2d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/about2d.html
new file mode 100644
index 00000000..42cfaedb
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/about2d.html
@@ -0,0 +1,26 @@
+
+
+
+
+About 2D barcodes
+
+
+
+
Barcode Scanner also understands how to read two dimensional barcodes, like QR Codes and Data Matrix codes. For example, the codes below contain a hyperlink to the ZXing Project home page:
+
+
+
+
+
You can also represent contact information in a QR Code, and put it on a business card or web site. When you scan it, the results screen provides a choice of actions:
+
+
Besides URLs and contact info, QR Codes can also contain:
+
+
Calendar events, which you can add to your Calendar
+
Phone numbers, which you can dial
+
SMS numbers, which you can text message
+
Email addresses, which you can email
+
Geographic coordinates, which you can open in Maps
+
Plain text, which you can read, then share with a friend
+
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/index.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/index.html
new file mode 100644
index 00000000..2e1cc336
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+Barcode Scanner Help
+
+
+
+
Barcode Scanner uses the camera on your phone to read barcodes and look up product information such as prices and reviews.
+
+
It also reads 2D barcodes such as QR Codes and Data Matrix. These can contain links to web sites, contact information such as phone numbers and email addresses, and more.
Barcode Scanner continuously scans a square region shown on your screen -- just line up the phone so the barcode is completely inside the viewfinder rectangle:
+
+
1D barcodes like those found on products require a phone with autofocus. Without it, only QR Codes and Data Matrix codes will be scannable.
+
When a barcode is read, a beep sound will play and you'll see the results of the scan, a description of what the barcode contains, and options to take action on the contents.
+
If you're having trouble scanning, make sure to hold the phone steady. If the camera is unable to focus, try moving the phone further or closer from the barcode.
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/sharing.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/sharing.html
new file mode 100644
index 00000000..8943dd2c
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-en/sharing.html
@@ -0,0 +1,14 @@
+
+
+
+
+How to create QR Codes
+
+
+
+
In addition to scanning 2D barcodes, Barcode Scanner can also generate a QR Code and display it on your screen. Then you can show it to a friend, and let them scan the barcode with their phone:
+
+
To use this feature, press the Menu button from the main scanning screen, and tap Share. Then choose whether you want to share a contact, a bookmark, an application, or the contents of the clipboard. A QR Code will be generated automatically. When you're done, press Back or Home.
Estos códigos de barras 1D contiene un código único que generalmente describe un producto, como un CD o un libro. Usted puede ver este código en el Internet para encontrar precios, comentarios y más.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-es/about2d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-es/about2d.html
new file mode 100644
index 00000000..57fe24b2
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-es/about2d.html
@@ -0,0 +1,26 @@
+
+
+
+
+ Acerca de los códigos de barras 2D
+
+
+
+
Barcode Scanner utiliza la cámara de su móvil para leer códigos de barras y buscar información sobre los productos como los precios y las revisiones.
Cuando un código de barras es leÃdo, un sonido se reproducirá y podrás ver los resultados del análisis, una descripción de lo que contiene el código de barras, y las opciones para tomar acción sobre los contenidos.
Para utilizar esta función, presione el botón Menú en la pantalla de exploración principal y toque Compartir. A continuación, seleccione si desea compartir un contacto, un marcador, una aplicación o el contenido del portapapeles. Un código QR se generará automáticamente. Cuando haya terminado, pulse Atrás o Inicio.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/about1d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/about1d.html
new file mode 100644
index 00000000..8b0d8a0a
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/about1d.html
@@ -0,0 +1,15 @@
+
+
+
+
+ A proposito di codici a barre 1D
+
+
+
+
Codici a barre tradizionali, come quelle stampate sulla confezione del prodotto, sono noti anche come uno codici a barre bidimensionali. Ci sono diversi tipi di uso comune, tra cui UPC ed EAN. La maggior parte simile al seguente:
+
+
Queste barre 1D contengono un codice unico che descrive tipicamente un prodotto, come un CD o un libro. È possibile cercare questo codice su internet per trovare i prezzi, recensioni e altro.
+
Se si esegue la scansione di un libro, è anche possibile cercare i contenuti del libro per una parola o una frase, e trovare tutte le pagine in cui appare:
+
+
Tradotto da Google Translate.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/about2d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/about2d.html
new file mode 100644
index 00000000..6b862639
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/about2d.html
@@ -0,0 +1,26 @@
+
+
+
+
+ A proposito di codici a barre 2D
+
+
+
+
Barcode Scanner comprende anche come leggere due codici a barre bidimensionali, come i codici QR e codici Data Matrix. Per esempio, i seguenti codici contengono un collegamento ipertestuale alla pagina ZXing principale del progetto:
+
+
+
+
+
È anche possibile rappresentare le informazioni di contatto in un QR Code, e metterlo su un biglietto da visita o un sito web. Quando si esegue la scansione, la schermata dei risultati fornisce una serie di azioni:
+
+
Oltre URL e informazioni di contatto, i codici QR possono contenere anche:
+
+
Eventi del Calendario, che è possibile aggiungere al vostro calendario
+
I numeri di telefono, che possono essere digitati
+
Numeri di SMS, che è possibile il testo del messaggio
+
Indirizzi e-mail, che possono essere inviati per email
+
Coordinate geografiche, che è possibile aprire in Mappe
+
Testo semplice, che si può leggere, quindi condividere con un amico
+
+
Tradotto da Google Translate.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/index.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/index.html
new file mode 100644
index 00000000..b8e8d737
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+ Barcode Scanner Aiuto
+
+
+
+
Scanner di codici a barre utilizza la fotocamera del telefono per leggere codici a barre e ricercare informazioni sui prodotti, i prezzi e le recensioni.
+
+
Legge anche codici a barre 2D, come i codici QR e Data Matrix. Questi possono contenere link a siti web, informazioni di contatto, quali numeri di telefono e indirizzi e-mail e altro ancora.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/scanning.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/scanning.html
new file mode 100644
index 00000000..81d3cc03
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/scanning.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Come eseguire la scansione
+
+
+
+
Barcode Scanner analizza continuamente una regione quadrata mostrata sullo schermo - solo linea il telefono in modo che il codice a barre è completamente all'interno del rettangolo del mirino:
+
+
Codici a barre 1D, come quelle che si trovano sui prodotti richiede un telefono con autofocus. Senza di essa, solo i codici QR e codici Data Matrix sarà leggibile.
+
Quando un codice a barre viene letto, un bip si giocare e vedrete i risultati della scansione, una descrizione di ciò che il codice a barre contiene, e le opzioni per intervenire sui contenuti.
+
Se hai dei problemi di scansione, assicurarsi di tenere il telefono fermo. Se la fotocamera non riesce a mettere a fuoco, provare a spostare il telefono lontano o più vicino dal codice a barre.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/sharing.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/sharing.html
new file mode 100644
index 00000000..32ad9276
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/sharing.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Come creare codici QR
+
+
+
+
Oltre alla scansione di codici a barre 2D, Barcode Scanner può anche generare un codice QR e visualizzarla sullo schermo. Poi si può mostrare ad un amico, e far loro eseguire la scansione del codice a barre con il proprio telefono:
+
+
Per utilizzare questa funzione, premere il tasto Menu dalla schermata di scansione principale, e toccare Condividi. Quindi scegliere se si desidera condividere un contatto, un segnalibro, un'applicazione, o il contenuto degli appunti. Un codice a barre verrà generato automaticamente. Al termine, premere Indietro o Home.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/whatsnew.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/whatsnew.html
new file mode 100644
index 00000000..bae41c91
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-it/whatsnew.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Cosa c'è di nuovo nella Barcode Scanner
+
+
+
+
Nuovo nella versione 4.3.1:
+
+
Disabilitato il controllo dell'esposizione, ha causato problemi su dispositivi diversi buggy
+
Altre correzioni di bug piccoli
+
+
Tradotto da Google Translate.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-ja/about1d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-ja/about1d.html
new file mode 100644
index 00000000..6af6ad70
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-ja/about1d.html
@@ -0,0 +1,15 @@
+
+
+
+
+ 1Dãƒãƒ¼ã‚³ãƒ¼ãƒ‰ã«ã¤ã„ã¦
+
+
+
+
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/about1d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/about1d.html
new file mode 100644
index 00000000..c49fb57b
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/about1d.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Over 1D barcodes
+
+
+
+
Traditionele barcodes, zoals gedrukt op de verpakking, ook bekend als eendimensionale barcodes. Er zijn verschillende types gebruikt, zoals UPC en EAN. De meeste lijken op deze:
+
+
Deze 1D barcodes bevatten een unieke code die typisch beschrijft een product, zoals een cd of een boek. U kunt kijken deze code op het internet om de prijzen, reviews en nog veel meer te vinden.
+
Als u scant een boek, kunt u ook zoeken in de inhoud van het boek voor een woord of zin, en vind alle pagina's waar het verschijnt:
+
+
Vertaald door Google Translate.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/about2d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/about2d.html
new file mode 100644
index 00000000..dcb1d47b
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/about2d.html
@@ -0,0 +1,26 @@
+
+
+
+
+ Over 2D barcodes
+
+
+
+
Barcode Scanner begrijpt ook hoe om te lezen tweedimensionale barcodes, zoals QR Codes en Data Matrix codes. Bijvoorbeeld, de volgende codes bevatten een hyperlink naar de ZXing Project home page:
+
+
+
+
+
U kunt contactgegevens ook te vertegenwoordigen in een QR-code, en zet het op een visitekaartje of website. Als u het scannen, de resultaten scherm biedt een keuze van acties:
+
+
Naast URL's en contactgegevens, kunnen QR Codes bevatten:
+
+
Agenda-items, die u kunt toevoegen aan uw agenda
+
Telefoonnummers, die u kunt bellen
+
SMS-nummers, die u kunt SMS-bericht
+
E-mailadressen, die u kunt e-mailen
+
Geografische coördinaten, die u kunt openen in Google Maps
+
Platte tekst, die u kunt lezen, dan delen met een vriend
+
+
Vertaald door Google Translate.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/index.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/index.html
new file mode 100644
index 00000000..7e5e36bd
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+ Barcode Scanner Help
+
+
+
+
Barcode Scanner maakt gebruik van de camera op je telefoon om barcodes te lezen en op te zoeken productinformatie, zoals prijzen en reviews.
+
+
Het leest ook 2D barcodes zoals QR Codes en Data Matrix. Deze kunnen links naar websites bevatten, contactgegevens zoals telefoonnummers en e-mailadressen, en nog veel meer.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/scanning.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/scanning.html
new file mode 100644
index 00000000..b9e61394
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/scanning.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Hoe om te scannen
+
+
+
+
Barcode Scanner scant continu een vierkant gebied op uw scherm - net line-up van de telefoon, zodat de barcode is helemaal in de zoeker rechthoek:
+
+
1D barcodes zoals die gevonden op producten vereisen een telefoon met autofocus. Zonder dat zal alleen maar QR Codes en Data Matrix codes zijn leesbaar.
+
Wanneer een barcode wordt gelezen, zal een pieptoon te spelen en zie je de resultaten van de scan, een beschrijving van wat de barcode bevat, en opties om actie te ondernemen op de inhoud.
+
Als u problemen ondervindt bij het scannen, moet u Houd de telefoon stil. Als de camera niet kan scherpstellen, probeer dan het verplaatsen van de telefoon verder of dichter van de barcode.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/sharing.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/sharing.html
new file mode 100644
index 00000000..c4c635f2
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/sharing.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Hoe kan ik QR Codes te creëren
+
+
+
+
In aanvulling op het scannen van 2D-barcodes, kan Barcode Scanner ook het genereren van een QR-code en geeft deze weer op het scherm. Dan kunt u laten zien aan een vriend, en laat ze de streepjescode scannen met hun telefoon:
+
+
Om deze functie te gebruiken, drukt u op de knop Menu van de belangrijkste scannen scherm en tik op Delen. Vervolgens kiest u of u een contact, een bladwijzer, een toepassing, of de inhoud van het klembord te delen. Een QR-code wordt automatisch gegenereerd. Als u klaar bent, drukt u op Terug of Home.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/whatsnew.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/whatsnew.html
new file mode 100644
index 00000000..aa7b6d4f
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-nl/whatsnew.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Wat is nieuw in Barcode Scanner
+
+
+
+
Nieuw in versie 4.3.1:
+
+
Uitgeschakeld blootstelling beheersing als het veroorzaakt problemen op meerdere buggy apparaten
+
Andere kleine bugfixes
+
+
Vertaald door Google Translate.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/about1d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/about1d.html
new file mode 100644
index 00000000..1a4e5575
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/about1d.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Sobre códigos de barras 1D
+
+
+
+
Estes códigos de barras 1D conter um código único, o qual geralmente descreve um produto, como um CD ou um livro. Você pode olhar este código na internet para pesquisar preços, opiniões, e muito mais.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/about2d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/about2d.html
new file mode 100644
index 00000000..dd6fa0f2
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/about2d.html
@@ -0,0 +1,26 @@
+
+
+
+
+ Sobre códigos de barras 2D
+
+
+
+
Códigos de barras 1D como os encontrados em produtos necessitam de um telefone com foco automático. Sem ele, apenas QR Codes e códigos Data Matrix será legÃvel.
Se você está tendo problemas de digitalização, certifique-se de segurar o telefone fixo. Se a câmera não consegue focar, tente mover o telefone mais próximo ou a partir do código de barras.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/sharing.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/sharing.html
new file mode 100644
index 00000000..655967bf
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/sharing.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Como criar QR Codes
+
+
+
+
Para usar esse recurso, pressione o botão Menu a partir do ecrã de digitalização principal e toque em Compartilhar. Em seguida, escolha se você deseja compartilhar um contato, um marcador, um aplicativo, ou o conteúdo da área de transferência. Um QR Code será gerado automaticamente. Quando estiver pronto, pressione Voltar ou Casa.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/whatsnew.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/whatsnew.html
new file mode 100644
index 00000000..34398279
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-pt/whatsnew.html
@@ -0,0 +1,15 @@
+
+
+
+
+ O que há de novo no Barcode Scanner
+
+
+
+
Novo na versão 4.3.1:
+
+
Desativado controle de exposição, uma vez que causou problemas em dispositivos de buggy vários
+
Outras pequenas correções de bugs
+
+
Traduzido pelo Google Translate.
+
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-ru/about1d.html b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-ru/about1d.html
new file mode 100644
index 00000000..1ba439fe
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/assets/html-ru/about1d.html
@@ -0,0 +1,15 @@
+
+
+
+
+ О 1D штрих-кодов
+
+
+
+
Encapsulates the result of decoding a barcode within an image.
+ *
+ * @author Sean Owen
+ */
+public final class Result {
+
+ private final String text;
+ private final byte[] rawBytes;
+ private ResultPoint[] resultPoints;
+ private final BarcodeFormat format;
+ private Map resultMetadata;
+ private final long timestamp;
+
+ public Result(String text,
+ byte[] rawBytes,
+ ResultPoint[] resultPoints,
+ BarcodeFormat format) {
+ this(text, rawBytes, resultPoints, format, System.currentTimeMillis());
+ }
+
+ public Result(String text,
+ byte[] rawBytes,
+ ResultPoint[] resultPoints,
+ BarcodeFormat format,
+ long timestamp) {
+ this.text = text;
+ this.rawBytes = rawBytes;
+ this.resultPoints = resultPoints;
+ this.format = format;
+ this.resultMetadata = null;
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * @return raw text encoded by the barcode
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * @return raw bytes encoded by the barcode, if applicable, otherwise {@code null}
+ */
+ public byte[] getRawBytes() {
+ return rawBytes;
+ }
+
+ /**
+ * @return points related to the barcode in the image. These are typically points
+ * identifying finder patterns or the corners of the barcode. The exact meaning is
+ * specific to the type of barcode that was decoded.
+ */
+ public ResultPoint[] getResultPoints() {
+ return resultPoints;
+ }
+
+ /**
+ * @return {@link BarcodeFormat} representing the format of the barcode that was decoded
+ */
+ public BarcodeFormat getBarcodeFormat() {
+ return format;
+ }
+
+ /**
+ * @return {@link Map} mapping {@link ResultMetadataType} keys to values. May be
+ * {@code null}. This contains optional metadata about what was detected about the barcode,
+ * like orientation.
+ */
+ public Map getResultMetadata() {
+ return resultMetadata;
+ }
+
+ public void putMetadata(ResultMetadataType type, Object value) {
+ if (resultMetadata == null) {
+ resultMetadata = new EnumMap(ResultMetadataType.class);
+ }
+ resultMetadata.put(type, value);
+ }
+
+ public void putAllMetadata(Map metadata) {
+ if (metadata != null) {
+ if (resultMetadata == null) {
+ resultMetadata = metadata;
+ } else {
+ resultMetadata.putAll(metadata);
+ }
+ }
+ }
+
+ public void addResultPoints(ResultPoint[] newPoints) {
+ ResultPoint[] oldPoints = resultPoints;
+ if (oldPoints == null) {
+ resultPoints = newPoints;
+ } else if (newPoints != null && newPoints.length > 0) {
+ ResultPoint[] allPoints = new ResultPoint[oldPoints.length + newPoints.length];
+ System.arraycopy(oldPoints, 0, allPoints, 0, oldPoints.length);
+ System.arraycopy(newPoints, 0, allPoints, oldPoints.length, newPoints.length);
+ resultPoints = allPoints;
+ }
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultMetadataType.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultMetadataType.java
new file mode 100644
index 00000000..32cc7c99
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultMetadataType.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing;
+
+/**
+ * Represents some type of metadata about the result of the decoding that the decoder
+ * wishes to communicate back to the caller.
+ *
+ * @author Sean Owen
+ */
+public enum ResultMetadataType {
+
+ /**
+ * Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
+ */
+ OTHER,
+
+ /**
+ * Denotes the likely approximate orientation of the barcode in the image. This value
+ * is given as degrees rotated clockwise from the normal, upright orientation.
+ * For example a 1D barcode which was found by reading top-to-bottom would be
+ * said to have orientation "90". This key maps to an {@link Integer} whose
+ * value is in the range [0,360).
+ */
+ ORIENTATION,
+
+ /**
+ *
2D barcode formats typically encode text, but allow for a sort of 'byte mode'
+ * which is sometimes used to encode binary data. While {@link Result} makes available
+ * the complete raw bytes in the barcode for these formats, it does not offer the bytes
+ * from the byte segments alone.
+ *
+ *
This maps to a {@link java.util.List} of byte arrays corresponding to the
+ * raw bytes in the byte segments in the barcode, in order.
+ */
+ BYTE_SEGMENTS,
+
+ /**
+ * Error correction level used, if applicable. The value type depends on the
+ * format, but is typically a String.
+ */
+ ERROR_CORRECTION_LEVEL,
+
+ /**
+ * For some periodicals, indicates the issue number as an {@link Integer}.
+ */
+ ISSUE_NUMBER,
+
+ /**
+ * For some products, indicates the suggested retail price in the barcode as a
+ * formatted {@link String}.
+ */
+ SUGGESTED_PRICE ,
+
+ /**
+ * For some products, the possible country of manufacture as a {@link String} denoting the
+ * ISO country code. Some map to multiple possible countries, like "US/CA".
+ */
+ POSSIBLE_COUNTRY,
+
+ /**
+ * For some products, the extension text
+ */
+ UPC_EAN_EXTENSION,
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultPoint.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultPoint.java
new file mode 100644
index 00000000..a69d9c0c
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultPoint.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2007 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing;
+
+import com.google.zxing.common.detector.MathUtils;
+
+/**
+ *
Encapsulates a point of interest in an image containing a barcode. Typically, this
+ * would be the location of a finder pattern or the corner of the barcode, for example.
+ *
+ * @author Sean Owen
+ */
+public class ResultPoint {
+
+ private final float x;
+ private final float y;
+
+ public ResultPoint(float x, float y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public final float getX() {
+ return x;
+ }
+
+ public final float getY() {
+ return y;
+ }
+
+ @Override
+ public final boolean equals(Object other) {
+ if (other instanceof ResultPoint) {
+ ResultPoint otherPoint = (ResultPoint) other;
+ return x == otherPoint.x && y == otherPoint.y;
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return 31 * Float.floatToIntBits(x) + Float.floatToIntBits(y);
+ }
+
+ @Override
+ public final String toString() {
+ StringBuilder result = new StringBuilder(25);
+ result.append('(');
+ result.append(x);
+ result.append(',');
+ result.append(y);
+ result.append(')');
+ return result.toString();
+ }
+
+ /**
+ *
Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
+ * BC < AC and the angle between BC and BA is less than 180 degrees.
+ */
+ public static void orderBestPatterns(ResultPoint[] patterns) {
+
+ // Find distances between pattern centers
+ float zeroOneDistance = distance(patterns[0], patterns[1]);
+ float oneTwoDistance = distance(patterns[1], patterns[2]);
+ float zeroTwoDistance = distance(patterns[0], patterns[2]);
+
+ ResultPoint pointA;
+ ResultPoint pointB;
+ ResultPoint pointC;
+ // Assume one closest to other two is B; A and C will just be guesses at first
+ if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
+ pointB = patterns[0];
+ pointA = patterns[1];
+ pointC = patterns[2];
+ } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
+ pointB = patterns[1];
+ pointA = patterns[0];
+ pointC = patterns[2];
+ } else {
+ pointB = patterns[2];
+ pointA = patterns[0];
+ pointC = patterns[1];
+ }
+
+ // Use cross product to figure out whether A and C are correct or flipped.
+ // This asks whether BC x BA has a positive z component, which is the arrangement
+ // we want for A, B, C. If it's negative, then we've got it flipped around and
+ // should swap A and C.
+ if (crossProductZ(pointA, pointB, pointC) < 0.0f) {
+ ResultPoint temp = pointA;
+ pointA = pointC;
+ pointC = temp;
+ }
+
+ patterns[0] = pointA;
+ patterns[1] = pointB;
+ patterns[2] = pointC;
+ }
+
+
+ /**
+ * @return distance between two points
+ */
+ public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
+ return MathUtils.distance(pattern1.x, pattern1.y, pattern2.x, pattern2.y);
+ }
+
+ /**
+ * Returns the z component of the cross product between vectors BC and BA.
+ */
+ private static float crossProductZ(ResultPoint pointA,
+ ResultPoint pointB,
+ ResultPoint pointC) {
+ float bX = pointB.x;
+ float bY = pointB.y;
+ return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
+ }
+
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultPointCallback.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultPointCallback.java
new file mode 100644
index 00000000..0c85410b
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/ResultPointCallback.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing;
+
+/**
+ * Callback which is invoked when a possible result point (significant
+ * point in the barcode image such as a corner) is found.
+ *
+ * @see DecodeHintType#NEED_RESULT_POINT_CALLBACK
+ */
+public interface ResultPointCallback {
+
+ void foundPossibleResultPoint(ResultPoint point);
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/Writer.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/Writer.java
new file mode 100644
index 00000000..db1887d7
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/Writer.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing;
+
+import com.google.zxing.common.BitMatrix;
+
+import java.util.Map;
+
+/**
+ * The base class for all objects which encode/generate a barcode image.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public interface Writer {
+
+ /**
+ * Encode a barcode using the default settings.
+ *
+ * @param contents The contents to encode in the barcode
+ * @param format The barcode format to generate
+ * @param width The preferred width in pixels
+ * @param height The preferred height in pixels
+ */
+ BitMatrix encode(String contents, BarcodeFormat format, int width, int height)
+ throws WriterException;
+
+ /**
+ *
+ * @param contents The contents to encode in the barcode
+ * @param format The barcode format to generate
+ * @param width The preferred width in pixels
+ * @param height The preferred height in pixels
+ * @param hints Additional parameters to supply to the encoder
+ */
+ BitMatrix encode(String contents,
+ BarcodeFormat format,
+ int width,
+ int height,
+ Map hints)
+ throws WriterException;
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/WriterException.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/WriterException.java
new file mode 100644
index 00000000..c61800b9
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/WriterException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing;
+
+/**
+ * A base class which covers the range of exceptions which may occur when encoding a barcode using
+ * the Writer framework.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class WriterException extends Exception {
+
+ public WriterException() {
+ }
+
+ public WriterException(String message) {
+ super(message);
+ }
+
+ public WriterException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/AztecDetectorResult.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/AztecDetectorResult.java
new file mode 100644
index 00000000..ee27af8a
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/AztecDetectorResult.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.aztec;
+
+import com.google.zxing.ResultPoint;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.DetectorResult;
+
+public final class AztecDetectorResult extends DetectorResult {
+
+ private final boolean compact;
+ private final int nbDatablocks;
+ private final int nbLayers;
+
+ public AztecDetectorResult(BitMatrix bits,
+ ResultPoint[] points,
+ boolean compact,
+ int nbDatablocks,
+ int nbLayers) {
+ super(bits, points);
+ this.compact = compact;
+ this.nbDatablocks = nbDatablocks;
+ this.nbLayers = nbLayers;
+ }
+
+ public int getNbLayers() {
+ return nbLayers;
+ }
+
+ public int getNbDatablocks() {
+ return nbDatablocks;
+ }
+
+ public boolean isCompact() {
+ return compact;
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/AztecReader.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/AztecReader.java
new file mode 100644
index 00000000..fd7b4453
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/AztecReader.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.aztec;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.FormatException;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.Reader;
+import com.google.zxing.Result;
+import com.google.zxing.ResultMetadataType;
+import com.google.zxing.ResultPoint;
+import com.google.zxing.ResultPointCallback;
+import com.google.zxing.common.DecoderResult;
+import com.google.zxing.aztec.decoder.Decoder;
+import com.google.zxing.aztec.detector.Detector;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This implementation can detect and decode Aztec codes in an image.
+ *
+ * @author David Olivier
+ */
+public final class AztecReader implements Reader {
+
+ /**
+ * Locates and decodes a Data Matrix code in an image.
+ *
+ * @return a String representing the content encoded by the Data Matrix code
+ * @throws NotFoundException if a Data Matrix code cannot be found
+ * @throws FormatException if a Data Matrix code cannot be decoded
+ * @throws com.google.zxing.ChecksumException if error correction fails
+ */
+ @Override
+ public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {
+ return decode(image, null);
+ }
+
+ @Override
+ public Result decode(BinaryBitmap image, Map hints)
+ throws NotFoundException, FormatException {
+
+ AztecDetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();
+ ResultPoint[] points = detectorResult.getPoints();
+
+ if (hints != null) {
+ ResultPointCallback rpcb = (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
+ if (rpcb != null) {
+ for (ResultPoint point : points) {
+ rpcb.foundPossibleResultPoint(point);
+ }
+ }
+ }
+
+ DecoderResult decoderResult = new Decoder().decode(detectorResult);
+
+ Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.AZTEC);
+
+ List byteSegments = decoderResult.getByteSegments();
+ if (byteSegments != null) {
+ result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
+ }
+ String ecLevel = decoderResult.getECLevel();
+ if (ecLevel != null) {
+ result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
+ }
+
+ return result;
+ }
+
+ @Override
+ public void reset() {
+ // do nothing
+ }
+
+}
\ No newline at end of file
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/decoder/Decoder.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/decoder/Decoder.java
new file mode 100644
index 00000000..5f5667e1
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/decoder/Decoder.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.aztec.decoder;
+
+import com.google.zxing.FormatException;
+import com.google.zxing.aztec.AztecDetectorResult;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.DecoderResult;
+import com.google.zxing.common.reedsolomon.GenericGF;
+import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
+import com.google.zxing.common.reedsolomon.ReedSolomonException;
+
+/**
+ *
The main class which implements Aztec Code decoding -- as opposed to locating and extracting
+ * the Aztec Code from an image.
+ *
+ * @return the corrected array
+ * @throws FormatException if the input contains too many errors
+ */
+ private boolean[] correctBits(boolean[] rawbits) throws FormatException {
+ GenericGF gf;
+
+ if (ddata.getNbLayers() <= 2) {
+ codewordSize = 6;
+ gf = GenericGF.AZTEC_DATA_6;
+ } else if (ddata.getNbLayers() <= 8) {
+ codewordSize = 8;
+ gf = GenericGF.AZTEC_DATA_8;
+ } else if (ddata.getNbLayers() <= 22) {
+ codewordSize = 10;
+ gf = GenericGF.AZTEC_DATA_10;
+ } else {
+ codewordSize = 12;
+ gf = GenericGF.AZTEC_DATA_12;
+ }
+
+ int numDataCodewords = ddata.getNbDatablocks();
+ int numECCodewords;
+ int offset;
+
+ if (ddata.isCompact()) {
+ offset = NB_BITS_COMPACT[ddata.getNbLayers()] - numCodewords * codewordSize;
+ numECCodewords = NB_DATABLOCK_COMPACT[ddata.getNbLayers()] - numDataCodewords;
+ } else {
+ offset = NB_BITS[ddata.getNbLayers()] - numCodewords * codewordSize;
+ numECCodewords = NB_DATABLOCK[ddata.getNbLayers()] - numDataCodewords;
+ }
+
+ int[] dataWords = new int[numCodewords];
+ for (int i = 0; i < numCodewords; i++) {
+ int flag = 1;
+ for (int j = 1; j <= codewordSize; j++) {
+ if (rawbits[codewordSize * i + codewordSize - j + offset]) {
+ dataWords[i] += flag;
+ }
+ flag <<= 1;
+ }
+
+ //if (dataWords[i] >= flag) {
+ // flag++;
+ //}
+ }
+
+ try {
+ ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(gf);
+ rsDecoder.decode(dataWords, numECCodewords);
+ } catch (ReedSolomonException rse) {
+ throw FormatException.getFormatInstance();
+ }
+
+ offset = 0;
+ invertedBitCount = 0;
+
+ boolean[] correctedBits = new boolean[numDataCodewords * codewordSize];
+ for (int i = 0; i < numDataCodewords; i++) {
+
+ boolean seriesColor = false;
+ int seriesCount = 0;
+ int flag = 1 << (codewordSize - 1);
+
+ for (int j = 0; j < codewordSize; j++) {
+
+ boolean color = (dataWords[i] & flag) == flag;
+
+ if (seriesCount == codewordSize - 1) {
+
+ if (color == seriesColor) {
+ //bit must be inverted
+ throw FormatException.getFormatInstance();
+ }
+
+ seriesColor = false;
+ seriesCount = 0;
+ offset++;
+ invertedBitCount++;
+ } else {
+
+ if (seriesColor == color) {
+ seriesCount++;
+ } else {
+ seriesCount = 1;
+ seriesColor = color;
+ }
+
+ correctedBits[i * codewordSize + j - offset] = color;
+
+ }
+
+ flag >>>= 1;
+ }
+ }
+
+ return correctedBits;
+ }
+
+ /**
+ * Gets the array of bits from an Aztec Code matrix
+ *
+ * @return the array of bits
+ * @throws FormatException if the matrix is not a valid aztec code
+ */
+ private boolean[] extractBits(BitMatrix matrix) throws FormatException {
+
+ boolean[] rawbits;
+ if (ddata.isCompact()) {
+ if (ddata.getNbLayers() > NB_BITS_COMPACT.length) {
+ throw FormatException.getFormatInstance();
+ }
+ rawbits = new boolean[NB_BITS_COMPACT[ddata.getNbLayers()]];
+ numCodewords = NB_DATABLOCK_COMPACT[ddata.getNbLayers()];
+ } else {
+ if (ddata.getNbLayers() > NB_BITS.length) {
+ throw FormatException.getFormatInstance();
+ }
+ rawbits = new boolean[NB_BITS[ddata.getNbLayers()]];
+ numCodewords = NB_DATABLOCK[ddata.getNbLayers()];
+ }
+
+ int layer = ddata.getNbLayers();
+ int size = matrix.getHeight();
+ int rawbitsOffset = 0;
+ int matrixOffset = 0;
+
+ while (layer != 0) {
+
+ int flip = 0;
+ for (int i = 0; i < 2 * size - 4; i++) {
+ rawbits[rawbitsOffset + i] = matrix.get(matrixOffset + flip, matrixOffset + i / 2);
+ rawbits[rawbitsOffset + 2 * size - 4 + i] = matrix.get(matrixOffset + i / 2, matrixOffset + size - 1 - flip);
+ flip = (flip + 1) % 2;
+ }
+
+ flip = 0;
+ for (int i = 2 * size + 1; i > 5; i--) {
+ rawbits[rawbitsOffset + 4 * size - 8 + (2 * size - i) + 1] =
+ matrix.get(matrixOffset + size - 1 - flip, matrixOffset + i / 2 - 1);
+ rawbits[rawbitsOffset + 6 * size - 12 + (2 * size - i) + 1] =
+ matrix.get(matrixOffset + i / 2 - 1, matrixOffset + flip);
+ flip = (flip + 1) % 2;
+ }
+
+ matrixOffset += 2;
+ rawbitsOffset += 8 * size - 16;
+ layer--;
+ size -= 4;
+ }
+
+ return rawbits;
+ }
+
+ /**
+ * Transforms an Aztec code matrix by removing the control dashed lines
+ */
+ private static BitMatrix removeDashedLines(BitMatrix matrix) {
+ int nbDashed = 1 + 2 * ((matrix.getWidth() - 1) / 2 / 16);
+ BitMatrix newMatrix = new BitMatrix(matrix.getWidth() - nbDashed, matrix.getHeight() - nbDashed);
+
+ int nx = 0;
+
+ for (int x = 0; x < matrix.getWidth(); x++) {
+
+ if ((matrix.getWidth() / 2 - x) % 16 == 0) {
+ continue;
+ }
+
+ int ny = 0;
+ for (int y = 0; y < matrix.getHeight(); y++) {
+
+ if ((matrix.getWidth() / 2 - y) % 16 == 0) {
+ continue;
+ }
+
+ if (matrix.get(x, y)) {
+ newMatrix.set(nx, ny);
+ }
+ ny++;
+ }
+ nx++;
+ }
+
+ return newMatrix;
+ }
+
+ /**
+ * Reads a code of given length and at given index in an array of bits
+ */
+ private static int readCode(boolean[] rawbits, int startIndex, int length) {
+ int res = 0;
+
+ for (int i = startIndex; i < startIndex + length; i++) {
+ res <<= 1;
+ if (rawbits[i]) {
+ res++;
+ }
+ }
+
+ return res;
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/detector/Detector.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/detector/Detector.java
new file mode 100644
index 00000000..413a4110
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/aztec/detector/Detector.java
@@ -0,0 +1,624 @@
+/*
+ * Copyright 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.aztec.detector;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.ResultPoint;
+import com.google.zxing.aztec.AztecDetectorResult;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.GridSampler;
+import com.google.zxing.common.detector.MathUtils;
+import com.google.zxing.common.detector.WhiteRectangleDetector;
+import com.google.zxing.common.reedsolomon.GenericGF;
+import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
+import com.google.zxing.common.reedsolomon.ReedSolomonException;
+
+/**
+ *
Encapsulates logic that can detect an Aztec Code in an image, even if the Aztec Code
+ * is rotated or skewed, or partially obscured.
+ *
+ * @author David Olivier
+ */
+public final class Detector {
+
+ private final BitMatrix image;
+
+ private boolean compact;
+ private int nbLayers;
+ private int nbDataBlocks;
+ private int nbCenterLayers;
+ private int shift;
+
+ public Detector(BitMatrix image) {
+ this.image = image;
+ }
+
+ /**
+ *
Detects an Aztec Code in an image.
+ *
+ * @return {@link AztecDetectorResult} encapsulating results of detecting an Aztec Code
+ * @throws NotFoundException if no Aztec Code can be found
+ */
+ public AztecDetectorResult detect() throws NotFoundException {
+
+ // 1. Get the center of the aztec matrix
+ Point pCenter = getMatrixCenter();
+
+ // 2. Get the corners of the center bull's eye
+ Point[] bullEyeCornerPoints = getBullEyeCornerPoints(pCenter);
+
+ // 3. Get the size of the matrix from the bull's eye
+ extractParameters(bullEyeCornerPoints);
+
+ // 4. Get the corners of the matrix
+ ResultPoint[] corners = getMatrixCornerPoints(bullEyeCornerPoints);
+
+ // 5. Sample the grid
+ BitMatrix bits = sampleGrid(image, corners[shift%4], corners[(shift+3)%4], corners[(shift+2)%4], corners[(shift+1)%4]);
+
+ return new AztecDetectorResult(bits, corners, compact, nbDataBlocks, nbLayers);
+ }
+
+ /**
+ *
Extracts the number of data layers and data blocks from the layer around the bull's eye
+ *
+ * @param bullEyeCornerPoints the array of bull's eye corners
+ * @throws NotFoundException in case of too many errors or invalid parameters
+ */
+ private void extractParameters(Point[] bullEyeCornerPoints)
+ throws NotFoundException {
+
+ // Get the bits around the bull's eye
+ boolean[] resab = sampleLine(bullEyeCornerPoints[0], bullEyeCornerPoints[1], 2*nbCenterLayers+1);
+ boolean[] resbc = sampleLine(bullEyeCornerPoints[1], bullEyeCornerPoints[2], 2*nbCenterLayers+1);
+ boolean[] rescd = sampleLine(bullEyeCornerPoints[2], bullEyeCornerPoints[3], 2*nbCenterLayers+1);
+ boolean[] resda = sampleLine(bullEyeCornerPoints[3], bullEyeCornerPoints[0], 2*nbCenterLayers+1);
+
+ // Determine the orientation of the matrix
+ if (resab[0] && resab[2 * nbCenterLayers]) {
+ shift = 0;
+ } else if (resbc[0] && resbc[2 * nbCenterLayers]) {
+ shift = 1;
+ } else if (rescd[0] && rescd[2 * nbCenterLayers]) {
+ shift = 2;
+ } else if (resda[0] && resda[2 * nbCenterLayers]) {
+ shift = 3;
+ } else {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ //d a
+ //
+ //c b
+
+ // Flatten the bits in a single array
+ boolean[] parameterData;
+ boolean[] shiftedParameterData;
+ if (compact) {
+ shiftedParameterData = new boolean[28];
+ for (int i = 0; i < 7; i++) {
+ shiftedParameterData[i] = resab[2+i];
+ shiftedParameterData[i+7] = resbc[2+i];
+ shiftedParameterData[i+14] = rescd[2+i];
+ shiftedParameterData[i+21] = resda[2+i];
+ }
+
+ parameterData = new boolean[28];
+ for (int i = 0; i < 28; i++) {
+ parameterData[i] = shiftedParameterData[(i+shift*7)%28];
+ }
+ } else {
+ shiftedParameterData = new boolean[40];
+ for (int i = 0; i < 11; i++) {
+ if (i < 5) {
+ shiftedParameterData[i] = resab[2+i];
+ shiftedParameterData[i+10] = resbc[2+i];
+ shiftedParameterData[i+20] = rescd[2+i];
+ shiftedParameterData[i+30] = resda[2+i];
+ }
+ if (i > 5) {
+ shiftedParameterData[i-1] = resab[2+i];
+ shiftedParameterData[i+10-1] = resbc[2+i];
+ shiftedParameterData[i+20-1] = rescd[2+i];
+ shiftedParameterData[i+30-1] = resda[2+i];
+ }
+ }
+
+ parameterData = new boolean[40];
+ for (int i = 0; i < 40; i++) {
+ parameterData[i] = shiftedParameterData[(i+shift*10)%40];
+ }
+ }
+
+ // corrects the error using RS algorithm
+ correctParameterData(parameterData, compact);
+
+ // gets the parameters from the bit array
+ getParameters(parameterData);
+ }
+
+ /**
+ *
+ *
Gets the Aztec code corners from the bull's eye corners and the parameters
+ *
+ * @param bullEyeCornerPoints the array of bull's eye corners
+ * @return the array of aztec code corners
+ * @throws NotFoundException if the corner points do not fit in the image
+ */
+ private ResultPoint[] getMatrixCornerPoints(Point[] bullEyeCornerPoints) throws NotFoundException {
+
+ float ratio = (2 * nbLayers + (nbLayers > 4 ? 1 : 0) + (nbLayers - 4) / 8)
+ / (2.0f * nbCenterLayers);
+
+ int dx = bullEyeCornerPoints[0].x-bullEyeCornerPoints[2].x;
+ dx+=dx>0?1:-1;
+ int dy = bullEyeCornerPoints[0].y-bullEyeCornerPoints[2].y;
+ dy+=dy>0?1:-1;
+
+ int targetcx = MathUtils.round(bullEyeCornerPoints[2].x - ratio * dx);
+ int targetcy = MathUtils.round(bullEyeCornerPoints[2].y - ratio * dy);
+
+ int targetax = MathUtils.round(bullEyeCornerPoints[0].x + ratio * dx);
+ int targetay = MathUtils.round(bullEyeCornerPoints[0].y + ratio * dy);
+
+ dx = bullEyeCornerPoints[1].x-bullEyeCornerPoints[3].x;
+ dx+=dx>0?1:-1;
+ dy = bullEyeCornerPoints[1].y-bullEyeCornerPoints[3].y;
+ dy+=dy>0?1:-1;
+
+ int targetdx = MathUtils.round(bullEyeCornerPoints[3].x - ratio * dx);
+ int targetdy = MathUtils.round(bullEyeCornerPoints[3].y - ratio * dy);
+ int targetbx = MathUtils.round(bullEyeCornerPoints[1].x + ratio * dx);
+ int targetby = MathUtils.round(bullEyeCornerPoints[1].y+ratio*dy);
+
+ if (!isValid(targetax, targetay) || !isValid(targetbx, targetby) || !isValid(targetcx, targetcy) || !isValid(targetdx, targetdy)) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ return new ResultPoint[]{new ResultPoint(targetax, targetay), new ResultPoint(targetbx, targetby), new ResultPoint(targetcx, targetcy), new ResultPoint(targetdx, targetdy)};
+ }
+
+ /**
+ *
+ *
Corrects the parameter bits using Reed-Solomon algorithm
+ *
+ * @param parameterData paremeter bits
+ * @param compact true if this is a compact Aztec code
+ * @throws NotFoundException if the array contains too many errors
+ */
+ private static void correctParameterData(boolean[] parameterData, boolean compact) throws NotFoundException {
+
+ int numCodewords;
+ int numDataCodewords;
+
+ if (compact) {
+ numCodewords = 7;
+ numDataCodewords = 2;
+ } else {
+ numCodewords = 10;
+ numDataCodewords = 4;
+ }
+
+ int numECCodewords = numCodewords - numDataCodewords;
+ int[] parameterWords = new int[numCodewords];
+
+ int codewordSize = 4;
+ for (int i = 0; i < numCodewords; i++) {
+ int flag = 1;
+ for (int j = 1; j <= codewordSize; j++) {
+ if (parameterData[codewordSize*i + codewordSize - j]) {
+ parameterWords[i] += flag;
+ }
+ flag <<= 1;
+ }
+ }
+
+ try {
+ ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM);
+ rsDecoder.decode(parameterWords, numECCodewords);
+ } catch (ReedSolomonException rse) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ for (int i = 0; i < numDataCodewords; i ++) {
+ int flag = 1;
+ for (int j = 1; j <= codewordSize; j++) {
+ parameterData[i*codewordSize+codewordSize-j] = (parameterWords[i] & flag) == flag;
+ flag <<= 1;
+ }
+ }
+ }
+
+ /**
+ *
+ *
Finds the corners of a bull-eye centered on the passed point
+ *
+ * @param pCenter Center point
+ * @return The corners of the bull-eye
+ * @throws NotFoundException If no valid bull-eye can be found
+ */
+ private Point[] getBullEyeCornerPoints(Point pCenter) throws NotFoundException {
+
+ Point pina = pCenter;
+ Point pinb = pCenter;
+ Point pinc = pCenter;
+ Point pind = pCenter;
+
+ boolean color = true;
+
+ for (nbCenterLayers = 1; nbCenterLayers < 9; nbCenterLayers++) {
+ Point pouta = getFirstDifferent(pina, color, 1, -1);
+ Point poutb = getFirstDifferent(pinb, color, 1, 1);
+ Point poutc = getFirstDifferent(pinc, color, -1, 1);
+ Point poutd = getFirstDifferent(pind, color, -1, -1);
+
+ //d a
+ //
+ //c b
+
+ if (nbCenterLayers>2) {
+ float q = distance(poutd, pouta)*nbCenterLayers/(distance(pind, pina)*(nbCenterLayers+2));
+ if ( q < 0.75 || q > 1.25 || !isWhiteOrBlackRectangle(pouta, poutb, poutc, poutd)) {
+ break;
+ }
+ }
+
+ pina = pouta;
+ pinb = poutb;
+ pinc = poutc;
+ pind = poutd;
+
+ color = !color;
+ }
+
+ if (nbCenterLayers != 5 && nbCenterLayers != 7) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ compact = nbCenterLayers==5;
+
+ float ratio = 0.75f*2/(2*nbCenterLayers-3);
+
+ int dx = pina.x-pinc.x;
+ int dy = pina.y-pinc.y;
+ int targetcx = MathUtils.round(pinc.x-ratio*dx);
+ int targetcy = MathUtils.round(pinc.y-ratio*dy);
+ int targetax = MathUtils.round(pina.x+ratio*dx);
+ int targetay = MathUtils.round(pina.y+ratio*dy);
+
+ dx = pinb.x-pind.x;
+ dy = pinb.y-pind.y;
+
+ int targetdx = MathUtils.round(pind.x-ratio*dx);
+ int targetdy = MathUtils.round(pind.y-ratio*dy);
+ int targetbx = MathUtils.round(pinb.x+ratio*dx);
+ int targetby = MathUtils.round(pinb.y+ratio*dy);
+
+ if (!isValid(targetax, targetay) || !isValid(targetbx, targetby)
+ || !isValid(targetcx, targetcy) || !isValid(targetdx, targetdy)) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ Point pa = new Point(targetax,targetay);
+ Point pb = new Point(targetbx,targetby);
+ Point pc = new Point(targetcx,targetcy);
+ Point pd = new Point(targetdx,targetdy);
+
+ return new Point[]{pa, pb, pc, pd};
+ }
+
+ /**
+ *
+ * Finds a candidate center point of an Aztec code from an image
+ *
+ * @return the center point
+ */
+ private Point getMatrixCenter() {
+
+ ResultPoint pointA;
+ ResultPoint pointB;
+ ResultPoint pointC;
+ ResultPoint pointD;
+
+ //Get a white rectangle that can be the border of the matrix in center bull's eye or
+ try {
+
+ ResultPoint[] cornerPoints = new WhiteRectangleDetector(image).detect();
+ pointA = cornerPoints[0];
+ pointB = cornerPoints[1];
+ pointC = cornerPoints[2];
+ pointD = cornerPoints[3];
+
+ } catch (NotFoundException e) {
+
+ // This exception can be in case the initial rectangle is white
+ // In that case, surely in the bull's eye, we try to expand the rectangle.
+ int cx = image.getWidth()/2;
+ int cy = image.getHeight()/2;
+ pointA = getFirstDifferent(new Point(cx+15/2, cy-15/2), false, 1, -1).toResultPoint();
+ pointB = getFirstDifferent(new Point(cx+15/2, cy+15/2), false, 1, 1).toResultPoint();
+ pointC = getFirstDifferent(new Point(cx-15/2, cy+15/2), false, -1, 1).toResultPoint();
+ pointD = getFirstDifferent(new Point(cx-15/2, cy-15/2), false, -1, -1).toResultPoint();
+
+ }
+
+ //Compute the center of the rectangle
+ int cx = MathUtils.round((pointA.getX() + pointD.getX() + pointB.getX() + pointC.getX())/4);
+ int cy = MathUtils.round((pointA.getY() + pointD.getY() + pointB.getY() + pointC.getY())/4);
+
+ // Redetermine the white rectangle starting from previously computed center.
+ // This will ensure that we end up with a white rectangle in center bull's eye
+ // in order to compute a more accurate center.
+ try {
+ ResultPoint[] cornerPoints = new WhiteRectangleDetector(image, 15, cx, cy).detect();
+ pointA = cornerPoints[0];
+ pointB = cornerPoints[1];
+ pointC = cornerPoints[2];
+ pointD = cornerPoints[3];
+ } catch (NotFoundException e) {
+
+ // This exception can be in case the initial rectangle is white
+ // In that case we try to expand the rectangle.
+ pointA = getFirstDifferent(new Point(cx+15/2, cy-15/2), false, 1, -1).toResultPoint();
+ pointB = getFirstDifferent(new Point(cx+15/2, cy+15/2), false, 1, 1).toResultPoint();
+ pointC = getFirstDifferent(new Point(cx-15/2, cy+15/2), false, -1, 1).toResultPoint();
+ pointD = getFirstDifferent(new Point(cx-15/2, cy-15/2), false, -1, -1).toResultPoint();
+
+ }
+
+ // Recompute the center of the rectangle
+ cx = MathUtils.round((pointA.getX() + pointD.getX() + pointB.getX() + pointC.getX())/4);
+ cy = MathUtils.round((pointA.getY() + pointD.getY() + pointB.getY() + pointC.getY())/4);
+
+ return new Point(cx, cy);
+ }
+
+ /**
+ * Samples an Aztec matrix from an image
+ */
+ private BitMatrix sampleGrid(BitMatrix image,
+ ResultPoint topLeft,
+ ResultPoint bottomLeft,
+ ResultPoint bottomRight,
+ ResultPoint topRight) throws NotFoundException {
+
+ int dimension;
+ if (compact) {
+ dimension = 4*nbLayers+11;
+ } else {
+ if (nbLayers <= 4) {
+ dimension = 4*nbLayers + 15;
+ } else {
+ dimension = 4*nbLayers + 2*((nbLayers-4)/8 + 1) + 15 ;
+ }
+ }
+
+ GridSampler sampler = GridSampler.getInstance();
+
+ return sampler.sampleGrid(image,
+ dimension,
+ dimension,
+ 0.5f,
+ 0.5f,
+ dimension - 0.5f,
+ 0.5f,
+ dimension - 0.5f,
+ dimension - 0.5f,
+ 0.5f,
+ dimension - 0.5f,
+ topLeft.getX(),
+ topLeft.getY(),
+ topRight.getX(),
+ topRight.getY(),
+ bottomRight.getX(),
+ bottomRight.getY(),
+ bottomLeft.getX(),
+ bottomLeft.getY());
+ }
+
+ /**
+ * Sets number of layers and number of datablocks from parameter bits
+ */
+ private void getParameters(boolean[] parameterData) {
+
+ int nbBitsForNbLayers;
+ int nbBitsForNbDatablocks;
+
+ if (compact) {
+ nbBitsForNbLayers = 2;
+ nbBitsForNbDatablocks = 6;
+ } else {
+ nbBitsForNbLayers = 5;
+ nbBitsForNbDatablocks = 11;
+ }
+
+ for (int i = 0; i < nbBitsForNbLayers; i++) {
+ nbLayers <<= 1;
+ if (parameterData[i]) {
+ nbLayers += 1;
+ }
+ }
+
+ for (int i = nbBitsForNbLayers; i < nbBitsForNbLayers + nbBitsForNbDatablocks; i++) {
+ nbDataBlocks <<= 1;
+ if (parameterData[i]) {
+ nbDataBlocks += 1;
+ }
+ }
+
+ nbLayers ++;
+ nbDataBlocks ++;
+
+ }
+
+ /**
+ *
+ * Samples a line
+ *
+ * @param p1 first point
+ * @param p2 second point
+ * @param size number of bits
+ * @return the array of bits
+ */
+ private boolean[] sampleLine(Point p1, Point p2, int size) {
+
+ boolean[] res = new boolean[size];
+ float d = distance(p1,p2);
+ float moduleSize = d/(size-1);
+ float dx = moduleSize*(p2.x - p1.x)/d;
+ float dy = moduleSize*(p2.y - p1.y)/d;
+
+ float px = p1.x;
+ float py = p1.y;
+
+ for (int i = 0; i < size; i++) {
+ res[i] = image.get(MathUtils.round(px), MathUtils.round(py));
+ px+=dx;
+ py+=dy;
+ }
+
+ return res;
+ }
+
+ /**
+ * @return true if the border of the rectangle passed in parameter is compound of white points only
+ * or black points only
+ */
+ private boolean isWhiteOrBlackRectangle(Point p1,
+ Point p2,
+ Point p3,
+ Point p4) {
+
+ int corr = 3;
+
+ p1 = new Point(p1.x-corr, p1.y+corr);
+ p2 = new Point(p2.x-corr, p2.y-corr);
+ p3 = new Point(p3.x+corr, p3.y-corr);
+ p4 = new Point(p4.x+corr, p4.y+corr);
+
+ int cInit = getColor(p4, p1);
+
+ if (cInit == 0) {
+ return false;
+ }
+
+ int c = getColor(p1, p2);
+
+ if (c != cInit) {
+ return false;
+ }
+
+ c = getColor(p2, p3);
+
+ if (c != cInit) {
+ return false;
+ }
+
+ c = getColor(p3, p4);
+
+ return c == cInit;
+
+ }
+
+ /**
+ * Gets the color of a segment
+ *
+ * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else
+ */
+ private int getColor(Point p1, Point p2) {
+ float d = distance(p1,p2);
+ float dx = (p2.x - p1.x)/d;
+ float dy = (p2.y - p1.y)/d;
+ int error = 0;
+
+ float px = p1.x;
+ float py = p1.y;
+
+ boolean colorModel = image.get(p1.x, p1.y);
+
+ for (int i = 0; i < d; i++) {
+ px+=dx;
+ py+=dy;
+ if (image.get(MathUtils.round(px), MathUtils.round(py)) != colorModel) {
+ error++;
+ }
+ }
+
+ float errRatio = (float)error/d;
+
+ if (errRatio > 0.1 && errRatio < 0.9) {
+ return 0;
+ }
+
+ if (errRatio <= 0.1) {
+ return colorModel?1:-1;
+ } else {
+ return colorModel?-1:1;
+ }
+ }
+
+ /**
+ * Gets the coordinate of the first point with a different color in the given direction
+ */
+ private Point getFirstDifferent(Point init, boolean color, int dx, int dy) {
+ int x = init.x+dx;
+ int y = init.y+dy;
+
+ while(isValid(x,y) && image.get(x,y) == color) {
+ x+=dx;
+ y+=dy;
+ }
+
+ x-=dx;
+ y-=dy;
+
+ while(isValid(x,y) && image.get(x, y) == color) {
+ x+=dx;
+ }
+ x-=dx;
+
+ while(isValid(x,y) && image.get(x, y) == color) {
+ y+=dy;
+ }
+ y-=dy;
+
+ return new Point(x,y);
+ }
+
+ private static final class Point {
+ public final int x;
+ public final int y;
+
+ public ResultPoint toResultPoint() {
+ return new ResultPoint(x, y);
+ }
+
+ private Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ }
+
+ private boolean isValid(int x, int y) {
+ return x >= 0 && x < image.getWidth() && y > 0 && y < image.getHeight();
+ }
+
+ private static float distance(Point a, Point b) {
+ return MathUtils.distance(a.x, a.y, b.x, b.y);
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/BeepManager.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/BeepManager.java
new file mode 100644
index 00000000..d6ae0948
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/BeepManager.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.AssetFileDescriptor;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.Vibrator;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Manages beeps and vibrations for {@link CaptureActivity}.
+ */
+final class BeepManager {
+
+ private static final String TAG = BeepManager.class.getSimpleName();
+
+ private static final float BEEP_VOLUME = 0.10f;
+ private static final long VIBRATE_DURATION = 200L;
+
+ private final Activity activity;
+ private MediaPlayer mediaPlayer;
+ private boolean playBeep;
+ private boolean vibrate;
+
+ BeepManager(Activity activity) {
+ this.activity = activity;
+ this.mediaPlayer = null;
+ updatePrefs();
+ }
+
+ void updatePrefs() {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+ playBeep = shouldBeep(prefs, activity);
+ vibrate = prefs.getBoolean(PreferencesActivity.KEY_VIBRATE, false);
+ if (playBeep && mediaPlayer == null) {
+ // The volume on STREAM_SYSTEM is not adjustable, and users found it too loud,
+ // so we now play on the music stream.
+ activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
+ mediaPlayer = buildMediaPlayer(activity);
+ }
+ }
+
+ void playBeepSoundAndVibrate() {
+ if (playBeep && mediaPlayer != null) {
+ mediaPlayer.start();
+ }
+ if (vibrate) {
+ Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
+ vibrator.vibrate(VIBRATE_DURATION);
+ }
+ }
+
+ private static boolean shouldBeep(SharedPreferences prefs, Context activity) {
+ boolean shouldPlayBeep = prefs.getBoolean(PreferencesActivity.KEY_PLAY_BEEP, true);
+ if (shouldPlayBeep) {
+ // See if sound settings overrides this
+ AudioManager audioService = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
+ if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
+ shouldPlayBeep = false;
+ }
+ }
+ return shouldPlayBeep;
+ }
+
+ private static MediaPlayer buildMediaPlayer(Context activity) {
+ MediaPlayer mediaPlayer = new MediaPlayer();
+ mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ // When the beep has finished playing, rewind to queue up another one.
+ mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer player) {
+ player.seekTo(0);
+ }
+ });
+
+ AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.beep);
+ try {
+ mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
+ file.close();
+ mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
+ mediaPlayer.prepare();
+ } catch (IOException ioe) {
+ Log.w(TAG, ioe);
+ mediaPlayer = null;
+ }
+ return mediaPlayer;
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/CaptureActivity.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/CaptureActivity.java
new file mode 100644
index 00000000..624bfb4b
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/CaptureActivity.java
@@ -0,0 +1,745 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.Result;
+import com.google.zxing.ResultMetadataType;
+import com.google.zxing.ResultPoint;
+import com.google.zxing.client.android.camera.CameraManager;
+import com.google.zxing.client.android.history.HistoryActivity;
+import com.google.zxing.client.android.history.HistoryItem;
+import com.google.zxing.client.android.history.HistoryManager;
+import com.google.zxing.client.android.result.ResultButtonListener;
+import com.google.zxing.client.android.result.ResultHandler;
+import com.google.zxing.client.android.result.ResultHandlerFactory;
+import com.google.zxing.client.android.result.supplement.SupplementalInfoRetriever;
+import com.google.zxing.client.android.share.ShareActivity;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.text.ClipboardManager;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.text.DateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This activity opens the camera and does the actual scanning on a background thread. It draws a
+ * viewfinder to help the user place the barcode correctly, shows feedback as the image processing
+ * is happening, and then overlays the results when a scan is successful.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ * @author Sean Owen
+ */
+public final class CaptureActivity extends Activity implements SurfaceHolder.Callback {
+
+ private static final String TAG = CaptureActivity.class.getSimpleName();
+
+ private static final long DEFAULT_INTENT_RESULT_DURATION_MS = 1500L;
+ private static final long BULK_MODE_SCAN_DELAY_MS = 1000L;
+
+ private static final String PACKAGE_NAME = "com.google.zxing.client.android";
+ private static final String PRODUCT_SEARCH_URL_PREFIX = "http://www.google";
+ private static final String PRODUCT_SEARCH_URL_SUFFIX = "/m/products/scan";
+ private static final String[] ZXING_URLS = { "http://zxing.appspot.com/scan", "zxing://scan/" };
+ private static final String RETURN_CODE_PLACEHOLDER = "{CODE}";
+ private static final String RETURN_URL_PARAM = "ret";
+ private static final String RAW_PARAM = "raw";
+
+ public static final int HISTORY_REQUEST_CODE = 0x0000bacc;
+
+ private static final Set DISPLAYABLE_METADATA_TYPES =
+ EnumSet.of(ResultMetadataType.ISSUE_NUMBER,
+ ResultMetadataType.SUGGESTED_PRICE,
+ ResultMetadataType.ERROR_CORRECTION_LEVEL,
+ ResultMetadataType.POSSIBLE_COUNTRY);
+
+ private CameraManager cameraManager;
+ private CaptureActivityHandler handler;
+ private Result savedResultToShow;
+ private ViewfinderView viewfinderView;
+ private TextView statusView;
+ private View resultView;
+ private Result lastResult;
+ private boolean hasSurface;
+ private boolean copyToClipboard;
+ private IntentSource source;
+ private String sourceUrl;
+ private String returnUrlTemplate;
+ private boolean returnRaw;
+ private Collection decodeFormats;
+ private String characterSet;
+ private HistoryManager historyManager;
+ private InactivityTimer inactivityTimer;
+ private BeepManager beepManager;
+
+ ViewfinderView getViewfinderView() {
+ return viewfinderView;
+ }
+
+ public Handler getHandler() {
+ return handler;
+ }
+
+ CameraManager getCameraManager() {
+ return cameraManager;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ Window window = getWindow();
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ setContentView(R.layout.capture);
+
+ hasSurface = false;
+ historyManager = new HistoryManager(this);
+ historyManager.trimHistory();
+ inactivityTimer = new InactivityTimer(this);
+ beepManager = new BeepManager(this);
+
+ PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+
+ showHelpOnFirstLaunch();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // CameraManager must be initialized here, not in onCreate(). This is necessary because we don't
+ // want to open the camera driver and measure the screen size if we're going to show the help on
+ // first launch. That led to bugs where the scanning rectangle was the wrong size and partially
+ // off screen.
+ cameraManager = new CameraManager(getApplication());
+
+ viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
+ viewfinderView.setCameraManager(cameraManager);
+
+ resultView = findViewById(R.id.result_view);
+ statusView = (TextView) findViewById(R.id.status_view);
+
+ handler = null;
+ lastResult = null;
+
+ resetStatusView();
+
+ SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
+ SurfaceHolder surfaceHolder = surfaceView.getHolder();
+ if (hasSurface) {
+ // The activity was paused but not stopped, so the surface still exists. Therefore
+ // surfaceCreated() won't be called, so init the camera here.
+ initCamera(surfaceHolder);
+ } else {
+ // Install the callback and wait for surfaceCreated() to init the camera.
+ surfaceHolder.addCallback(this);
+ surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ }
+
+ beepManager.updatePrefs();
+
+ inactivityTimer.onResume();
+
+ Intent intent = getIntent();
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ copyToClipboard = prefs.getBoolean(PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true)
+ && (intent == null || intent.getBooleanExtra(Intents.Scan.SAVE_HISTORY, true));
+
+ // source = IntentSource.NONE;
+ source = IntentSource.NATIVE_APP_INTENT;
+ decodeFormats = null;
+ characterSet = null;
+
+ if (intent != null) {
+
+ String action = intent.getAction();
+ String dataString = intent.getDataString();
+
+ if (Intents.Scan.ACTION.equals(action)) {
+
+ // Scan the formats the intent requested, and return the result to the calling activity.
+ source = IntentSource.NATIVE_APP_INTENT;
+ decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);
+
+ if (intent.hasExtra(Intents.Scan.WIDTH) && intent.hasExtra(Intents.Scan.HEIGHT)) {
+ int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
+ int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);
+ if (width > 0 && height > 0) {
+ cameraManager.setManualFramingRect(width, height);
+ }
+ }
+
+ String customPromptMessage = intent.getStringExtra(Intents.Scan.PROMPT_MESSAGE);
+ if (customPromptMessage != null) {
+ statusView.setText(customPromptMessage);
+ }
+
+ } else if (dataString != null &&
+ dataString.contains(PRODUCT_SEARCH_URL_PREFIX) &&
+ dataString.contains(PRODUCT_SEARCH_URL_SUFFIX)) {
+
+ // Scan only products and send the result to mobile Product Search.
+ source = IntentSource.PRODUCT_SEARCH_LINK;
+ sourceUrl = dataString;
+ decodeFormats = DecodeFormatManager.PRODUCT_FORMATS;
+
+ } else if (isZXingURL(dataString)) {
+
+ // Scan formats requested in query string (all formats if none specified).
+ // If a return URL is specified, send the results there. Otherwise, handle it ourselves.
+ source = IntentSource.ZXING_LINK;
+ sourceUrl = dataString;
+ Uri inputUri = Uri.parse(sourceUrl);
+ returnUrlTemplate = inputUri.getQueryParameter(RETURN_URL_PARAM);
+ returnRaw = inputUri.getQueryParameter(RAW_PARAM) != null;
+ decodeFormats = DecodeFormatManager.parseDecodeFormats(inputUri);
+
+ }
+
+ characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);
+
+ }
+ }
+
+ private static boolean isZXingURL(String dataString) {
+ if (dataString == null) {
+ return false;
+ }
+ for (String url : ZXING_URLS) {
+ if (dataString.startsWith(url)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected void onPause() {
+ if (handler != null) {
+ handler.quitSynchronously();
+ handler = null;
+ }
+ inactivityTimer.onPause();
+ cameraManager.closeDriver();
+ if (!hasSurface) {
+ SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
+ SurfaceHolder surfaceHolder = surfaceView.getHolder();
+ surfaceHolder.removeCallback(this);
+ }
+ super.onPause();
+ }
+
+ @Override
+ protected void onDestroy() {
+ inactivityTimer.shutdown();
+ super.onDestroy();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ if (source == IntentSource.NATIVE_APP_INTENT) {
+ setResult(RESULT_CANCELED);
+ finish();
+ return true;
+ }
+ if ((source == IntentSource.NONE || source == IntentSource.ZXING_LINK) && lastResult != null) {
+ restartPreviewAfterDelay(0L);
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_FOCUS:
+ case KeyEvent.KEYCODE_CAMERA:
+ // Handle these events so they don't launch the Camera app
+ return true;
+ // Use volume up/down to turn on light
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ cameraManager.setTorch(false);
+ return true;
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ cameraManager.setTorch(true);
+ return true;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.capture, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ int itemId = item.getItemId();
+ if (itemId == R.id.menu_share) {
+ intent.setClassName(this, ShareActivity.class.getName());
+ startActivity(intent);
+ } else if (itemId == R.id.menu_history) {
+ intent.setClassName(this, HistoryActivity.class.getName());
+ startActivityForResult(intent, HISTORY_REQUEST_CODE);
+ } else if (itemId == R.id.menu_settings) {
+ intent.setClassName(this, PreferencesActivity.class.getName());
+ startActivity(intent);
+ } else if (itemId == R.id.menu_help) {
+ intent.setClassName(this, HelpActivity.class.getName());
+ startActivity(intent);
+ } else {
+ return super.onOptionsItemSelected(item);
+ }
+ return true;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (resultCode == RESULT_OK) {
+ if (requestCode == HISTORY_REQUEST_CODE) {
+ int itemNumber = intent.getIntExtra(Intents.History.ITEM_NUMBER, -1);
+ if (itemNumber >= 0) {
+ HistoryItem historyItem = historyManager.buildHistoryItem(itemNumber);
+ decodeOrStoreSavedBitmap(null, historyItem.getResult());
+ }
+ }
+ }
+ }
+
+ private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
+ // Bitmap isn't used yet -- will be used soon
+ if (handler == null) {
+ savedResultToShow = result;
+ } else {
+ if (result != null) {
+ savedResultToShow = result;
+ }
+ if (savedResultToShow != null) {
+ Message message = Message.obtain(handler, R.id.decode_succeeded, savedResultToShow);
+ handler.sendMessage(message);
+ }
+ savedResultToShow = null;
+ }
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ if (holder == null) {
+ Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
+ }
+ if (!hasSurface) {
+ hasSurface = true;
+ initCamera(holder);
+ }
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ hasSurface = false;
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ /**
+ * A valid barcode has been found, so give an indication of success and show the results.
+ *
+ * @param rawResult The contents of the barcode.
+ * @param barcode A greyscale bitmap of the camera data which was decoded.
+ */
+ public void handleDecode(Result rawResult, Bitmap barcode) {
+ inactivityTimer.onActivity();
+ lastResult = rawResult;
+ ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
+
+ boolean fromLiveScan = barcode != null;
+ if (fromLiveScan) {
+ historyManager.addHistoryItem(rawResult, resultHandler);
+ // Then not from history, so beep/vibrate and we have an image to draw on
+ beepManager.playBeepSoundAndVibrate();
+ drawResultPoints(barcode, rawResult);
+ }
+
+ switch (source) {
+ case NATIVE_APP_INTENT:
+ case PRODUCT_SEARCH_LINK:
+ handleDecodeExternally(rawResult, resultHandler, barcode);
+ break;
+ case ZXING_LINK:
+ if (returnUrlTemplate == null){
+ handleDecodeInternally(rawResult, resultHandler, barcode);
+ } else {
+ handleDecodeExternally(rawResult, resultHandler, barcode);
+ }
+ break;
+ case NONE:
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ if (fromLiveScan && prefs.getBoolean(PreferencesActivity.KEY_BULK_MODE, false)) {
+ String message = getResources().getString(R.string.msg_bulk_mode_scanned)
+ + " (" + rawResult.getText() + ')';
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ // Wait a moment or else it will scan the same barcode continuously about 3 times
+ restartPreviewAfterDelay(BULK_MODE_SCAN_DELAY_MS);
+ } else {
+ handleDecodeInternally(rawResult, resultHandler, barcode);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Superimpose a line for 1D or dots for 2D to highlight the key features of the barcode.
+ *
+ * @param barcode A bitmap of the captured image.
+ * @param rawResult The decoded results which contains the points to draw.
+ */
+ private void drawResultPoints(Bitmap barcode, Result rawResult) {
+ ResultPoint[] points = rawResult.getResultPoints();
+ if (points != null && points.length > 0) {
+ Canvas canvas = new Canvas(barcode);
+ Paint paint = new Paint();
+ paint.setColor(getResources().getColor(R.color.result_points));
+ if (points.length == 2) {
+ paint.setStrokeWidth(4.0f);
+ drawLine(canvas, paint, points[0], points[1]);
+ } else if (points.length == 4 &&
+ (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A ||
+ rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
+ // Hacky special case -- draw two lines, for the barcode and metadata
+ drawLine(canvas, paint, points[0], points[1]);
+ drawLine(canvas, paint, points[2], points[3]);
+ } else {
+ paint.setStrokeWidth(10.0f);
+ for (ResultPoint point : points) {
+ canvas.drawPoint(point.getX(), point.getY(), paint);
+ }
+ }
+ }
+ }
+
+ private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b) {
+ canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint);
+ }
+
+ // Put up our own UI for how to handle the decoded contents.
+ private void handleDecodeInternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
+ statusView.setVisibility(View.GONE);
+ viewfinderView.setVisibility(View.GONE);
+ resultView.setVisibility(View.VISIBLE);
+
+ ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view);
+ if (barcode == null) {
+ barcodeImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),
+ R.drawable.launcher_icon));
+ } else {
+ barcodeImageView.setImageBitmap(barcode);
+ }
+
+ TextView formatTextView = (TextView) findViewById(R.id.format_text_view);
+ formatTextView.setText(rawResult.getBarcodeFormat().toString());
+
+ TextView typeTextView = (TextView) findViewById(R.id.type_text_view);
+ typeTextView.setText(resultHandler.getType().toString());
+
+ DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+ String formattedTime = formatter.format(new Date(rawResult.getTimestamp()));
+ TextView timeTextView = (TextView) findViewById(R.id.time_text_view);
+ timeTextView.setText(formattedTime);
+
+
+ TextView metaTextView = (TextView) findViewById(R.id.meta_text_view);
+ View metaTextViewLabel = findViewById(R.id.meta_text_view_label);
+ metaTextView.setVisibility(View.GONE);
+ metaTextViewLabel.setVisibility(View.GONE);
+ Map metadata = rawResult.getResultMetadata();
+ if (metadata != null) {
+ StringBuilder metadataText = new StringBuilder(20);
+ for (Map.Entry entry : metadata.entrySet()) {
+ if (DISPLAYABLE_METADATA_TYPES.contains(entry.getKey())) {
+ metadataText.append(entry.getValue()).append('\n');
+ }
+ }
+ if (metadataText.length() > 0) {
+ metadataText.setLength(metadataText.length() - 1);
+ metaTextView.setText(metadataText);
+ metaTextView.setVisibility(View.VISIBLE);
+ metaTextViewLabel.setVisibility(View.VISIBLE);
+ }
+ }
+
+ TextView contentsTextView = (TextView) findViewById(R.id.contents_text_view);
+ CharSequence displayContents = resultHandler.getDisplayContents();
+ contentsTextView.setText(displayContents);
+ // Crudely scale betweeen 22 and 32 -- bigger font for shorter text
+ int scaledSize = Math.max(22, 32 - displayContents.length() / 4);
+ contentsTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize);
+
+ TextView supplementTextView = (TextView) findViewById(R.id.contents_supplement_text_view);
+ supplementTextView.setText("");
+ supplementTextView.setOnClickListener(null);
+ if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
+ PreferencesActivity.KEY_SUPPLEMENTAL, true)) {
+ SupplementalInfoRetriever.maybeInvokeRetrieval(supplementTextView,
+ resultHandler.getResult(),
+ historyManager,
+ this);
+ }
+
+ int buttonCount = resultHandler.getButtonCount();
+ ViewGroup buttonView = (ViewGroup) findViewById(R.id.result_button_view);
+ buttonView.requestFocus();
+ for (int x = 0; x < ResultHandler.MAX_BUTTON_COUNT; x++) {
+ TextView button = (TextView) buttonView.getChildAt(x);
+ if (x < buttonCount) {
+ button.setVisibility(View.VISIBLE);
+ button.setText(resultHandler.getButtonText(x));
+ button.setOnClickListener(new ResultButtonListener(resultHandler, x));
+ } else {
+ button.setVisibility(View.GONE);
+ }
+ }
+
+ if (copyToClipboard && !resultHandler.areContentsSecure()) {
+ ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ if (displayContents != null) {
+ clipboard.setText(displayContents);
+ }
+ }
+ }
+
+ // Briefly show the contents of the barcode, then handle the result outside Barcode Scanner.
+ private void handleDecodeExternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
+ if (barcode != null) {
+ viewfinderView.drawResultBitmap(barcode);
+ }
+
+ long resultDurationMS;
+ if (getIntent() == null) {
+ resultDurationMS = DEFAULT_INTENT_RESULT_DURATION_MS;
+ } else {
+ resultDurationMS = getIntent().getLongExtra(Intents.Scan.RESULT_DISPLAY_DURATION_MS,
+ DEFAULT_INTENT_RESULT_DURATION_MS);
+ }
+
+ // Since this message will only be shown for a second, just tell the user what kind of
+ // barcode was found (e.g. contact info) rather than the full contents, which they won't
+ // have time to read.
+ if (resultDurationMS > 0) {
+ statusView.setText(getString(resultHandler.getDisplayTitle()));
+ }
+
+ if (copyToClipboard && !resultHandler.areContentsSecure()) {
+ ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ CharSequence text = resultHandler.getDisplayContents();
+ if (text != null) {
+ clipboard.setText(text);
+ }
+ }
+
+ if (source == IntentSource.NATIVE_APP_INTENT) {
+
+ // Hand back whatever action they requested - this can be changed to Intents.Scan.ACTION when
+ // the deprecated intent is retired.
+ Intent intent = new Intent(getIntent().getAction());
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ intent.putExtra(Intents.Scan.RESULT, rawResult.toString());
+ intent.putExtra(Intents.Scan.RESULT_FORMAT, rawResult.getBarcodeFormat().toString());
+ byte[] rawBytes = rawResult.getRawBytes();
+ if (rawBytes != null && rawBytes.length > 0) {
+ intent.putExtra(Intents.Scan.RESULT_BYTES, rawBytes);
+ }
+ Map metadata = rawResult.getResultMetadata();
+ if (metadata != null) {
+ if (metadata.containsKey(ResultMetadataType.UPC_EAN_EXTENSION)) {
+ intent.putExtra(Intents.Scan.RESULT_UPC_EAN_EXTENSION,
+ metadata.get(ResultMetadataType.UPC_EAN_EXTENSION).toString());
+ }
+ Integer orientation = (Integer) metadata.get(ResultMetadataType.ORIENTATION);
+ if (orientation != null) {
+ intent.putExtra(Intents.Scan.RESULT_ORIENTATION, orientation.intValue());
+ }
+ String ecLevel = (String) metadata.get(ResultMetadataType.ERROR_CORRECTION_LEVEL);
+ if (ecLevel != null) {
+ intent.putExtra(Intents.Scan.RESULT_ERROR_CORRECTION_LEVEL, ecLevel);
+ }
+ Iterable byteSegments = (Iterable) metadata.get(ResultMetadataType.BYTE_SEGMENTS);
+ if (byteSegments != null) {
+ int i = 0;
+ for (byte[] byteSegment : byteSegments) {
+ intent.putExtra(Intents.Scan.RESULT_BYTE_SEGMENTS_PREFIX + i, byteSegment);
+ i++;
+ }
+ }
+ }
+ sendReplyMessage(R.id.return_scan_result, intent, resultDurationMS);
+
+ } else if (source == IntentSource.PRODUCT_SEARCH_LINK) {
+
+ // Reformulate the URL which triggered us into a query, so that the request goes to the same
+ // TLD as the scan URL.
+ int end = sourceUrl.lastIndexOf("/scan");
+ String replyURL = sourceUrl.substring(0, end) + "?q=" + resultHandler.getDisplayContents() + "&source=zxing";
+ sendReplyMessage(R.id.launch_product_query, replyURL, resultDurationMS);
+
+ } else if (source == IntentSource.ZXING_LINK) {
+
+ // Replace each occurrence of RETURN_CODE_PLACEHOLDER in the returnUrlTemplate
+ // with the scanned code. This allows both queries and REST-style URLs to work.
+ if (returnUrlTemplate != null) {
+ CharSequence codeReplacement = returnRaw ? rawResult.getText() : resultHandler.getDisplayContents();
+ try {
+ codeReplacement = URLEncoder.encode(codeReplacement.toString(), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // can't happen; UTF-8 is always supported. Continue, I guess, without encoding
+ }
+ String replyURL = returnUrlTemplate.replace(RETURN_CODE_PLACEHOLDER, codeReplacement);
+ sendReplyMessage(R.id.launch_product_query, replyURL, resultDurationMS);
+ }
+
+ }
+ }
+
+ private void sendReplyMessage(int id, Object arg, long delayMS) {
+ Message message = Message.obtain(handler, id, arg);
+ if (delayMS > 0L) {
+ handler.sendMessageDelayed(message, delayMS);
+ } else {
+ handler.sendMessage(message);
+ }
+ }
+
+ /**
+ * We want the help screen to be shown automatically the first time a new version of the app is
+ * run. The easiest way to do this is to check android:versionCode from the manifest, and compare
+ * it to a value stored as a preference.
+ */
+ private boolean showHelpOnFirstLaunch() {
+ try {
+ PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
+ int currentVersion = info.versionCode;
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ int lastVersion = prefs.getInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN, 0);
+ if (currentVersion > lastVersion) {
+ prefs.edit().putInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN, currentVersion).commit();
+ Intent intent = new Intent(this, HelpActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ // Show the default page on a clean install, and the what's new page on an upgrade.
+ String page = lastVersion == 0 ? HelpActivity.DEFAULT_PAGE : HelpActivity.WHATS_NEW_PAGE;
+ intent.putExtra(HelpActivity.REQUESTED_PAGE_KEY, page);
+ startActivity(intent);
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, e);
+ }
+ return false;
+ }
+
+ private void initCamera(SurfaceHolder surfaceHolder) {
+ if (surfaceHolder == null) {
+ throw new IllegalStateException("No SurfaceHolder provided");
+ }
+ if (cameraManager.isOpen()) {
+ Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
+ return;
+ }
+ try {
+ cameraManager.openDriver(surfaceHolder);
+ // Creating the handler starts the preview, which can also throw a RuntimeException.
+ if (handler == null) {
+ handler = new CaptureActivityHandler(this, decodeFormats, characterSet, cameraManager);
+ }
+ decodeOrStoreSavedBitmap(null, null);
+ } catch (IOException ioe) {
+ Log.w(TAG, ioe);
+ displayFrameworkBugMessageAndExit();
+ } catch (RuntimeException e) {
+ // Barcode Scanner has seen crashes in the wild of this variety:
+ // java.?lang.?RuntimeException: Fail to connect to camera service
+ Log.w(TAG, "Unexpected error initializing camera", e);
+ displayFrameworkBugMessageAndExit();
+ }
+ }
+
+ private void displayFrameworkBugMessageAndExit() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getString(R.string.app_name));
+ builder.setMessage(getString(R.string.msg_camera_framework_bug));
+ builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
+ builder.setOnCancelListener(new FinishListener(this));
+ builder.show();
+ }
+
+ public void restartPreviewAfterDelay(long delayMS) {
+ if (handler != null) {
+ handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
+ }
+ resetStatusView();
+ }
+
+ private void resetStatusView() {
+ resultView.setVisibility(View.GONE);
+ statusView.setText(R.string.msg_default_status);
+ statusView.setVisibility(View.VISIBLE);
+ viewfinderView.setVisibility(View.VISIBLE);
+ lastResult = null;
+ }
+
+ public void drawViewfinder() {
+ viewfinderView.drawViewfinder();
+ }
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/CaptureActivityHandler.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/CaptureActivityHandler.java
new file mode 100644
index 00000000..b5acf831
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/CaptureActivityHandler.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import android.content.ActivityNotFoundException;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Browser;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.Result;
+import com.google.zxing.client.android.camera.CameraManager;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import java.util.Collection;
+
+/**
+ * This class handles all the messaging which comprises the state machine for capture.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class CaptureActivityHandler extends Handler {
+
+ private static final String TAG = CaptureActivityHandler.class.getSimpleName();
+
+ private final CaptureActivity activity;
+ private final DecodeThread decodeThread;
+ private State state;
+ private final CameraManager cameraManager;
+
+ private enum State {
+ PREVIEW,
+ SUCCESS,
+ DONE
+ }
+
+ CaptureActivityHandler(CaptureActivity activity,
+ Collection decodeFormats,
+ String characterSet,
+ CameraManager cameraManager) {
+ this.activity = activity;
+ decodeThread = new DecodeThread(activity, decodeFormats, characterSet,
+ new ViewfinderResultPointCallback(activity.getViewfinderView()));
+ decodeThread.start();
+ state = State.SUCCESS;
+
+ // Start ourselves capturing previews and decoding.
+ this.cameraManager = cameraManager;
+ cameraManager.startPreview();
+ restartPreviewAndDecode();
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == R.id.restart_preview) {
+ Log.d(TAG, "Got restart preview message");
+ restartPreviewAndDecode();
+ } else if (message.what == R.id.decode_succeeded) {
+ Log.d(TAG, "Got decode succeeded message");
+ state = State.SUCCESS;
+ Bundle bundle = message.getData();
+ Bitmap barcode = bundle == null ? null :
+ (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);
+ activity.handleDecode((Result) message.obj, barcode);
+ } else if (message.what == R.id.decode_failed) {
+ // We're decoding as fast as possible, so when one decode fails, start another.
+ state = State.PREVIEW;
+ cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
+ } else if (message.what == R.id.return_scan_result) {
+ Log.d(TAG, "Got return scan result message");
+ activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
+ activity.finish();
+ } else if (message.what == R.id.launch_product_query) {
+ Log.d(TAG, "Got product query message");
+ String url = (String) message.obj;
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ intent.setData(Uri.parse(url));
+ ResolveInfo resolveInfo =
+ activity.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ String browserPackageName = null;
+ if (resolveInfo.activityInfo != null) {
+ browserPackageName = resolveInfo.activityInfo.packageName;
+ Log.d(TAG, "Using browser in package " + browserPackageName);
+ }
+ // Needed for default Android browser only apparently
+ if ("com.android.browser".equals(browserPackageName)) {
+ intent.setPackage(browserPackageName);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, browserPackageName);
+ }
+ try {
+ activity.startActivity(intent);
+ } catch (ActivityNotFoundException anfe) {
+ Log.w(TAG, "Can't find anything to handle VIEW of URI " + url);
+ }
+ }
+ }
+
+ public void quitSynchronously() {
+ state = State.DONE;
+ cameraManager.stopPreview();
+ Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
+ quit.sendToTarget();
+ try {
+ // Wait at most half a second; should be enough time, and onPause() will timeout quickly
+ decodeThread.join(500L);
+ } catch (InterruptedException e) {
+ // continue
+ }
+
+ // Be absolutely sure we don't send any queued up messages
+ removeMessages(R.id.decode_succeeded);
+ removeMessages(R.id.decode_failed);
+ }
+
+ private void restartPreviewAndDecode() {
+ if (state == State.SUCCESS) {
+ state = State.PREVIEW;
+ cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
+ activity.drawViewfinder();
+ }
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/Contents.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/Contents.java
new file mode 100644
index 00000000..9e5a86dc
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/Contents.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import android.provider.ContactsContract;
+
+/**
+ * The set of constants to use when sending Barcode Scanner an Intent which requests a barcode
+ * to be encoded.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class Contents {
+ private Contents() {
+ }
+
+ public static final class Type {
+ /**
+ * Plain text. Use Intent.putExtra(DATA, string). This can be used for URLs too, but string
+ * must include "http://" or "https://".
+ */
+ public static final String TEXT = "TEXT_TYPE";
+
+ /**
+ * An email type. Use Intent.putExtra(DATA, string) where string is the email address.
+ */
+ public static final String EMAIL = "EMAIL_TYPE";
+
+ /**
+ * Use Intent.putExtra(DATA, string) where string is the phone number to call.
+ */
+ public static final String PHONE = "PHONE_TYPE";
+
+ /**
+ * An SMS type. Use Intent.putExtra(DATA, string) where string is the number to SMS.
+ */
+ public static final String SMS = "SMS_TYPE";
+
+ /**
+ * A contact. Send a request to encode it as follows:
+ *
+ * import android.provider.Contacts;
+ *
+ * Intent intent = new Intent(Intents.Encode.ACTION);
+ * intent.putExtra(Intents.Encode.TYPE, CONTACT);
+ * Bundle bundle = new Bundle();
+ * bundle.putString(Contacts.Intents.Insert.NAME, "Jenny");
+ * bundle.putString(Contacts.Intents.Insert.PHONE, "8675309");
+ * bundle.putString(Contacts.Intents.Insert.EMAIL, "jenny@the80s.com");
+ * bundle.putString(Contacts.Intents.Insert.POSTAL, "123 Fake St. San Francisco, CA 94102");
+ * intent.putExtra(Intents.Encode.DATA, bundle);
+ */
+ public static final String CONTACT = "CONTACT_TYPE";
+
+ /**
+ * A geographic location. Use as follows:
+ * Bundle bundle = new Bundle();
+ * bundle.putFloat("LAT", latitude);
+ * bundle.putFloat("LONG", longitude);
+ * intent.putExtra(Intents.Encode.DATA, bundle);
+ */
+ public static final String LOCATION = "LOCATION_TYPE";
+
+ private Type() {
+ }
+ }
+
+ public static final String URL_KEY = "URL_KEY";
+
+ public static final String NOTE_KEY = "NOTE_KEY";
+
+ /**
+ * When using Type.CONTACT, these arrays provide the keys for adding or retrieving multiple
+ * phone numbers and addresses.
+ */
+ public static final String[] PHONE_KEYS = {
+ ContactsContract.Intents.Insert.PHONE,
+ ContactsContract.Intents.Insert.SECONDARY_PHONE,
+ ContactsContract.Intents.Insert.TERTIARY_PHONE
+ };
+
+ public static final String[] PHONE_TYPE_KEYS = {
+ ContactsContract.Intents.Insert.PHONE_TYPE,
+ ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE,
+ ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE
+ };
+
+ public static final String[] EMAIL_KEYS = {
+ ContactsContract.Intents.Insert.EMAIL,
+ ContactsContract.Intents.Insert.SECONDARY_EMAIL,
+ ContactsContract.Intents.Insert.TERTIARY_EMAIL
+ };
+
+ public static final String[] EMAIL_TYPE_KEYS = {
+ ContactsContract.Intents.Insert.EMAIL_TYPE,
+ ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE,
+ ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE
+ };
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeFormatManager.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeFormatManager.java
new file mode 100644
index 00000000..26b34bcd
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeFormatManager.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import android.content.Intent;
+import android.net.Uri;
+import com.google.zxing.BarcodeFormat;
+
+final class DecodeFormatManager {
+
+ private static final Pattern COMMA_PATTERN = Pattern.compile(",");
+
+ static final Collection PRODUCT_FORMATS;
+ static final Collection ONE_D_FORMATS;
+ static final Collection QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
+ static final Collection DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);
+ static {
+ PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A,
+ BarcodeFormat.UPC_E,
+ BarcodeFormat.EAN_13,
+ BarcodeFormat.EAN_8,
+ BarcodeFormat.RSS_14);
+ ONE_D_FORMATS = EnumSet.of(BarcodeFormat.CODE_39,
+ BarcodeFormat.CODE_93,
+ BarcodeFormat.CODE_128,
+ BarcodeFormat.ITF,
+ BarcodeFormat.CODABAR);
+ ONE_D_FORMATS.addAll(PRODUCT_FORMATS);
+ }
+
+ private DecodeFormatManager() {}
+
+ static Collection parseDecodeFormats(Intent intent) {
+ List scanFormats = null;
+ String scanFormatsString = intent.getStringExtra(Intents.Scan.FORMATS);
+ if (scanFormatsString != null) {
+ scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString));
+ }
+ return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE));
+ }
+
+ static Collection parseDecodeFormats(Uri inputUri) {
+ List formats = inputUri.getQueryParameters(Intents.Scan.FORMATS);
+ if (formats != null && formats.size() == 1 && formats.get(0) != null){
+ formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
+ }
+ return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE));
+ }
+
+ private static Collection parseDecodeFormats(Iterable scanFormats,
+ String decodeMode) {
+ if (scanFormats != null) {
+ Collection formats = EnumSet.noneOf(BarcodeFormat.class);
+ try {
+ for (String format : scanFormats) {
+ formats.add(BarcodeFormat.valueOf(format));
+ }
+ return formats;
+ } catch (IllegalArgumentException iae) {
+ // ignore it then
+ }
+ }
+ if (decodeMode != null) {
+ if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) {
+ return PRODUCT_FORMATS;
+ }
+ if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) {
+ return QR_CODE_FORMATS;
+ }
+ if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) {
+ return DATA_MATRIX_FORMATS;
+ }
+ if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) {
+ return ONE_D_FORMATS;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeHandler.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeHandler.java
new file mode 100644
index 00000000..33866d69
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeHandler.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import android.graphics.Bitmap;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.LuminanceSource;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.PlanarYUVLuminanceSource;
+import com.google.zxing.ReaderException;
+import com.google.zxing.Result;
+import com.google.zxing.common.HybridBinarizer;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import java.util.Map;
+
+final class DecodeHandler extends Handler {
+
+ private static final String TAG = DecodeHandler.class.getSimpleName();
+
+ private final CaptureActivity activity;
+ private final MultiFormatReader multiFormatReader;
+ private boolean running = true;
+
+ DecodeHandler(CaptureActivity activity, Map hints) {
+ multiFormatReader = new MultiFormatReader();
+ multiFormatReader.setHints(hints);
+ this.activity = activity;
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ if (!running) {
+ return;
+ }
+ if (message.what == R.id.decode) {
+ decode((byte[]) message.obj, message.arg1, message.arg2);
+ } else if (message.what == R.id.quit) {
+ running = false;
+ Looper.myLooper().quit();
+ }
+ }
+
+ /**
+ * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
+ * reuse the same reader objects from one decode to the next.
+ *
+ * @param data The YUV preview frame.
+ * @param width The width of the preview frame.
+ * @param height The height of the preview frame.
+ */
+ private void decode(byte[] data, int width, int height) {
+ long start = System.currentTimeMillis();
+ Result rawResult = null;
+ PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
+ if (source != null) {
+ BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ try {
+ rawResult = multiFormatReader.decodeWithState(bitmap);
+ } catch (ReaderException re) {
+ // continue
+ } finally {
+ multiFormatReader.reset();
+ }
+ }
+
+ Handler handler = activity.getHandler();
+ if (rawResult != null) {
+ // Don't log the barcode contents for security.
+ long end = System.currentTimeMillis();
+ Log.d(TAG, "Found barcode in " + (end - start) + " ms");
+ if (handler != null) {
+ Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
+ Bundle bundle = new Bundle();
+ Bitmap grayscaleBitmap = toBitmap(source, source.renderCroppedGreyscaleBitmap());
+ bundle.putParcelable(DecodeThread.BARCODE_BITMAP, grayscaleBitmap);
+ message.setData(bundle);
+ message.sendToTarget();
+ }
+ } else {
+ if (handler != null) {
+ Message message = Message.obtain(handler, R.id.decode_failed);
+ message.sendToTarget();
+ }
+ }
+ }
+
+ private static Bitmap toBitmap(LuminanceSource source, int[] pixels) {
+ int width = source.getWidth();
+ int height = source.getHeight();
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
+ return bitmap;
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeThread.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeThread.java
new file mode 100644
index 00000000..83ea75d1
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/DecodeThread.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.ResultPointCallback;
+
+import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.Looper;
+import android.preference.PreferenceManager;
+
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This thread does all the heavy lifting of decoding the images.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+final class DecodeThread extends Thread {
+
+ public static final String BARCODE_BITMAP = "barcode_bitmap";
+
+ private final CaptureActivity activity;
+ private final Map hints;
+ private Handler handler;
+ private final CountDownLatch handlerInitLatch;
+
+ DecodeThread(CaptureActivity activity,
+ Collection decodeFormats,
+ String characterSet,
+ ResultPointCallback resultPointCallback) {
+
+ this.activity = activity;
+ handlerInitLatch = new CountDownLatch(1);
+
+ hints = new EnumMap(DecodeHintType.class);
+
+ // The prefs can't change while the thread is running, so pick them up once here.
+ if (decodeFormats == null || decodeFormats.isEmpty()) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+ decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
+ if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, false)) {
+ decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
+ }
+ if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, false)) {
+ decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
+ }
+ if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_DATA_MATRIX, false)) {
+ decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
+ }
+ }
+ hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
+
+ if (characterSet != null) {
+ hints.put(DecodeHintType.CHARACTER_SET, characterSet);
+ }
+ hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);
+ }
+
+ Handler getHandler() {
+ try {
+ handlerInitLatch.await();
+ } catch (InterruptedException ie) {
+ // continue?
+ }
+ return handler;
+ }
+
+ @Override
+ public void run() {
+ Looper.prepare();
+ handler = new DecodeHandler(activity, hints);
+ handlerInitLatch.countDown();
+ Looper.loop();
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/FinishListener.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/FinishListener.java
new file mode 100644
index 00000000..5d598861
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/FinishListener.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+
+/**
+ * Simple listener used to exit the app in a few cases.
+ *
+ * @author Sean Owen
+ */
+public final class FinishListener implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
+
+ private final Activity activityToFinish;
+
+ public FinishListener(Activity activityToFinish) {
+ this.activityToFinish = activityToFinish;
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialogInterface) {
+ run();
+ }
+
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ run();
+ }
+
+ private void run() {
+ activityToFinish.finish();
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/HelpActivity.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/HelpActivity.java
new file mode 100644
index 00000000..cb145cc9
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/HelpActivity.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.view.KeyEvent;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Button;
+
+/**
+ * An HTML-based help screen with Back and Done buttons at the bottom.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class HelpActivity extends Activity {
+
+ // Use this key and one of the values below when launching this activity via intent. If not
+ // present, the default page will be loaded.
+ public static final String REQUESTED_PAGE_KEY = "requested_page_key";
+ public static final String DEFAULT_PAGE = "index.html";
+ public static final String WHATS_NEW_PAGE = "whatsnew.html";
+
+ private static final String BASE_URL =
+ "file:///android_asset/html-" + LocaleManager.getTranslatedAssetLanguage() + '/';
+ private static final String WEBVIEW_STATE_PRESENT = "webview_state_present";
+
+ private WebView webView;
+ private Button backButton;
+
+ private final Button.OnClickListener backListener = new Button.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ webView.goBack();
+ }
+ };
+
+ private final Button.OnClickListener doneListener = new Button.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ finish();
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.help);
+
+ webView = (WebView)findViewById(R.id.help_contents);
+ webView.setWebViewClient(new HelpClient());
+
+ // Froyo has a bug with calling onCreate() twice in a row, which causes the What's New page
+ // that's auto-loaded on first run to appear blank. As a workaround we only call restoreState()
+ // if a valid URL was loaded at the time the previous activity was torn down.
+ Intent intent = getIntent();
+ if (icicle != null && icicle.getBoolean(WEBVIEW_STATE_PRESENT, false)) {
+ webView.restoreState(icicle);
+ } else if (intent != null) {
+ String page = intent.getStringExtra(REQUESTED_PAGE_KEY);
+ if (page != null && page.length() > 0) {
+ webView.loadUrl(BASE_URL + page);
+ } else {
+ webView.loadUrl(BASE_URL + DEFAULT_PAGE);
+ }
+ } else {
+ webView.loadUrl(BASE_URL + DEFAULT_PAGE);
+ }
+
+ backButton = (Button) findViewById(R.id.back_button);
+ backButton.setOnClickListener(backListener);
+ View doneButton = findViewById(R.id.done_button);
+ doneButton.setOnClickListener(doneListener);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle state) {
+ String url = webView.getUrl();
+ if (url != null && url.length() > 0) {
+ webView.saveState(state);
+ state.putBoolean(WEBVIEW_STATE_PRESENT, true);
+ }
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ if (webView.canGoBack()) {
+ webView.goBack();
+ return true;
+ }
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ private final class HelpClient extends WebViewClient {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ setTitle(view.getTitle());
+ backButton.setEnabled(view.canGoBack());
+ }
+
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ if (url.startsWith("file")) {
+ // Keep local assets in this WebView.
+ return false;
+ } else {
+ // Open external URLs in Browser.
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+ return true;
+ }
+ }
+ }
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/HttpHelper.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/HttpHelper.java
new file mode 100644
index 00000000..047608e8
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/HttpHelper.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2011 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+
+/**
+ * Utility methods for retrieving content over HTTP using the more-supported {@code java.net} classes
+ * in Android.
+ */
+public final class HttpHelper {
+
+ private static final String TAG = HttpHelper.class.getSimpleName();
+
+ private static final Collection REDIRECTOR_DOMAINS = new HashSet(Arrays.asList(
+ "amzn.to", "bit.ly", "bitly.com", "fb.me", "goo.gl", "is.gd", "j.mp", "lnkd.in", "ow.ly",
+ "R.BEETAGG.COM", "r.beetagg.com", "SCN.BY", "su.pr", "t.co", "tinyurl.com", "tr.im"
+ ));
+
+ private HttpHelper() {
+ }
+
+ public enum ContentType {
+ /** HTML-like content type, including HTML, XHTML, etc. */
+ HTML,
+ /** JSON content */
+ JSON,
+ /** Plain text content */
+ TEXT,
+ }
+
+ /**
+ * Downloads the entire resource instead of part.
+ *
+ * @see #downloadViaHttp(String, HttpHelper.ContentType, int)
+ */
+ public static CharSequence downloadViaHttp(String uri, ContentType type) throws IOException {
+ return downloadViaHttp(uri, type, Integer.MAX_VALUE);
+ }
+
+ /**
+ * @param uri URI to retrieve
+ * @param type expected text-like MIME type of that content
+ * @param maxChars approximate maximum characters to read from the source
+ * @return content as a {@code String}
+ * @throws IOException if the content can't be retrieved because of a bad URI, network problem, etc.
+ */
+ public static CharSequence downloadViaHttp(String uri, ContentType type, int maxChars) throws IOException {
+ String contentTypes;
+ switch (type) {
+ case HTML:
+ contentTypes = "application/xhtml+xml,text/html,text/*,*/*";
+ break;
+ case JSON:
+ contentTypes = "application/json,text/*,*/*";
+ break;
+ case TEXT:
+ default:
+ contentTypes = "text/*,*/*";
+ }
+ return downloadViaHttp(uri, contentTypes, maxChars);
+ }
+
+ private static CharSequence downloadViaHttp(String uri, String contentTypes, int maxChars) throws IOException {
+ Log.i(TAG, "Downloading " + uri);
+ URL url = new URL(uri);
+ URLConnection conn = url.openConnection();
+ if (!(conn instanceof HttpURLConnection)) {
+ throw new IOException();
+ }
+ HttpURLConnection connection = (HttpURLConnection) conn;
+ connection.setRequestProperty("Accept", contentTypes);
+ connection.setRequestProperty("Accept-Charset", "utf-8,*");
+ connection.setRequestProperty("User-Agent", "ZXing (Android)");
+ try {
+ try {
+ connection.connect();
+ } catch (NullPointerException npe) {
+ // this is an Android bug: http://code.google.com/p/android/issues/detail?id=16895
+ Log.w(TAG, "Bad URI? " + uri);
+ throw new IOException(npe);
+ } catch (IllegalArgumentException iae) {
+ // Also seen this in the wild, not sure what to make of it. Probably a bad URL
+ Log.w(TAG, "Bad URI? " + uri);
+ throw new IOException(iae);
+ }
+ int responseCode;
+ try {
+ responseCode = connection.getResponseCode();
+ } catch (NullPointerException npe) {
+ // this is maybe this Android bug: http://code.google.com/p/android/issues/detail?id=15554
+ Log.w(TAG, "Bad URI? " + uri);
+ throw new IOException(npe);
+ }
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ throw new IOException("Bad HTTP response: " + responseCode);
+ }
+ Log.i(TAG, "Consuming " + uri);
+ return consume(connection, maxChars);
+ } finally {
+ connection.disconnect();
+ }
+ }
+
+ private static String getEncoding(URLConnection connection) {
+ String contentTypeHeader = connection.getHeaderField("Content-Type");
+ if (contentTypeHeader != null) {
+ int charsetStart = contentTypeHeader.indexOf("charset=");
+ if (charsetStart >= 0) {
+ return contentTypeHeader.substring(charsetStart + "charset=".length());
+ }
+ }
+ return "UTF-8";
+ }
+
+ private static CharSequence consume(URLConnection connection, int maxChars) throws IOException {
+ String encoding = getEncoding(connection);
+ StringBuilder out = new StringBuilder();
+ Reader in = null;
+ try {
+ in = new InputStreamReader(connection.getInputStream(), encoding);
+ char[] buffer = new char[1024];
+ int charsRead;
+ while (out.length() < maxChars && (charsRead = in.read(buffer)) > 0) {
+ out.append(buffer, 0, charsRead);
+ }
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ioe) {
+ // continue
+ } catch (NullPointerException npe) {
+ // another apparent Android / Harmony bug; continue
+ }
+ }
+ }
+ return out;
+ }
+
+ public static URI unredirect(URI uri) throws IOException {
+ if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
+ return uri;
+ }
+ URL url = uri.toURL();
+
+ URLConnection conn = url.openConnection();
+ if (!(conn instanceof HttpURLConnection)) {
+ throw new IOException();
+ }
+ HttpURLConnection connection = (HttpURLConnection) conn;
+ connection.setInstanceFollowRedirects(false);
+ connection.setDoInput(false);
+ connection.setRequestMethod("HEAD");
+ connection.setRequestProperty("User-Agent", "ZXing (Android)");
+ try {
+ try {
+ connection.connect();
+ } catch (NullPointerException npe) {
+ // this is an Android bug: http://code.google.com/p/android/issues/detail?id=16895
+ Log.w(TAG, "Bad URI? " + uri);
+ throw new IOException(npe);
+ } catch (IllegalArgumentException iae) {
+ // Also seen this in the wild, not sure what to make of it. Probably a bad URL
+ Log.w(TAG, "Bad URI? " + uri);
+ throw new IOException(iae);
+ }
+ int responseCode;
+ try {
+ responseCode = connection.getResponseCode();
+ } catch (NullPointerException npe) {
+ // this is maybe this Android bug: http://code.google.com/p/android/issues/detail?id=15554
+ Log.w(TAG, "Bad URI? " + uri);
+ throw new IOException(npe);
+ }
+ switch (responseCode) {
+ case HttpURLConnection.HTTP_MULT_CHOICE:
+ case HttpURLConnection.HTTP_MOVED_PERM:
+ case HttpURLConnection.HTTP_MOVED_TEMP:
+ case HttpURLConnection.HTTP_SEE_OTHER:
+ case 307: // No constant for 307 Temporary Redirect ?
+ String location = connection.getHeaderField("Location");
+ if (location != null) {
+ try {
+ return new URI(location);
+ } catch (URISyntaxException e) {
+ // nevermind
+ }
+ }
+ }
+ return uri;
+ } finally {
+ connection.disconnect();
+ }
+ }
+
+}
diff --git a/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/InactivityTimer.java b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/InactivityTimer.java
new file mode 100644
index 00000000..2b66efc1
--- /dev/null
+++ b/Android/BarcodeScanner/2.2.0/LibraryProject/src/com/google/zxing/client/android/InactivityTimer.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.android;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncTask;
+import android.os.BatteryManager;
+import android.util.Log;
+
+import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;
+import com.google.zxing.client.android.common.executor.AsyncTaskExecManager;
+
+/**
+ * Finishes an activity after a period of inactivity if the device is on battery power.
+ */
+final class InactivityTimer {
+
+ private static final String TAG = InactivityTimer.class.getSimpleName();
+
+ private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
+
+ private final Activity activity;
+ private final AsyncTaskExecInterface taskExec;
+ private final BroadcastReceiver powerStatusReceiver;
+ private InactivityAsyncTask inactivityTask;
+
+ InactivityTimer(Activity activity) {
+ this.activity = activity;
+ taskExec = new AsyncTaskExecManager().build();
+ powerStatusReceiver = new PowerStatusReceiver();
+ onActivity();
+ }
+
+ synchronized void onActivity() {
+ cancel();
+ inactivityTask = new InactivityAsyncTask();
+ taskExec.execute(inactivityTask);
+ }
+
+ public void onPause() {
+ cancel();
+ activity.unregisterReceiver(powerStatusReceiver);
+ }
+
+ public void onResume(){
+ activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ onActivity();
+ }
+
+ private synchronized void cancel() {
+ AsyncTask,?,?> task = inactivityTask;
+ if (task != null) {
+ task.cancel(true);
+ inactivityTask = null;
+ }
+ }
+
+ void shutdown() {
+ cancel();
+ }
+
+ private final class PowerStatusReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent){
+ if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
+ // 0 indicates that we're on battery
+ boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0;
+ if (onBatteryNow) {
+ InactivityTimer.this.onActivity();
+ } else {
+ InactivityTimer.this.cancel();
+ }
+ }
+ }
+ }
+
+ private final class InactivityAsyncTask extends AsyncTask