You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ky...@apache.org on 2019/07/31 12:11:10 UTC

[incubator-weex-playground] branch master updated: [Android] Remove some zxing source code (#13)

This is an automated email from the ASF dual-hosted git repository.

kyork pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex-playground.git


The following commit(s) were added to refs/heads/master by this push:
     new e6e18a2  [Android] Remove some zxing source code (#13)
e6e18a2 is described below

commit e6e18a2f9948d7fd57e839828c751d5b97d96b53
Author: katherine95s <51...@users.noreply.github.com>
AuthorDate: Wed Jul 31 20:11:05 2019 +0800

    [Android] Remove some zxing source code (#13)
---
 LICENSE                                            |  32 +
 android/playground/build.gradle                    |   5 +-
 android/playground/src/main/AndroidManifest.xml    |  30 +-
 .../com/alibaba/weex/CustomCaptureActivity.java    | 195 ++++++
 .../main/java/com/alibaba/weex/IndexActivity.java  |  11 +-
 .../alibaba/weex/extend/module/WXEventModule.java  |  14 +-
 .../alibaba/weex/thirdParty/zxing}/DBHelper.java   |   3 +-
 .../weex/thirdParty/zxing}/HistoryActivity.java    |  10 +-
 .../weex/thirdParty/zxing}/HistoryItem.java        |   3 +-
 .../weex/thirdParty/zxing}/HistoryItemAdapter.java |   3 +-
 .../weex/thirdParty/zxing}/HistoryManager.java     |  22 +-
 .../zxing/client/android/AmbientLightManager.java  |  87 ---
 .../google/zxing/client/android/BeepManager.java   | 133 ----
 .../zxing/client/android/CaptureActivity.java      | 780 ---------------------
 .../client/android/CaptureActivityHandler.java     | 164 -----
 .../com/google/zxing/client/android/Contents.java  | 115 ---
 .../zxing/client/android/DecodeFormatManager.java  | 106 ---
 .../google/zxing/client/android/DecodeHandler.java | 132 ----
 .../zxing/client/android/DecodeHintManager.java    | 236 -------
 .../google/zxing/client/android/DecodeThread.java  | 113 ---
 .../zxing/client/android/FinishListener.java       |  49 --
 .../google/zxing/client/android/HelpActivity.java  |  68 --
 .../google/zxing/client/android/HttpHelper.java    | 228 ------
 .../zxing/client/android/InactivityTimer.java      | 116 ---
 .../google/zxing/client/android/IntentSource.java  |  26 -
 .../com/google/zxing/client/android/Intents.java   | 278 --------
 .../google/zxing/client/android/LocaleManager.java | 188 -----
 .../zxing/client/android/PreferencesActivity.java  |  72 --
 .../zxing/client/android/PreferencesFragment.java  | 129 ----
 .../client/android/ScanFromWebPageManager.java     |  77 --
 .../android/ViewfinderResultPointCallback.java     |  35 -
 .../zxing/client/android/ViewfinderView.java       | 191 -----
 .../client/android/book/BrowseBookListener.java    |  62 --
 .../android/book/SearchBookContentsActivity.java   | 274 --------
 .../android/book/SearchBookContentsAdapter.java    |  61 --
 .../android/book/SearchBookContentsListItem.java   |  85 ---
 .../android/book/SearchBookContentsResult.java     |  66 --
 .../client/android/camera/AutoFocusManager.java    | 132 ----
 .../android/camera/CameraConfigurationManager.java | 252 -------
 .../android/camera/CameraConfigurationUtils.java   | 447 ------------
 .../zxing/client/android/camera/CameraManager.java | 338 ---------
 .../client/android/camera/FrontLightMode.java      |  43 --
 .../client/android/camera/PreviewCallback.java     |  56 --
 .../client/android/camera/open/CameraFacing.java   |  24 -
 .../client/android/camera/open/OpenCamera.java     |  52 --
 .../android/camera/open/OpenCameraInterface.java   |  95 ---
 .../android/clipboard/ClipboardInterface.java      |  58 --
 .../client/android/encode/ContactEncoder.java      |  96 ---
 .../client/android/encode/EncodeActivity.java      | 242 -------
 .../zxing/client/android/encode/Formatter.java     |  33 -
 .../android/encode/MECARDContactEncoder.java       |  97 ---
 .../zxing/client/android/encode/QRCodeEncoder.java | 389 ----------
 .../client/android/encode/VCardContactEncoder.java | 155 ----
 .../client/android/encode/VCardFieldFormatter.java |  79 ---
 .../android/encode/VCardTelDisplayFormatter.java   |  73 --
 .../android/result/AddressBookResultHandler.java   | 219 ------
 .../android/result/CalendarResultHandler.java      | 186 -----
 .../android/result/EmailAddressResultHandler.java  |  71 --
 .../client/android/result/GeoResultHandler.java    |  67 --
 .../client/android/result/ISBNResultHandler.java   |  76 --
 .../android/result/ProductResultHandler.java       |  83 ---
 .../android/result/ResultButtonListener.java       |  40 --
 .../zxing/client/android/result/ResultHandler.java | 513 --------------
 .../android/result/ResultHandlerFactory.java       |  64 --
 .../client/android/result/SMSResultHandler.java    |  85 ---
 .../client/android/result/TelResultHandler.java    |  82 ---
 .../client/android/result/TextResultHandler.java   |  76 --
 .../client/android/result/URIResultHandler.java    | 105 ---
 .../client/android/result/WifiResultHandler.java   |  92 ---
 .../result/supplement/BookResultInfoRetriever.java | 106 ---
 .../supplement/ProductResultInfoRetriever.java     |  83 ---
 .../supplement/SupplementalInfoRetriever.java      | 181 -----
 .../android/result/supplement/TitleRetriever.java  |  71 --
 .../result/supplement/URIResultInfoRetriever.java  |  64 --
 .../google/zxing/client/android/share/AppInfo.java |  65 --
 .../client/android/share/AppPickerActivity.java    |  64 --
 .../client/android/share/BookMarkColumns.java      |  68 --
 .../client/android/share/BookmarkAdapter.java      |  84 ---
 .../android/share/BookmarkPickerActivity.java      |  89 ---
 .../android/share/LoadPackagesAsyncTask.java       | 116 ---
 .../zxing/client/android/share/ShareActivity.java  | 299 --------
 .../zxing/client/android/wifi/NetworkType.java     |  41 --
 .../client/android/wifi/WifiConfigManager.java     | 226 ------
 .../src/main/res/layout/activity_qrcode.xml        |  18 +
 .../src/main/res/layout/app_picker_list_item.xml   |  38 -
 .../main/res/layout/bookmark_picker_list_item.xml  |  38 -
 android/playground/src/main/res/layout/camera.xml  |  36 -
 android/playground/src/main/res/layout/capture.xml | 204 ------
 .../src/main/res/layout/catalog_item.xml           |  32 -
 android/playground/src/main/res/layout/encode.xml  |  53 --
 android/playground/src/main/res/layout/help.xml    |  21 -
 .../src/main/res/layout/layout_zxing.xml           |  23 +
 .../src/main/res/layout/search_book_contents.xml   |  54 --
 .../res/layout/search_book_contents_header.xml     |  24 -
 .../res/layout/search_book_contents_list_item.xml  |  40 --
 android/playground/src/main/res/layout/share.xml   |  95 ---
 android/playground/src/main/res/menu/encode.xml    |  28 -
 .../src/main/res/values/scan_code_arrays.xml       |  62 --
 .../src/main/res/values/scan_code_colors.xml       |  29 -
 .../src/main/res/values/scan_code_ids.xml          |  25 -
 .../src/main/res/values/scan_code_styles.xml       |  48 --
 .../playground/src/main/res/xml/preferences.xml    | 133 ----
 .../src/main/res/xml/scan_code_preferences.xml     | 130 ----
 103 files changed, 316 insertions(+), 10991 deletions(-)

diff --git a/LICENSE b/LICENSE
index 8c17493..798a9bb 100644
--- a/LICENSE
+++ b/LICENSE
@@ -200,3 +200,35 @@
    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.
+
+==============================================================================
+
+Apache Weex-playground Submodules:
+
+Apache Weex-playground includes a number of submodules with separate copyright notices
+and license terms. Your use of these submodules is subject to the terms and
+conditions of the following licenses.
+
+This product bundles zxing v3.3.0, which is available under a
+"Apache" license,For details, see https://github.com/zxing/zxing/tree/zxing-3.3.0 and following files:
+android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/DBHelper.java
+android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryActivity.java
+android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryItem.java
+android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryItemAdapter.java
+android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryManager.java
+
+/*
+ * Copyright (C) 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.
+ */
diff --git a/android/playground/build.gradle b/android/playground/build.gradle
index a6eac50..09d315b 100755
--- a/android/playground/build.gradle
+++ b/android/playground/build.gradle
@@ -48,7 +48,7 @@ android {
         main {
             jniLibs.srcDir(['libs'])
             java {
-                srcDirs = ["src/main/java", "src/main/java_zxing"];
+                srcDirs = ["src/main/java"];
             }
         }
     }
@@ -125,6 +125,7 @@ dependencies {
     implementation 'com.alibaba.android:bindingx-core:1.1.1.2@aar'
     implementation 'com.alibaba.android:bindingx_weex_plugin:1.1.1@aar'
 
+    implementation('com.journeyapps:zxing-android-embedded:3.6.0') { transitive = false }
     if(project.implementFromWeex){
         implementation project(':weex_sdk')
     }
@@ -136,7 +137,7 @@ dependencies {
 if(file('../license/LICENSE').exists()){
     license {
         header = file('../license/LICENSE')
-        excludes(["com/google/zxing/**/*.java","**/*.xml"])
+        excludes(["**/*.xml","com/alibaba/weex/thirdParty/zxing/*.java"])
     }
     preBuild.dependsOn licenseFormat
 }
diff --git a/android/playground/src/main/AndroidManifest.xml b/android/playground/src/main/AndroidManifest.xml
index de7c3db..a24b20b 100755
--- a/android/playground/src/main/AndroidManifest.xml
+++ b/android/playground/src/main/AndroidManifest.xml
@@ -92,28 +92,7 @@ under the License.
             </intent-filter>
         </activity>
         <activity
-                android:name="com.google.zxing.client.android.CaptureActivity"
-                android:clearTaskOnLaunch="true"
-                android:screenOrientation="portrait"
-                android:stateNotNeeded="true"
-                android:theme="@style/CaptureTheme"
-                android:windowSoftInputMode="stateAlwaysHidden">
-            <intent-filter>
-                <action android:name="com.google.zxing.client.android.SCAN"/>
-
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW"/>
-
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.BROWSABLE"/>
-
-                <data android:host="zxing.appspot.com" android:path="/scan" android:scheme="http"/>
-            </intent-filter>
-        </activity>
-        <activity
-                android:name="com.google.zxing.client.android.history.HistoryActivity"
+                android:name=".thirdParty.zxing.HistoryActivity"
                 android:label="@string/history_title"
                 android:stateNotNeeded="true"/>
         <activity android:name="com.alibaba.weex.BenchmarkActivity"
@@ -123,6 +102,13 @@ under the License.
                   android:exported="true"
                   android:screenOrientation="portrait">
         </activity>
+        <activity android:name=".CustomCaptureActivity"
+            android:clearTaskOnLaunch="true"
+            android:screenOrientation="portrait"
+            android:stateNotNeeded="true"
+            android:theme="@style/CaptureTheme"
+            android:windowSoftInputMode="stateAlwaysHidden"
+            ></activity>
 
         <service
             android:name=".update.UpdateService"
diff --git a/android/playground/src/main/java/com/alibaba/weex/CustomCaptureActivity.java b/android/playground/src/main/java/com/alibaba/weex/CustomCaptureActivity.java
new file mode 100644
index 0000000..e416c05
--- /dev/null
+++ b/android/playground/src/main/java/com/alibaba/weex/CustomCaptureActivity.java
@@ -0,0 +1,195 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.alibaba.weex;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+import com.alibaba.weex.constants.Constants;
+import com.google.zxing.Result;
+import com.google.zxing.ResultPoint;
+import com.alibaba.weex.thirdParty.zxing.HistoryActivity;
+import com.alibaba.weex.thirdParty.zxing.HistoryItem;
+import com.alibaba.weex.thirdParty.zxing.HistoryManager;
+import com.journeyapps.barcodescanner.BarcodeCallback;
+import com.journeyapps.barcodescanner.BarcodeResult;
+import com.journeyapps.barcodescanner.CaptureManager;
+import com.journeyapps.barcodescanner.DecoratedBarcodeView;
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.WXSDKEngine;
+
+import java.util.List;
+
+public class CustomCaptureActivity extends Activity {
+    private CaptureManager capture;
+    private DecoratedBarcodeView barcodeScannerView;
+    private HistoryManager historyManager;
+    public static final int HISTORY_REQUEST_CODE = 0x0000bacc;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Window window = getWindow();
+        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        setContentView(R.layout.activity_qrcode);
+
+        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        } else {
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        }
+
+        barcodeScannerView = findViewById(R.id.decoratedBarcodeView);
+
+        capture = new CaptureManager(this, barcodeScannerView);
+        capture.initializeFromIntent(getIntent(), savedInstanceState);
+
+        barcodeScannerView.decodeContinuous(new BarcodeCallback() {
+            @Override
+            public void barcodeResult(BarcodeResult result) {
+                historyManager.addHistoryItem(result.getResult());
+                handleDecodeInternally(result.getResult());
+            }
+
+            @Override
+            public void possibleResultPoints(List<ResultPoint> resultPoints) {
+
+            }
+        });
+    }
+
+    private void handleDecodeInternally(Result rawResult) {
+        String code = rawResult.getText();
+        if (!TextUtils.isEmpty(code)) {
+            Uri uri = Uri.parse(code);
+            if (uri.getPath().contains("dynamic/replace")) {
+                Intent intent = new Intent("weex.intent.action.dynamic", uri);
+                intent.addCategory("weex.intent.category.dynamic");
+                startActivity(intent);
+                finish();
+            } else if (uri.getQueryParameterNames().contains("_wx_devtool")) {
+                WXEnvironment.sRemoteDebugProxyUrl = uri.getQueryParameter("_wx_devtool");
+                WXEnvironment.sDebugServerConnectable = true;
+                WXSDKEngine.reload();
+                Toast.makeText(this, "devtool", Toast.LENGTH_SHORT).show();
+                finish();
+                return;
+            } else {
+                String urlData = uri.getQueryParameter(Constants.WEEX_TPL_KEY);
+                if (TextUtils.isEmpty(urlData)){
+                    urlData = code;
+                }
+                Log.d("test->", "before nav activity ");
+                WXPreLoadManager.getInstance().preLoad(urlData);
+                Toast.makeText(this, rawResult.getText(), Toast.LENGTH_SHORT).show();
+                Intent intent = new Intent(CustomCaptureActivity.this, WXPageActivity.class);
+                intent.setData(Uri.parse(code));
+                startActivity(intent);
+            }
+        }
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        if (resultCode == RESULT_OK && requestCode == HISTORY_REQUEST_CODE
+                && historyManager != null) {
+            int itemNumber = intent
+                    .getIntExtra(historyManager.ITEM_NUMBER, -1);
+            if (itemNumber >= 0) {
+                HistoryItem historyItem = historyManager
+                        .buildHistoryItem(itemNumber);
+                handleDecodeInternally(historyItem.getResult());
+            }
+        }
+    }
+
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        capture.onResume();
+        historyManager = new HistoryManager(this);
+        historyManager.trimHistory();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        capture.onPause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        capture.onDestroy();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        capture.onSaveInstanceState(outState);
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
+        capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        return barcodeScannerView.onKeyDown(keyCode, event) || 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 i = item.getItemId();
+        if (i == R.id.menu_history) {
+            intent.setClassName(this, HistoryActivity.class.getName());
+            startActivityForResult(intent, HISTORY_REQUEST_CODE);
+        } else {
+            return super.onOptionsItemSelected(item);
+        }
+        return true;
+    }
+
+
+}
diff --git a/android/playground/src/main/java/com/alibaba/weex/IndexActivity.java b/android/playground/src/main/java/com/alibaba/weex/IndexActivity.java
index 2f0f971..5680b79 100644
--- a/android/playground/src/main/java/com/alibaba/weex/IndexActivity.java
+++ b/android/playground/src/main/java/com/alibaba/weex/IndexActivity.java
@@ -41,7 +41,7 @@ import android.widget.Toast;
 
 import com.alibaba.weex.commons.AbstractWeexActivity;
 import com.alibaba.weex.update.CheckForUpdateUtil;
-import com.google.zxing.client.android.CaptureActivity;
+import com.google.zxing.integration.android.IntentIntegrator;
 import com.taobao.weex.WXSDKEngine;
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.common.WXErrorCode;
@@ -137,7 +137,10 @@ public class IndexActivity extends AbstractWeexActivity {
             ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
           }
         } else {
-          startActivity(new Intent(this, CaptureActivity.class));
+          new IntentIntegrator(this).setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
+                  .setBeepEnabled(false).setCaptureActivity(CustomCaptureActivity.class)
+                  .initiateScan();
+     //     startActivity(new Intent(this, CaptureActivity.class));
         }
         break;
       default:
@@ -152,7 +155,9 @@ public class IndexActivity extends AbstractWeexActivity {
     super.onRequestPermissionsResult(requestCode, permissions, grantResults);
     if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
       if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-        startActivity(new Intent(this, CaptureActivity.class));
+        new IntentIntegrator(this).setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
+                .setBeepEnabled(false).setCaptureActivity(CustomCaptureActivity.class)
+                .initiateScan();
       } else {
         Toast.makeText(this, "request camara permission fail!", Toast.LENGTH_SHORT).show();
       }
diff --git a/android/playground/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java b/android/playground/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java
index 5c63a1f..1396ef2 100644
--- a/android/playground/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java
+++ b/android/playground/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java
@@ -31,8 +31,9 @@ import android.support.v7.app.AppCompatActivity;
 import android.text.TextUtils;
 import android.widget.Toast;
 
+import com.alibaba.weex.CustomCaptureActivity;
 import com.alibaba.weex.WXPageActivity;
-import com.google.zxing.client.android.CaptureActivity;
+import com.google.zxing.integration.android.IntentIntegrator;
 import com.taobao.weex.annotation.JSMethod;
 import com.taobao.weex.bridge.JSCallback;
 import com.taobao.weex.common.WXModule;
@@ -65,7 +66,10 @@ public class WXEventModule extends WXModule {
           ActivityCompat.requestPermissions((Activity) mWXSDKInstance.getContext(), new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
         }
       } else {
-        mWXSDKInstance.getContext().startActivity(new Intent(mWXSDKInstance.getContext(), CaptureActivity.class));
+        new IntentIntegrator((Activity) mWXSDKInstance.getContext()).setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
+                .setBeepEnabled(false).setCaptureActivity(CustomCaptureActivity.class)
+                .initiateScan();
+ //       mWXSDKInstance.getContext().startActivity(new Intent(mWXSDKInstance.getContext(), CaptureActivity.class));
       }
       return;
     }
@@ -129,10 +133,14 @@ public class WXEventModule extends WXModule {
       super.onRequestPermissionsResult(requestCode, permissions, grantResults);
       if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
           if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-              mWXSDKInstance.getContext().startActivity(new Intent(mWXSDKInstance.getContext(), CaptureActivity.class));
+            new IntentIntegrator((Activity) mWXSDKInstance.getContext()).setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
+                    .setBeepEnabled(false).setCaptureActivity(CustomCaptureActivity.class)
+                    .initiateScan();
+ //             mWXSDKInstance.getContext().startActivity(new Intent(mWXSDKInstance.getContext(), CaptureActivity.class));
           } else {
               Toast.makeText(mWXSDKInstance.getContext(), "request camara permission fail!", Toast.LENGTH_SHORT).show();
           }
       }
   }
+
 }
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/DBHelper.java b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/DBHelper.java
similarity index 97%
rename from android/playground/src/main/java_zxing/com/google/zxing/client/android/history/DBHelper.java
rename to android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/DBHelper.java
index 290d867..5731cfd 100755
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/DBHelper.java
+++ b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/DBHelper.java
@@ -13,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package com.google.zxing.client.android.history;
+package com.alibaba.weex.thirdParty.zxing;
 
 import android.content.Context;
 import android.database.sqlite.SQLiteDatabase;
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryActivity.java b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryActivity.java
similarity index 94%
rename from android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryActivity.java
rename to android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryActivity.java
index 555bf53..5cde864 100755
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryActivity.java
+++ b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryActivity.java
@@ -13,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package com.google.zxing.client.android.history;
+package com.alibaba.weex.thirdParty.zxing;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -35,9 +34,8 @@ import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
 
+import com.alibaba.weex.CustomCaptureActivity;
 import com.alibaba.weex.R;
-import com.google.zxing.client.android.CaptureActivity;
-import com.google.zxing.client.android.Intents;
 
 public final class HistoryActivity extends ListActivity {
 
@@ -79,8 +77,8 @@ public final class HistoryActivity extends ListActivity {
   @Override
   protected void onListItemClick(ListView l, View v, int position, long id) {
     if (adapter.getItem(position).getResult() != null) {
-      Intent intent = new Intent(this, CaptureActivity.class);
-      intent.putExtra(Intents.History.ITEM_NUMBER, position);
+      Intent intent = new Intent(this, CustomCaptureActivity.class);
+      intent.putExtra(historyManager.ITEM_NUMBER, position);
       setResult(Activity.RESULT_OK, intent);
       finish();
     }
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryItem.java b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryItem.java
similarity index 96%
rename from android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryItem.java
rename to android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryItem.java
index 45da8bd..72c5cca 100755
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryItem.java
+++ b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryItem.java
@@ -13,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package com.google.zxing.client.android.history;
+package com.alibaba.weex.thirdParty.zxing;
 
 import com.google.zxing.Result;
 
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryItemAdapter.java b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryItemAdapter.java
similarity index 97%
rename from android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryItemAdapter.java
rename to android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryItemAdapter.java
index 1ebb21c..34bbe60 100755
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryItemAdapter.java
+++ b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryItemAdapter.java
@@ -13,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package com.google.zxing.client.android.history;
+package com.alibaba.weex.thirdParty.zxing;
 
 import android.content.Context;
 import android.content.res.Resources;
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryManager.java b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryManager.java
similarity index 94%
rename from android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryManager.java
rename to android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryManager.java
index 281ae82..769b8f0 100755
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/history/HistoryManager.java
+++ b/android/playground/src/main/java/com/alibaba/weex/thirdParty/zxing/HistoryManager.java
@@ -13,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package com.google.zxing.client.android.history;
+package com.alibaba.weex.thirdParty.zxing;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -40,9 +39,6 @@ import android.util.Log;
 
 import com.google.zxing.BarcodeFormat;
 import com.google.zxing.Result;
-import com.google.zxing.client.android.Intents;
-import com.google.zxing.client.android.PreferencesActivity;
-import com.google.zxing.client.android.result.ResultHandler;
 
 /**
  * <p>Manages functionality related to scan history.</p>
@@ -70,11 +66,16 @@ public final class HistoryManager {
 
   private final Activity activity;
   private final boolean enableHistory;
+  public final String ITEM_NUMBER = "ITEM_NUMBER";
+  public static final String SAVE_HISTORY = "SAVE_HISTORY";
+  public static final String KEY_REMEMBER_DUPLICATES = "preferences_remember_duplicates";
+  public static final String KEY_ENABLE_HISTORY = "preferences_history";
+
 
   public HistoryManager(Activity activity) {
     this.activity = activity;
     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
-    enableHistory = prefs.getBoolean(PreferencesActivity.KEY_ENABLE_HISTORY, true);
+    enableHistory = prefs.getBoolean(KEY_ENABLE_HISTORY, true);
   }
 
   public boolean hasHistoryItems() {
@@ -151,23 +152,22 @@ public final class HistoryManager {
     }
   }
 
-  public void addHistoryItem(Result result, ResultHandler handler) {
+  public void addHistoryItem(Result result) {
     // Do not save this item to the history if the preference is turned off, or the contents are
     // considered secure.
-    if (!activity.getIntent().getBooleanExtra(Intents.Scan.SAVE_HISTORY, true) ||
-        handler.areContentsSecure() || !enableHistory) {
+    if (!activity.getIntent().getBooleanExtra(SAVE_HISTORY, true) || !enableHistory) {
       return;
     }
 
     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
-    if (!prefs.getBoolean(PreferencesActivity.KEY_REMEMBER_DUPLICATES, false)) {
+    if (!prefs.getBoolean(KEY_REMEMBER_DUPLICATES, false)) {
       deletePrevious(result.getText());
     }
 
     ContentValues values = new ContentValues();
     values.put(DBHelper.TEXT_COL, result.getText());
     values.put(DBHelper.FORMAT_COL, result.getBarcodeFormat().toString());
-    values.put(DBHelper.DISPLAY_COL, handler.getDisplayContents().toString());
+    values.put(DBHelper.DISPLAY_COL, result.getText());
     values.put(DBHelper.TIMESTAMP_COL, System.currentTimeMillis());
 
     SQLiteOpenHelper helper = new DBHelper(activity);
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/AmbientLightManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/AmbientLightManager.java
deleted file mode 100755
index cc4e405..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/AmbientLightManager.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2012 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.Context;
-import android.content.SharedPreferences;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.preference.PreferenceManager;
-
-import com.google.zxing.client.android.camera.CameraManager;
-import com.google.zxing.client.android.camera.FrontLightMode;
-
-/**
- * Detects ambient light and switches on the front light when very dark, and off again when sufficiently light.
- *
- * @author Sean Owen
- * @author Nikolaus Huber
- */
-final class AmbientLightManager implements SensorEventListener {
-
-  private static final float TOO_DARK_LUX = 45.0f;
-  private static final float BRIGHT_ENOUGH_LUX = 450.0f;
-
-  private final Context context;
-  private CameraManager cameraManager;
-  private Sensor lightSensor;
-
-  AmbientLightManager(Context context) {
-    this.context = context;
-  }
-
-  void start(CameraManager cameraManager) {
-    this.cameraManager = cameraManager;
-    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
-    if (FrontLightMode.readPref(sharedPrefs) == FrontLightMode.AUTO) {
-      SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
-      lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
-      if (lightSensor != null) {
-        sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
-      }
-    }
-  }
-
-  void stop() {
-    if (lightSensor != null) {
-      SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
-      sensorManager.unregisterListener(this);
-      cameraManager = null;
-      lightSensor = null;
-    }
-  }
-
-  @Override
-  public void onSensorChanged(SensorEvent sensorEvent) {
-    float ambientLightLux = sensorEvent.values[0];
-    if (cameraManager != null) {
-      if (ambientLightLux <= TOO_DARK_LUX) {
-        cameraManager.setTorch(true);
-      } else if (ambientLightLux >= BRIGHT_ENOUGH_LUX) {
-        cameraManager.setTorch(false);
-      }
-    }
-  }
-
-  @Override
-  public void onAccuracyChanged(Sensor sensor, int accuracy) {
-    // do nothing
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/BeepManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/BeepManager.java
deleted file mode 100755
index 7cf7467..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/BeepManager.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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 com.alibaba.weex.R;
-
-import java.io.Closeable;
-import java.io.IOException;
-
-
-/**
- * Manages beeps and vibrations for {@link CaptureActivity}.
- */
-final class BeepManager implements MediaPlayer.OnErrorListener, Closeable {
-
-  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();
-  }
-
-  synchronized 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);
-    }
-  }
-
-  synchronized 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 MediaPlayer buildMediaPlayer(Context activity) {
-    MediaPlayer mediaPlayer = new MediaPlayer();
-    try {
-      AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.beep);
-      try {
-        mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
-      } finally {
-        file.close();
-      }
-      mediaPlayer.setOnErrorListener(this);
-      mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
-      mediaPlayer.setLooping(false);
-      mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
-      mediaPlayer.prepare();
-      return mediaPlayer;
-    } catch (IOException ioe) {
-      Log.w(TAG, ioe);
-      mediaPlayer.release();
-      return null;
-    }
-  }
-
-  @Override
-  public synchronized boolean onError(MediaPlayer mp, int what, int extra) {
-    if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
-      // we are finished, so put up an appropriate error toast if required and finish
-      activity.finish();
-    } else {
-      // possibly media player error, so release and recreate
-      close();
-      updatePrefs();
-    }
-    return true;
-  }
-
-  @Override
-  public synchronized void close() {
-    if (mediaPlayer != null) {
-      mediaPlayer.release();
-      mediaPlayer = null;
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/CaptureActivity.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/CaptureActivity.java
deleted file mode 100755
index 1170348..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/CaptureActivity.java
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * 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.app.Activity;
-import android.app.AlertDialog;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-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.TextUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.alibaba.weex.R;
-import com.alibaba.weex.WXPageActivity;
-import com.alibaba.weex.WXPreLoadManager;
-import com.alibaba.weex.constants.Constants;
-
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.DecodeHintType;
-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.clipboard.ClipboardInterface;
-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.ResultHandler;
-import com.google.zxing.client.android.result.ResultHandlerFactory;
-import com.taobao.weex.WXEnvironment;
-import com.taobao.weex.WXSDKEngine;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Map;
-
-
-/**
- * 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[] ZXING_URLS = {
-					"http://zxing.appspot.com/scan", "zxing://scan/" };
-
-	public static final int HISTORY_REQUEST_CODE = 0x0000bacc;
-
-	private static final Collection<ResultMetadataType> 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 ScanFromWebPageManager scanFromWebPageManager;
-	private Collection<BarcodeFormat> decodeFormats;
-	private Map<DecodeHintType, ?> decodeHints;
-	private String characterSet;
-	private HistoryManager historyManager;
-	private InactivityTimer inactivityTimer;
-	private BeepManager beepManager;
-	private AmbientLightManager ambientLightManager;
-
-	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;
-		inactivityTimer = new InactivityTimer(this);
-		beepManager = new BeepManager(this);
-		ambientLightManager = new AmbientLightManager(this);
-
-		PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
-
-		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
-			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-		} else {
-			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-		}
-	}
-
-	@Override
-	protected void onResume() {
-		super.onResume();
-
-		// historyManager must be initialized here to update the history
-		// preference
-		historyManager = new HistoryManager(this);
-		historyManager.trimHistory();
-
-		// 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;
-
-		SharedPreferences prefs = PreferenceManager
-						.getDefaultSharedPreferences(this);
-
-//		if (prefs.getBoolean(PreferencesActivity.KEY_DISABLE_AUTO_ORIENTATION,
-//				true)) {
-//			setRequestedOrientation(getCurrentOrientation());
-//		} else {
-//			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
-//		}
-
-		resetStatusView();
-
-		beepManager.updatePrefs();
-		ambientLightManager.start(cameraManager);
-
-		inactivityTimer.onResume();
-
-		Intent intent = getIntent();
-
-		copyToClipboard = prefs.getBoolean(
-						PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true)
-						&& (intent == null || intent.getBooleanExtra(
-						Intents.Scan.SAVE_HISTORY, true));
-
-		source = IntentSource.NONE;
-		sourceUrl = null;
-		scanFromWebPageManager = null;
-		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);
-				decodeHints = DecodeHintManager.parseDecodeHints(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);
-					}
-				}
-
-				if (intent.hasExtra(Intents.Scan.CAMERA_ID)) {
-					int cameraId = intent.getIntExtra(Intents.Scan.CAMERA_ID,
-									-1);
-					if (cameraId >= 0) {
-						cameraManager.setManualCameraId(cameraId);
-					}
-				}
-
-				String customPromptMessage = intent
-								.getStringExtra(Intents.Scan.PROMPT_MESSAGE);
-				if (customPromptMessage != null) {
-					statusView.setText(customPromptMessage);
-				}
-
-			} else if (dataString != null
-							&& dataString.contains("http://www.google")
-							&& dataString.contains("/m/products/scan")) {
-
-				// 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(dataString);
-				scanFromWebPageManager = new ScanFromWebPageManager(inputUri);
-				decodeFormats = DecodeFormatManager
-								.parseDecodeFormats(inputUri);
-				// Allow a sub-set of the hints to be specified by the caller.
-				decodeHints = DecodeHintManager.parseDecodeHints(inputUri);
-
-			}
-
-			characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);
-
-		}
-
-		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);
-		}
-	}
-
-	private int getCurrentOrientation() {
-		int rotation = getWindowManager().getDefaultDisplay().getRotation();
-		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
-			switch (rotation) {
-				case Surface.ROTATION_0:
-				case Surface.ROTATION_90:
-					return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-				default:
-					return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
-			}
-		} else {
-			switch (rotation) {
-				case Surface.ROTATION_0:
-				case Surface.ROTATION_270:
-					return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-				default:
-					return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
-			}
-		}
-	}
-
-	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();
-		ambientLightManager.stop();
-		beepManager.close();
-		cameraManager.closeDriver();
-		// historyManager = null; // Keep for onActivityResult
-		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 i = item.getItemId();
-		if (i == R.id.menu_history) {
-			intent.setClassName(this, HistoryActivity.class.getName());
-			startActivityForResult(intent, HISTORY_REQUEST_CODE);
-
-			// case R.id.menu_settings:
-			// intent.setClassName(this, PreferencesActivity.class.getName());
-			// startActivity(intent);
-			// break;
-			// case R.id.menu_help:
-			// intent.setClassName(this, HelpActivity.class.getName());
-			// startActivity(intent);
-			// break;
-		} else {
-			return super.onOptionsItemSelected(item);
-		}
-		return true;
-	}
-
-	@Override
-	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
-		if (resultCode == RESULT_OK && requestCode == HISTORY_REQUEST_CODE
-						&& historyManager != null) {
-			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 scaleFactor
-	 *            amount by which thumbnail was scaled
-	 * @param barcode
-	 *            A greyscale bitmap of the camera data which was decoded.
-	 */
-	public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
-		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, scaleFactor, rawResult);
-		}
-
-		switch (source) {
-			case NATIVE_APP_INTENT:
-			case PRODUCT_SEARCH_LINK:
-				handleDecodeExternally(rawResult, resultHandler, barcode);
-				break;
-			case ZXING_LINK:
-				if (scanFromWebPageManager == null
-								|| !scanFromWebPageManager.isScanFromWebPage()) {
-					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)) {
-					Toast.makeText(
-									getApplicationContext(),
-									getResources()
-													.getString(R.string.msg_bulk_mode_scanned)
-													+ " (" + rawResult.getText() + ')',
-									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 scaleFactor
-	 *            amount by which thumbnail was scaled
-	 * @param rawResult
-	 *            The decoded results which contains the points to draw.
-	 */
-	private void drawResultPoints(Bitmap barcode, float scaleFactor,
-								  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], scaleFactor);
-			} 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], scaleFactor);
-				drawLine(canvas, paint, points[2], points[3], scaleFactor);
-			} else {
-				paint.setStrokeWidth(10.0f);
-				for (ResultPoint point : points) {
-					if (point != null) {
-						canvas.drawPoint(scaleFactor * point.getX(),
-										scaleFactor * point.getY(), paint);
-					}
-				}
-			}
-		}
-	}
-
-	private static void drawLine(Canvas canvas, Paint paint, ResultPoint a,
-								 ResultPoint b, float scaleFactor) {
-		if (a != null && b != null) {
-			canvas.drawLine(scaleFactor * a.getX(), scaleFactor * a.getY(),
-							scaleFactor * b.getX(), scaleFactor * b.getY(), paint);
-		}
-	}
-
-	// Put up our own UI for how to handle the decoded contents.
-	private void handleDecodeInternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
-		String code = rawResult.getText();
-		if (!TextUtils.isEmpty(code)) {
-			Uri uri = Uri.parse(code);
-			if (uri.getPath().contains("dynamic/replace")) {
-				Intent intent = new Intent("weex.intent.action.dynamic", uri);
-				intent.addCategory("weex.intent.category.dynamic");
-				startActivity(intent);
-				finish();
-			} else if (uri.getQueryParameterNames().contains("_wx_devtool")) {
-				WXEnvironment.sRemoteDebugProxyUrl = uri.getQueryParameter("_wx_devtool");
-				WXEnvironment.sDebugServerConnectable = true;
-				WXSDKEngine.reload();
-				Toast.makeText(this, "devtool", Toast.LENGTH_SHORT).show();
-				finish();
-				return;
-			} else {
-				String urlData = uri.getQueryParameter(Constants.WEEX_TPL_KEY);
-				if (TextUtils.isEmpty(urlData)){
-					urlData = code;
-				}
-				Log.d("test->", "before nav activity ");
-
-				WXPreLoadManager.getInstance().preLoad(urlData);
-				Toast.makeText(this, rawResult.getText(), Toast.LENGTH_SHORT).show();
-				Intent intent = new Intent(CaptureActivity.this, WXPageActivity.class);
-				intent.setData(Uri.parse(code));
-				startActivity(intent);
-			}
-		}
-	}
-
-	// 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);
-		}
-
-		if (resultDurationMS > 0) {
-			String rawResultString = String.valueOf(rawResult);
-			if (rawResultString.length() > 32) {
-				rawResultString = rawResultString.substring(0, 32) + " ...";
-			}
-			statusView.setText(getString(resultHandler.getDisplayTitle())
-							+ " : " + rawResultString);
-		}
-
-		if (copyToClipboard && !resultHandler.areContentsSecure()) {
-			CharSequence text = resultHandler.getDisplayContents();
-			ClipboardInterface.setText(text, this);
-		}
-
-		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<ResultMetadataType, ?> 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());
-				}
-				Number orientation = (Number) 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);
-				}
-				@SuppressWarnings("unchecked")
-				Iterable<byte[]> byteSegments = (Iterable<byte[]>) 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) {
-
-			if (scanFromWebPageManager != null
-							&& scanFromWebPageManager.isScanFromWebPage()) {
-				String replyURL = scanFromWebPageManager.buildReplyURL(
-								rawResult, resultHandler);
-				scanFromWebPageManager = null;
-				sendReplyMessage(R.id.launch_product_query, replyURL,
-								resultDurationMS);
-			}
-
-		}
-	}
-
-	private void sendReplyMessage(int id, Object arg, long delayMS) {
-		if (handler != null) {
-			Message message = Message.obtain(handler, id, arg);
-			if (delayMS > 0L) {
-				handler.sendMessageDelayed(message, delayMS);
-			} else {
-				handler.sendMessage(message);
-			}
-		}
-	}
-
-	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,
-								decodeHints, 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/playground/src/main/java_zxing/com/google/zxing/client/android/CaptureActivityHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/CaptureActivityHandler.java
deleted file mode 100755
index 3ff78ee..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/CaptureActivityHandler.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Browser;
-import android.util.Log;
-
-import com.alibaba.weex.R;
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.DecodeHintType;
-import com.google.zxing.Result;
-import com.google.zxing.client.android.camera.CameraManager;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * 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<BarcodeFormat> decodeFormats,
-                         Map<DecodeHintType,?> baseHints,
-                         String characterSet,
-                         CameraManager cameraManager) {
-    this.activity = activity;
-    decodeThread = new DecodeThread(activity, decodeFormats, baseHints, 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) {
-      restartPreviewAndDecode();
-
-    } else if (message.what == R.id.decode_succeeded) {
-      state = State.SUCCESS;
-      Bundle bundle = message.getData();
-      Bitmap barcode = null;
-      float scaleFactor = 1.0f;
-      if (bundle != null) {
-        byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
-        if (compressedBitmap != null) {
-          barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
-          // Mutable copy:
-          barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
-        }
-        scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);
-      }
-      activity.handleDecode((Result) message.obj, barcode, scaleFactor);
-
-    } 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) {
-      activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
-      activity.finish();
-
-    } else if (message.what == R.id.launch_product_query) {
-      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 != null && resolveInfo.activityInfo != null) {
-        browserPackageName = resolveInfo.activityInfo.packageName;
-        Log.d(TAG, "Using browser in package " + browserPackageName);
-      }
-
-      // Needed for default Android browser / Chrome only apparently
-      if ("com.android.browser".equals(browserPackageName) || "com.android.chrome".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 ignored) {
-        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/playground/src/main/java_zxing/com/google/zxing/client/android/Contents.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/Contents.java
deleted file mode 100755
index 1cfff17..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/Contents.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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:
-     * {@code
-     * import android.provider.Contacts;
-     *
-     * Intent intent = new Intent(Intents.Encode.ACTION);
-     * intent.putExtra(Intents.Encode.TYPE, CONTACT);
-     * Bundle bundle = new Bundle();
-     * bundle.putString(ContactsContract.Intents.Insert.NAME, "Jenny");
-     * bundle.putString(ContactsContract.Intents.Insert.PHONE, "8675309");
-     * bundle.putString(ContactsContract.Intents.Insert.EMAIL, "jenny@the80s.com");
-     * bundle.putString(ContactsContract.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/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeFormatManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeFormatManager.java
deleted file mode 100755
index 8c5194b..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeFormatManager.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-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 Set<BarcodeFormat> PRODUCT_FORMATS;
-  static final Set<BarcodeFormat> INDUSTRIAL_FORMATS;
-  private static final Set<BarcodeFormat> ONE_D_FORMATS;
-  static final Set<BarcodeFormat> QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
-  static final Set<BarcodeFormat> DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);
-  static final Set<BarcodeFormat> AZTEC_FORMATS = EnumSet.of(BarcodeFormat.AZTEC);
-  static final Set<BarcodeFormat> PDF417_FORMATS = EnumSet.of(BarcodeFormat.PDF_417);
-  static {
-    PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A,
-                                 BarcodeFormat.UPC_E,
-                                 BarcodeFormat.EAN_13,
-                                 BarcodeFormat.EAN_8,
-                                 BarcodeFormat.RSS_14,
-                                 BarcodeFormat.RSS_EXPANDED);
-    INDUSTRIAL_FORMATS = EnumSet.of(BarcodeFormat.CODE_39,
-                                    BarcodeFormat.CODE_93,
-                                    BarcodeFormat.CODE_128,
-                                    BarcodeFormat.ITF,
-                                    BarcodeFormat.CODABAR);
-    ONE_D_FORMATS = EnumSet.copyOf(PRODUCT_FORMATS);
-    ONE_D_FORMATS.addAll(INDUSTRIAL_FORMATS);
-  }
-  private static final Map<String,Set<BarcodeFormat>> FORMATS_FOR_MODE;
-  static {
-    FORMATS_FOR_MODE = new HashMap<>();
-    FORMATS_FOR_MODE.put(Intents.Scan.ONE_D_MODE, ONE_D_FORMATS);
-    FORMATS_FOR_MODE.put(Intents.Scan.PRODUCT_MODE, PRODUCT_FORMATS);
-    FORMATS_FOR_MODE.put(Intents.Scan.QR_CODE_MODE, QR_CODE_FORMATS);
-    FORMATS_FOR_MODE.put(Intents.Scan.DATA_MATRIX_MODE, DATA_MATRIX_FORMATS);
-    FORMATS_FOR_MODE.put(Intents.Scan.AZTEC_MODE, AZTEC_FORMATS);
-    FORMATS_FOR_MODE.put(Intents.Scan.PDF417_MODE, PDF417_FORMATS);
-  }
-
-  private DecodeFormatManager() {}
-
-  static Set<BarcodeFormat> parseDecodeFormats(Intent intent) {
-    Iterable<String> scanFormats = null;
-    CharSequence 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 Set<BarcodeFormat> parseDecodeFormats(Uri inputUri) {
-    List<String> 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 Set<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats, String decodeMode) {
-    if (scanFormats != null) {
-      Set<BarcodeFormat> 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) {
-      return FORMATS_FOR_MODE.get(decodeMode);
-    }
-    return null;
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeHandler.java
deleted file mode 100755
index 9a8770a..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeHandler.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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 android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.alibaba.weex.R;
-import com.google.zxing.BinaryBitmap;
-import com.google.zxing.DecodeHintType;
-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 java.io.ByteArrayOutputStream;
-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<DecodeHintType,Object> 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);
-    
-    byte[] rotatedData = new byte[data.length];
-    for (int y = 0; y < height; y++) {
-        for (int x = 0; x < width; x++)
-            rotatedData[x * height + height - y - 1] = data[x + y * width];
-    }
-    int tmp = width;
-    width = height;
-    height = tmp;
-    PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(rotatedData, 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();
-        bundleThumbnail(source, bundle);        
-        message.setData(bundle);
-        message.sendToTarget();
-      }
-    } else {
-      if (handler != null) {
-        Message message = Message.obtain(handler, R.id.decode_failed);
-        message.sendToTarget();
-      }
-    }
-  }
-
-  private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
-    int[] pixels = source.renderThumbnail();
-    int width = source.getThumbnailWidth();
-    int height = source.getThumbnailHeight();
-    Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
-    ByteArrayOutputStream out = new ByteArrayOutputStream();    
-    bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
-    bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
-    bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width / source.getWidth());
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeHintManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeHintManager.java
deleted file mode 100755
index 39305fe..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeHintManager.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2013 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.EnumMap;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.google.zxing.DecodeHintType;
-
-/**
- * @author Lachezar Dobrev
- */
-final class DecodeHintManager {
-  
-  private static final String TAG = DecodeHintManager.class.getSimpleName();
-
-  // This pattern is used in decoding integer arrays.
-  private static final Pattern COMMA = Pattern.compile(",");
-
-  private DecodeHintManager() {}
-
-  /**
-   * <p>Split a query string into a list of name-value pairs.</p>
-   * 
-   * <p>This is an alternative to the {@link Uri#getQueryParameterNames()} and
-   * {@link Uri#getQueryParameters(String)}, which are quirky and not suitable
-   * for exist-only Uri parameters.</p>
-   * 
-   * <p>This method ignores multiple parameters with the same name and returns the
-   * first one only. This is technically incorrect, but should be acceptable due
-   * to the method of processing Hints: no multiple values for a hint.</p>
-   * 
-   * @param query query to split
-   * @return name-value pairs
-   */
-  private static Map<String,String> splitQuery(String query) {
-    Map<String,String> map = new HashMap<>();
-    int pos = 0;
-    while (pos < query.length()) {
-      if (query.charAt(pos) == '&') {
-        // Skip consecutive ampersand separators.
-        pos ++;
-        continue;
-      }
-      int amp = query.indexOf('&', pos);
-      int equ = query.indexOf('=', pos);
-      if (amp < 0) {
-        // This is the last element in the query, no more ampersand elements.
-        String name;
-        String text;
-        if (equ < 0) {
-          // No equal sign
-          name = query.substring(pos);
-          name = name.replace('+', ' '); // Preemptively decode +
-          name = Uri.decode(name);
-          text = "";
-        } else {
-          // Split name and text.
-          name = query.substring(pos, equ);
-          name = name.replace('+', ' '); // Preemptively decode +
-          name = Uri.decode(name);
-          text = query.substring(equ + 1);
-          text = text.replace('+', ' '); // Preemptively decode +
-          text = Uri.decode(text);
-        }
-        if (!map.containsKey(name)) {
-          map.put(name, text);
-        }
-        break;
-      }
-      if (equ < 0 || equ > amp) {
-        // No equal sign until the &: this is a simple parameter with no value.
-        String name = query.substring(pos, amp);
-        name = name.replace('+', ' '); // Preemptively decode +
-        name = Uri.decode(name);
-        if (!map.containsKey(name)) {
-          map.put(name, "");
-        }
-        pos = amp + 1;
-        continue;
-      }
-      String name = query.substring(pos, equ);
-      name = name.replace('+', ' '); // Preemptively decode +
-      name = Uri.decode(name);
-      String text = query.substring(equ+1, amp);
-      text = text.replace('+', ' '); // Preemptively decode +
-      text = Uri.decode(text);
-      if (!map.containsKey(name)) {
-        map.put(name, text);
-      }
-      pos = amp + 1;
-    }
-    return map;
-  }
-
-  static Map<DecodeHintType,?> parseDecodeHints(Uri inputUri) {
-    String query = inputUri.getEncodedQuery();
-    if (query == null || query.isEmpty()) {
-      return null;
-    }
-
-    // Extract parameters
-    Map<String, String> parameters = splitQuery(query);
-
-    Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
-
-    for (DecodeHintType hintType: DecodeHintType.values()) {
-
-      if (hintType == DecodeHintType.CHARACTER_SET ||
-          hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK ||
-          hintType == DecodeHintType.POSSIBLE_FORMATS) {
-        continue; // This hint is specified in another way
-      }
-
-      String parameterName = hintType.name();
-      String parameterText = parameters.get(parameterName);
-      if (parameterText == null) {
-        continue;
-      }
-      if (hintType.getValueType().equals(Object.class)) {
-        // This is an unspecified type of hint content. Use the value as is.
-        // TODO: Can we make a different assumption on this?
-        hints.put(hintType, parameterText);
-        continue;
-      }
-      if (hintType.getValueType().equals(Void.class)) {
-        // Void hints are just flags: use the constant specified by DecodeHintType
-        hints.put(hintType, Boolean.TRUE);
-        continue;
-      }
-      if (hintType.getValueType().equals(String.class)) {
-        // A string hint: use the decoded value.
-        hints.put(hintType, parameterText);
-        continue;
-      }
-      if (hintType.getValueType().equals(Boolean.class)) {
-        // A boolean hint: a few values for false, everything else is true.
-        // An empty parameter is simply a flag-style parameter, assuming true
-        if (parameterText.isEmpty()) {
-          hints.put(hintType, Boolean.TRUE);
-        } else if ("0".equals(parameterText) || 
-                   "false".equalsIgnoreCase(parameterText) || 
-                   "no".equalsIgnoreCase(parameterText)) {
-          hints.put(hintType, Boolean.FALSE);
-        } else {
-          hints.put(hintType, Boolean.TRUE);
-        }
-
-        continue;
-      }
-      if (hintType.getValueType().equals(int[].class)) {
-        // An integer array. Used to specify valid lengths.
-        // Strip a trailing comma as in Java style array initialisers.
-        if (!parameterText.isEmpty() && parameterText.charAt(parameterText.length() - 1) == ',') {
-          parameterText = parameterText.substring(0, parameterText.length() - 1);
-        }
-        String[] values = COMMA.split(parameterText);
-        int[] array = new int[values.length];
-        for (int i = 0; i < values.length; i++) {
-          try {
-            array[i] = Integer.parseInt(values[i]);
-          } catch (NumberFormatException ignored) {
-            Log.w(TAG, "Skipping array of integers hint " + hintType + " due to invalid numeric value: '" + values[i] + '\'');
-            array = null;
-            break;
-          }
-        }
-        if (array != null) {
-          hints.put(hintType, array);
-        }
-        continue;
-      } 
-      Log.w(TAG, "Unsupported hint type '" + hintType + "' of type " + hintType.getValueType());
-    }
-
-    Log.i(TAG, "Hints from the URI: " + hints);
-    return hints;
-  }
-
-  static Map<DecodeHintType, Object> parseDecodeHints(Intent intent) {
-    Bundle extras = intent.getExtras();
-    if (extras == null || extras.isEmpty()) {
-      return null;
-    }
-    Map<DecodeHintType,Object> hints = new EnumMap<>(DecodeHintType.class);
-
-    for (DecodeHintType hintType: DecodeHintType.values()) {
-
-      if (hintType == DecodeHintType.CHARACTER_SET ||
-          hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK ||
-          hintType == DecodeHintType.POSSIBLE_FORMATS) {
-        continue; // This hint is specified in another way
-      }
-
-      String hintName = hintType.name();
-      if (extras.containsKey(hintName)) {
-        if (hintType.getValueType().equals(Void.class)) {
-          // Void hints are just flags: use the constant specified by the DecodeHintType
-          hints.put(hintType, Boolean.TRUE);
-        } else {
-          Object hintData = extras.get(hintName);
-          if (hintType.getValueType().isInstance(hintData)) {
-            hints.put(hintType, hintData);
-          } else {
-            Log.w(TAG, "Ignoring hint " + hintType + " because it is not assignable from " + hintData);
-          }
-        }
-      }
-    }
-
-    Log.i(TAG, "Hints from the Intent: " + hints);
-    return hints;
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeThread.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeThread.java
deleted file mode 100755
index a2a0e81..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/DecodeThread.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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 java.util.Collection;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-
-import android.content.SharedPreferences;
-import android.os.Handler;
-import android.os.Looper;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.DecodeHintType;
-import com.google.zxing.ResultPointCallback;
-
-/**
- * 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";
-  public static final String BARCODE_SCALED_FACTOR = "barcode_scaled_factor";
-
-  private final CaptureActivity activity;
-  private final Map<DecodeHintType,Object> hints;
-  private Handler handler;
-  private final CountDownLatch handlerInitLatch;
-
-  DecodeThread(CaptureActivity activity,
-               Collection<BarcodeFormat> decodeFormats,
-               Map<DecodeHintType,?> baseHints,
-               String characterSet,
-               ResultPointCallback resultPointCallback) {
-
-    this.activity = activity;
-    handlerInitLatch = new CountDownLatch(1);
-
-    hints = new EnumMap<>(DecodeHintType.class);
-    if (baseHints != null) {
-      hints.putAll(baseHints);
-    }
-
-    // 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_PRODUCT, true)) {
-        decodeFormats.addAll(DecodeFormatManager.PRODUCT_FORMATS);
-      }
-      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D_INDUSTRIAL, true)) {
-        decodeFormats.addAll(DecodeFormatManager.INDUSTRIAL_FORMATS);
-      }
-      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, true)) {
-        decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
-      }
-      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_DATA_MATRIX, true)) {
-        decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
-      }
-      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_AZTEC, false)) {
-        decodeFormats.addAll(DecodeFormatManager.AZTEC_FORMATS);
-      }
-      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_PDF417, false)) {
-        decodeFormats.addAll(DecodeFormatManager.PDF417_FORMATS);
-      }
-    }
-    hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
-
-    if (characterSet != null) {
-      hints.put(DecodeHintType.CHARACTER_SET, characterSet);
-    }
-    hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);
-    Log.i("DecodeThread", "Hints: " + hints);
-  }
-
-  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/playground/src/main/java_zxing/com/google/zxing/client/android/FinishListener.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/FinishListener.java
deleted file mode 100755
index 5d59886..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/FinishListener.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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/playground/src/main/java_zxing/com/google/zxing/client/android/HelpActivity.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/HelpActivity.java
deleted file mode 100755
index f7d3973..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/HelpActivity.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.os.Bundle;
-import android.view.KeyEvent;
-import android.webkit.WebView;
-
-import com.alibaba.weex.R;
-
-
-/**
- * An HTML-based help screen.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class HelpActivity extends Activity {
-
-  private static final String BASE_URL =
-      "file:///android_asset/html-" + LocaleManager.getTranslatedAssetLanguage() + '/';
-
-  private WebView webView;
-
-  @Override
-  protected void onCreate(Bundle icicle) {
-    super.onCreate(icicle);
-    setContentView(R.layout.help);
-
-    webView = (WebView) findViewById(R.id.help_contents);
-
-    if (icicle == null) {
-      webView.loadUrl(BASE_URL + "index.html");
-    } else {
-      webView.restoreState(icicle);
-    }
-  }
-
-  @Override
-  public boolean onKeyDown(int keyCode, KeyEvent event) {
-    if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
-      webView.goBack();
-      return true;
-    }
-    return super.onKeyDown(keyCode, event);
-  }
-
-  @Override
-  protected void onSaveInstanceState(Bundle icicle) {
-    super.onSaveInstanceState(icicle);
-    webView.saveState(icicle);
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/HttpHelper.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/HttpHelper.java
deleted file mode 100755
index 6e3de99..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/HttpHelper.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * 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 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;
-
-import android.util.Log;
-
-/**
- * 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<String> 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,
-    /** XML */
-    XML,
-    /** Plain text content */
-    TEXT,
-  }
-
-  /**
-   * Downloads the entire resource instead of part.
-   *
-   * @param uri URI to retrieve
-   * @param type expected text-like MIME type of that content
-   * @return content as a {@code String}
-   * @throws IOException if the content can't be retrieved because of a bad URI, network problem, etc.
-   * @see #downloadViaHttp(String, 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 XML:
-        contentTypes = "application/xml,text/*,*/*";
-        break;
-      case TEXT:
-      default:
-        contentTypes = "text/*,*/*";
-    }
-    return downloadViaHttp(uri, contentTypes, maxChars);
-  }
-
-  private static CharSequence downloadViaHttp(String uri, String contentTypes, int maxChars) throws IOException {
-    int redirects = 0;
-    while (redirects < 5) {
-      URL url = new URL(uri);
-      HttpURLConnection connection = safelyOpenConnection(url);
-      connection.setInstanceFollowRedirects(true); // Won't work HTTP -> HTTPS or vice versa
-      connection.setRequestProperty("Accept", contentTypes);
-      connection.setRequestProperty("Accept-Charset", "utf-8,*");
-      connection.setRequestProperty("User-Agent", "ZXing (Android)");
-      try {
-        int responseCode = safelyConnect(connection);
-        switch (responseCode) {
-          case HttpURLConnection.HTTP_OK:
-            return consume(connection, maxChars);
-          case HttpURLConnection.HTTP_MOVED_TEMP:
-            String location = connection.getHeaderField("Location");
-            if (location != null) {
-              uri = location;
-              redirects++;
-              continue;
-            }
-            throw new IOException("No Location");
-          default:
-            throw new IOException("Bad HTTP response: " + responseCode);
-        }
-      } finally {
-        connection.disconnect();
-      }
-    }
-    throw new IOException("Too many redirects");
-  }
-
-  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 | NullPointerException ioe) {
-          // continue
-        }
-      }
-    }
-    return out;
-  }
-
-  public static URI unredirect(URI uri) throws IOException {
-    if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
-      return uri;
-    }
-    URL url = uri.toURL();
-    HttpURLConnection connection = safelyOpenConnection(url);
-    connection.setInstanceFollowRedirects(false);
-    connection.setDoInput(false);
-    connection.setRequestMethod("HEAD");
-    connection.setRequestProperty("User-Agent", "ZXing (Android)");
-    try {
-      int responseCode = safelyConnect(connection);
-      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();
-    }
-  }
-  
-  private static HttpURLConnection safelyOpenConnection(URL url) throws IOException {
-    URLConnection conn;
-    try {
-      conn = url.openConnection();
-    } catch (NullPointerException npe) {
-      // Another strange bug in Android?
-      Log.w(TAG, "Bad URI? " + url);
-      throw new IOException(npe);
-    }
-    if (!(conn instanceof HttpURLConnection)) {
-      throw new IOException();
-    }
-    return (HttpURLConnection) conn;
-  }
-
-  private static int safelyConnect(HttpURLConnection connection) throws IOException {
-    try {
-      connection.connect();
-    } catch (NullPointerException | IllegalArgumentException | IndexOutOfBoundsException | SecurityException e) {
-      // this is an Android bug: http://code.google.com/p/android/issues/detail?id=16895
-      throw new IOException(e);
-    }
-    try {
-      return connection.getResponseCode();
-    } catch (NullPointerException | StringIndexOutOfBoundsException | IllegalArgumentException e) {
-      // this is maybe this Android bug: http://code.google.com/p/android/issues/detail?id=15554
-      throw new IOException(e);
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/InactivityTimer.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/InactivityTimer.java
deleted file mode 100755
index 5e33d90..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/InactivityTimer.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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;
-
-/**
- * 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 BroadcastReceiver powerStatusReceiver;
-  private boolean registered;
-  private AsyncTask<Object,Object,Object> inactivityTask;
-
-  InactivityTimer(Activity activity) {
-    this.activity = activity;
-    powerStatusReceiver = new PowerStatusReceiver();
-    registered = false;
-    onActivity();
-  }
-
-  synchronized void onActivity() {
-    cancel();
-    inactivityTask = new InactivityAsyncTask();
-    inactivityTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-  }
-
-  public synchronized void onPause() {
-    cancel();
-    if (registered) {
-      activity.unregisterReceiver(powerStatusReceiver);
-      registered = false;
-    } else {
-      Log.w(TAG, "PowerStatusReceiver was never registered?");
-    }
-  }
-
-  public synchronized void onResume() {
-    if (registered) {
-      Log.w(TAG, "PowerStatusReceiver was already registered?");
-    } else {
-      activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
-      registered = true;
-    }
-    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<Object,Object,Object> {
-    @Override
-    protected Object doInBackground(Object... objects) {
-      try {
-        Thread.sleep(INACTIVITY_DELAY_MS);
-        Log.i(TAG, "Finishing activity due to inactivity");
-        activity.finish();
-      } catch (InterruptedException e) {
-        // continue without killing
-      }
-      return null;
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/IntentSource.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/IntentSource.java
deleted file mode 100755
index 3222db6..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/IntentSource.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 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;
-
-enum IntentSource {
-
-  NATIVE_APP_INTENT,
-  PRODUCT_SEARCH_LINK,
-  ZXING_LINK,
-  NONE
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/Intents.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/Intents.java
deleted file mode 100755
index 6e59e80..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/Intents.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * 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;
-
-/**
- * This class provides the constants to use when sending an Intent to Barcode Scanner.
- * These strings are effectively API and cannot be changed.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class Intents {
-  private Intents() {
-  }
-
-  public static final class Scan {
-    /**
-     * Send this intent to open the Barcodes app in scanning mode, find a barcode, and return
-     * the results.
-     */
-    public static final String ACTION = "com.google.zxing.client.android.SCAN";
-
-    /**
-     * By default, sending this will decode all barcodes that we understand. However it
-     * may be useful to limit scanning to certain formats. Use
-     * {@link android.content.Intent#putExtra(String, String)} with one of the values below.
-     *
-     * Setting this is effectively shorthand for setting explicit formats with {@link #FORMATS}.
-     * It is overridden by that setting.
-     */
-    public static final String MODE = "SCAN_MODE";
-
-    /**
-     * Decode only UPC and EAN barcodes. This is the right choice for shopping apps which get
-     * prices, reviews, etc. for products.
-     */
-    public static final String PRODUCT_MODE = "PRODUCT_MODE";
-
-    /**
-     * Decode only 1D barcodes.
-     */
-    public static final String ONE_D_MODE = "ONE_D_MODE";
-
-    /**
-     * Decode only QR codes.
-     */
-    public static final String QR_CODE_MODE = "QR_CODE_MODE";
-
-    /**
-     * Decode only Data Matrix codes.
-     */
-    public static final String DATA_MATRIX_MODE = "DATA_MATRIX_MODE";
-
-    /**
-     * Decode only Aztec.
-     */
-    public static final String AZTEC_MODE = "AZTEC_MODE";
-
-    /**
-     * Decode only PDF417.
-     */
-    public static final String PDF417_MODE = "PDF417_MODE";
-
-    /**
-     * Comma-separated list of formats to scan for. The values must match the names of
-     * {@link com.google.zxing.BarcodeFormat}s, e.g. {@link com.google.zxing.BarcodeFormat#EAN_13}.
-     * Example: "EAN_13,EAN_8,QR_CODE". This overrides {@link #MODE}.
-     */
-    public static final String FORMATS = "SCAN_FORMATS";
-
-    /**
-     * Optional parameter to specify the id of the camera from which to recognize barcodes.
-     * Overrides the default camera that would otherwise would have been selected.
-     * If provided, should be an int.
-     */
-    public static final String CAMERA_ID = "SCAN_CAMERA_ID";
-
-    /**
-     * @see com.google.zxing.DecodeHintType#CHARACTER_SET
-     */
-    public static final String CHARACTER_SET = "CHARACTER_SET";
-
-    /**
-     * Optional parameters to specify the width and height of the scanning rectangle in pixels.
-     * The app will try to honor these, but will clamp them to the size of the preview frame.
-     * You should specify both or neither, and pass the size as an int.
-     */
-    public static final String WIDTH = "SCAN_WIDTH";
-    public static final String HEIGHT = "SCAN_HEIGHT";
-
-    /**
-     * Desired duration in milliseconds for which to pause after a successful scan before
-     * returning to the calling intent. Specified as a long, not an integer!
-     * For example: 1000L, not 1000.
-     */
-    public static final String RESULT_DISPLAY_DURATION_MS = "RESULT_DISPLAY_DURATION_MS";
-
-    /**
-     * Prompt to show on-screen when scanning by intent. Specified as a {@link String}.
-     */
-    public static final String PROMPT_MESSAGE = "PROMPT_MESSAGE";
-
-    /**
-     * If a barcode is found, Barcodes returns {@link android.app.Activity#RESULT_OK} to
-     * {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)}
-     * of the app which requested the scan via
-     * {@link android.app.Activity#startActivityForResult(android.content.Intent, int)}
-     * The barcodes contents can be retrieved with
-     * {@link android.content.Intent#getStringExtra(String)}. 
-     * If the user presses Back, the result code will be {@link android.app.Activity#RESULT_CANCELED}.
-     */
-    public static final String RESULT = "SCAN_RESULT";
-
-    /**
-     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_FORMAT}
-     * to determine which barcode format was found.
-     * See {@link com.google.zxing.BarcodeFormat} for possible values.
-     */
-    public static final String RESULT_FORMAT = "SCAN_RESULT_FORMAT";
-
-    /**
-     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_UPC_EAN_EXTENSION}
-     * to return the content of any UPC extension barcode that was also found. Only applicable
-     * to {@link com.google.zxing.BarcodeFormat#UPC_A} and {@link com.google.zxing.BarcodeFormat#EAN_13}
-     * formats.
-     */
-    public static final String RESULT_UPC_EAN_EXTENSION = "SCAN_RESULT_UPC_EAN_EXTENSION";
-
-    /**
-     * Call {@link android.content.Intent#getByteArrayExtra(String)} with {@link #RESULT_BYTES}
-     * to get a {@code byte[]} of raw bytes in the barcode, if available.
-     */
-    public static final String RESULT_BYTES = "SCAN_RESULT_BYTES";
-
-    /**
-     * Key for the value of {@link com.google.zxing.ResultMetadataType#ORIENTATION}, if available.
-     * Call {@link android.content.Intent#getIntArrayExtra(String)} with {@link #RESULT_ORIENTATION}.
-     */
-    public static final String RESULT_ORIENTATION = "SCAN_RESULT_ORIENTATION";
-
-    /**
-     * Key for the value of {@link com.google.zxing.ResultMetadataType#ERROR_CORRECTION_LEVEL}, if available.
-     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_ERROR_CORRECTION_LEVEL}.
-     */
-    public static final String RESULT_ERROR_CORRECTION_LEVEL = "SCAN_RESULT_ERROR_CORRECTION_LEVEL";
-
-    /**
-     * Prefix for keys that map to the values of {@link com.google.zxing.ResultMetadataType#BYTE_SEGMENTS},
-     * if available. The actual values will be set under a series of keys formed by adding 0, 1, 2, ...
-     * to this prefix. So the first byte segment is under key "SCAN_RESULT_BYTE_SEGMENTS_0" for example.
-     * Call {@link android.content.Intent#getByteArrayExtra(String)} with these keys.
-     */
-    public static final String RESULT_BYTE_SEGMENTS_PREFIX = "SCAN_RESULT_BYTE_SEGMENTS_";
-
-    /**
-     * Setting this to false will not save scanned codes in the history. Specified as a {@code boolean}.
-     */
-    public static final String SAVE_HISTORY = "SAVE_HISTORY";
-
-    private Scan() {
-    }
-  }
-
-  public static final class History {
-
-    public static final String ITEM_NUMBER = "ITEM_NUMBER";
-
-    private History() {
-    }
-  }
-
-  public static final class Encode {
-    /**
-     * Send this intent to encode a piece of data as a QR code and display it full screen, so
-     * that another person can scan the barcode from your screen.
-     */
-    public static final String ACTION = "com.google.zxing.client.android.ENCODE";
-
-    /**
-     * The data to encode. Use {@link android.content.Intent#putExtra(String, String)} or
-     * {@link android.content.Intent#putExtra(String, android.os.Bundle)}, 
-     * depending on the type and format specified. Non-QR Code formats should
-     * just use a String here. For QR Code, see Contents for details.
-     */
-    public static final String DATA = "ENCODE_DATA";
-
-    /**
-     * The type of data being supplied if the format is QR Code. Use
-     * {@link android.content.Intent#putExtra(String, String)} with one of {@link Contents.Type}.
-     */
-    public static final String TYPE = "ENCODE_TYPE";
-
-    /**
-     * The barcode format to be displayed. If this isn't specified or is blank,
-     * it defaults to QR Code. Use {@link android.content.Intent#putExtra(String, String)}, where
-     * format is one of {@link com.google.zxing.BarcodeFormat}.
-     */
-    public static final String FORMAT = "ENCODE_FORMAT";
-
-    /**
-     * Normally the contents of the barcode are displayed to the user in a TextView. Setting this
-     * boolean to false will hide that TextView, showing only the encode barcode.
-     */
-    public static final String SHOW_CONTENTS = "ENCODE_SHOW_CONTENTS";
-
-    private Encode() {
-    }
-  }
-
-  public static final class SearchBookContents {
-    /**
-     * Use Google Book Search to search the contents of the book provided.
-     */
-    public static final String ACTION = "com.google.zxing.client.android.SEARCH_BOOK_CONTENTS";
-
-    /**
-     * The book to search, identified by ISBN number.
-     */
-    public static final String ISBN = "ISBN";
-
-    /**
-     * An optional field which is the text to search for.
-     */
-    public static final String QUERY = "QUERY";
-
-    private SearchBookContents() {
-    }
-  }
-
-  public static final class WifiConnect {
-    /**
-     * Internal intent used to trigger connection to a wi-fi network.
-     */
-    public static final String ACTION = "com.google.zxing.client.android.WIFI_CONNECT";
-
-    /**
-     * The network to connect to, all the configuration provided here.
-     */
-    public static final String SSID = "SSID";
-
-    /**
-     * The network to connect to, all the configuration provided here.
-     */
-    public static final String TYPE = "TYPE";
-
-    /**
-     * The network to connect to, all the configuration provided here.
-     */
-    public static final String PASSWORD = "PASSWORD";
-
-    private WifiConnect() {
-    }
-  }
-
-  public static final class Share {
-    /**
-     * Give the user a choice of items to encode as a barcode, then render it as a QR Code and
-     * display onscreen for a friend to scan with their phone.
-     */
-    public static final String ACTION = "com.google.zxing.client.android.SHARE";
-
-    private Share() {
-    }
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/LocaleManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/LocaleManager.java
deleted file mode 100755
index 5d74c5d..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/LocaleManager.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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 java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
-/**
- * Handles any locale-specific logic for the client.
- *
- * @author Sean Owen
- */
-public final class LocaleManager {
-
-  private static final String DEFAULT_TLD = "com";
-  private static final String DEFAULT_COUNTRY = "US";
-  private static final String DEFAULT_LANGUAGE = "en";
-
-  /**
-   * Locales (well, countries) where Google web search is available.
-   * These should be kept in sync with our translations.
-   */
-  private static final Map<String,String> GOOGLE_COUNTRY_TLD;
-  static {
-    GOOGLE_COUNTRY_TLD = new HashMap<>();
-    GOOGLE_COUNTRY_TLD.put("AR", "com.ar"); // ARGENTINA
-    GOOGLE_COUNTRY_TLD.put("AU", "com.au"); // AUSTRALIA
-    GOOGLE_COUNTRY_TLD.put("BR", "com.br"); // BRAZIL
-    GOOGLE_COUNTRY_TLD.put("BG", "bg"); // BULGARIA
-    GOOGLE_COUNTRY_TLD.put(Locale.CANADA.getCountry(), "ca");
-    GOOGLE_COUNTRY_TLD.put(Locale.CHINA.getCountry(), "cn");
-    GOOGLE_COUNTRY_TLD.put("CZ", "cz"); // CZECH REPUBLIC
-    GOOGLE_COUNTRY_TLD.put("DK", "dk"); // DENMARK
-    GOOGLE_COUNTRY_TLD.put("FI", "fi"); // FINLAND
-    GOOGLE_COUNTRY_TLD.put(Locale.FRANCE.getCountry(), "fr");
-    GOOGLE_COUNTRY_TLD.put(Locale.GERMANY.getCountry(), "de");
-    GOOGLE_COUNTRY_TLD.put("GR", "gr"); // GREECE
-    GOOGLE_COUNTRY_TLD.put("HU", "hu"); // HUNGARY
-    GOOGLE_COUNTRY_TLD.put("ID", "co.id"); // INDONESIA
-    GOOGLE_COUNTRY_TLD.put("IL", "co.il"); // ISRAEL
-    GOOGLE_COUNTRY_TLD.put(Locale.ITALY.getCountry(), "it");
-    GOOGLE_COUNTRY_TLD.put(Locale.JAPAN.getCountry(), "co.jp");
-    GOOGLE_COUNTRY_TLD.put(Locale.KOREA.getCountry(), "co.kr");
-    GOOGLE_COUNTRY_TLD.put("NL", "nl"); // NETHERLANDS
-    GOOGLE_COUNTRY_TLD.put("PL", "pl"); // POLAND
-    GOOGLE_COUNTRY_TLD.put("PT", "pt"); // PORTUGAL
-    GOOGLE_COUNTRY_TLD.put("RO", "ro"); // ROMANIA    
-    GOOGLE_COUNTRY_TLD.put("RU", "ru"); // RUSSIA
-    GOOGLE_COUNTRY_TLD.put("SK", "sk"); // SLOVAK REPUBLIC
-    GOOGLE_COUNTRY_TLD.put("SI", "si"); // SLOVENIA
-    GOOGLE_COUNTRY_TLD.put("ES", "es"); // SPAIN
-    GOOGLE_COUNTRY_TLD.put("SE", "se"); // SWEDEN
-    GOOGLE_COUNTRY_TLD.put("CH", "ch"); // SWITZERLAND    
-    GOOGLE_COUNTRY_TLD.put(Locale.TAIWAN.getCountry(), "tw");
-    GOOGLE_COUNTRY_TLD.put("TR", "com.tr"); // TURKEY
-    GOOGLE_COUNTRY_TLD.put("UA", "com.ua"); // UKRAINE
-    GOOGLE_COUNTRY_TLD.put(Locale.UK.getCountry(), "co.uk");
-    GOOGLE_COUNTRY_TLD.put(Locale.US.getCountry(), "com");
-  }
-
-  /**
-   * Google Product Search for mobile is available in fewer countries than web search. See here:
-   * http://support.google.com/merchants/bin/answer.py?hl=en-GB&answer=160619
-   */
-  private static final Map<String,String> GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD;
-  static {
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD = new HashMap<>();
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put("AU", "com.au"); // AUSTRALIA
-    //GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.CHINA.getCountry(), "cn");
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.FRANCE.getCountry(), "fr");
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.GERMANY.getCountry(), "de");
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.ITALY.getCountry(), "it");
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.JAPAN.getCountry(), "co.jp");
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put("NL", "nl"); // NETHERLANDS
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put("ES", "es"); // SPAIN
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put("CH", "ch"); // SWITZERLAND
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.UK.getCountry(), "co.uk");
-    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.US.getCountry(), "com");
-  }
-
-  /**
-   * Book search is offered everywhere that web search is available.
-   */
-  private static final Map<String,String> GOOGLE_BOOK_SEARCH_COUNTRY_TLD = GOOGLE_COUNTRY_TLD;
-
-  private static final Collection<String> TRANSLATED_HELP_ASSET_LANGUAGES =
-      Arrays.asList("de", "en", "es", "fr", "it", "ja", "ko", "nl", "pt", "ru", "uk", "zh-rCN", "zh-rTW", "zh-rHK");
-
-  private LocaleManager() {}
-
-  /**
-   * @param context application's {@link Context}
-   * @return country-specific TLD suffix appropriate for the current default locale
-   *  (e.g. "co.uk" for the United Kingdom)
-   */
-  public static String getCountryTLD(Context context) {
-    return doGetTLD(GOOGLE_COUNTRY_TLD, context);
-  }
-
-  /**
-   * The same as above, but specifically for Google Product Search.
-   *
-   * @param context application's {@link Context}
-   * @return The top-level domain to use.
-   */
-  public static String getProductSearchCountryTLD(Context context) {
-    return doGetTLD(GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD, context);
-  }
-
-  /**
-   * The same as above, but specifically for Google Book Search.
-   *
-   * @param context application's {@link Context}
-   * @return The top-level domain to use.
-   */
-  public static String getBookSearchCountryTLD(Context context) {
-    return doGetTLD(GOOGLE_BOOK_SEARCH_COUNTRY_TLD, context);
-  }
-
-  /**
-   * Does a given URL point to Google Book Search, regardless of domain.
-   *
-   * @param url The address to check.
-   * @return True if this is a Book Search URL.
-   */
-  public static boolean isBookSearchUrl(String url) {
-    return url.startsWith("http://google.com/books") || url.startsWith("http://books.google.");
-  }
-
-  private static String getSystemCountry() {
-    Locale locale = Locale.getDefault();
-    return locale == null ? DEFAULT_COUNTRY : locale.getCountry();
-  }
-
-  private static String getSystemLanguage() {
-    Locale locale = Locale.getDefault();
-    if (locale == null) {
-      return DEFAULT_LANGUAGE;
-    }
-    String language = locale.getLanguage();
-    // Special case Chinese
-    if (Locale.SIMPLIFIED_CHINESE.getLanguage().equals(language)) {
-      return language + "-r" + getSystemCountry();
-    }
-    return language;
-  }
-
-  public static String getTranslatedAssetLanguage() {
-    String language = getSystemLanguage();
-    return TRANSLATED_HELP_ASSET_LANGUAGES.contains(language) ? language : DEFAULT_LANGUAGE;
-  }
-
-  private static String doGetTLD(Map<String,String> map, Context context) {
-    String tld = map.get(getCountry(context));
-    return tld == null ? DEFAULT_TLD : tld;
-  }
-
-  public static String getCountry(Context context) {
-    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-    String countryOverride = prefs.getString(PreferencesActivity.KEY_SEARCH_COUNTRY, "-");
-    if (countryOverride != null && !countryOverride.isEmpty() && !"-".equals(countryOverride)) {
-      return countryOverride;
-    }
-    return getSystemCountry();
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/PreferencesActivity.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/PreferencesActivity.java
deleted file mode 100755
index 8d0dc64..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/PreferencesActivity.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.app.Activity;
-import android.os.Bundle;
-
-/**
- * The main settings activity.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- * @author Sean Owen
- */
-public final class PreferencesActivity extends Activity {
-
-  public static final String KEY_DECODE_1D_PRODUCT = "preferences_decode_1D_product";
-  public static final String KEY_DECODE_1D_INDUSTRIAL = "preferences_decode_1D_industrial";
-  public static final String KEY_DECODE_QR = "preferences_decode_QR";
-  public static final String KEY_DECODE_DATA_MATRIX = "preferences_decode_Data_Matrix";
-  public static final String KEY_DECODE_AZTEC = "preferences_decode_Aztec";
-  public static final String KEY_DECODE_PDF417 = "preferences_decode_PDF417";
-
-  public static final String KEY_CUSTOM_PRODUCT_SEARCH = "preferences_custom_product_search";
-
-  public static final String KEY_PLAY_BEEP = "preferences_play_beep";
-  public static final String KEY_VIBRATE = "preferences_vibrate";
-  public static final String KEY_COPY_TO_CLIPBOARD = "preferences_copy_to_clipboard";
-  public static final String KEY_FRONT_LIGHT_MODE = "preferences_front_light_mode";
-  public static final String KEY_BULK_MODE = "preferences_bulk_mode";
-  public static final String KEY_REMEMBER_DUPLICATES = "preferences_remember_duplicates";
-  public static final String KEY_ENABLE_HISTORY = "preferences_history";
-  public static final String KEY_SUPPLEMENTAL = "preferences_supplemental";
-  public static final String KEY_AUTO_FOCUS = "preferences_auto_focus";
-  public static final String KEY_INVERT_SCAN = "preferences_invert_scan";  
-  public static final String KEY_SEARCH_COUNTRY = "preferences_search_country";
-  public static final String KEY_DISABLE_AUTO_ORIENTATION = "preferences_orientation";
-
-  public static final String KEY_DISABLE_CONTINUOUS_FOCUS = "preferences_disable_continuous_focus";
-  public static final String KEY_DISABLE_EXPOSURE = "preferences_disable_exposure";
-  public static final String KEY_DISABLE_METERING = "preferences_disable_metering";
-  public static final String KEY_DISABLE_BARCODE_SCENE_MODE = "preferences_disable_barcode_scene_mode";
-  public static final String KEY_AUTO_OPEN_WEB = "preferences_auto_open_web";
-
-  @Override
-  protected void onCreate(Bundle icicle) {
-    super.onCreate(icicle);
-    getFragmentManager().beginTransaction().replace(android.R.id.content, new PreferencesFragment()).commit();
-  }
-
-  // Apparently this will be necessary when targeting API 19+:
-  /*
-  @Override
-  protected boolean isValidFragment(String fragmentName) {
-    return true;
-  }
-   */
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/PreferencesFragment.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/PreferencesFragment.java
deleted file mode 100755
index 8fecd8a..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/PreferencesFragment.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2013 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.AlertDialog;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.EditTextPreference;
-import android.preference.Preference;
-import android.preference.PreferenceFragment;
-import android.preference.PreferenceScreen;
-
-import com.alibaba.weex.R;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
-
-
-public final class PreferencesFragment 
-    extends PreferenceFragment 
-    implements SharedPreferences.OnSharedPreferenceChangeListener {
-
-  private CheckBoxPreference[] checkBoxPrefs;
-  
-  @Override
-  public void onCreate(Bundle icicle) {
-    super.onCreate(icicle);
-    addPreferencesFromResource(R.xml.preferences);
-    
-    PreferenceScreen preferences = getPreferenceScreen();
-    preferences.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
-    checkBoxPrefs = findDecodePrefs(preferences,
-                                    PreferencesActivity.KEY_DECODE_1D_PRODUCT,
-                                    PreferencesActivity.KEY_DECODE_1D_INDUSTRIAL,
-                                    PreferencesActivity.KEY_DECODE_QR,
-                                    PreferencesActivity.KEY_DECODE_DATA_MATRIX,
-                                    PreferencesActivity.KEY_DECODE_AZTEC,
-                                    PreferencesActivity.KEY_DECODE_PDF417);
-    disableLastCheckedPref();
-
-    EditTextPreference customProductSearch = (EditTextPreference)
-        preferences.findPreference(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH);
-    customProductSearch.setOnPreferenceChangeListener(new CustomSearchURLValidator());
-  }
-
-  private static CheckBoxPreference[] findDecodePrefs(PreferenceScreen preferences, String... keys) {
-    CheckBoxPreference[] prefs = new CheckBoxPreference[keys.length];
-    for (int i = 0; i < keys.length; i++) {
-      prefs[i] = (CheckBoxPreference) preferences.findPreference(keys[i]);
-    }
-    return prefs;
-  }
-  
-  @Override
-  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-    disableLastCheckedPref();
-  }
-
-  private void disableLastCheckedPref() {
-    Collection<CheckBoxPreference> checked = new ArrayList<>(checkBoxPrefs.length);
-    for (CheckBoxPreference pref : checkBoxPrefs) {
-      if (pref.isChecked()) {
-        checked.add(pref);
-      }
-    }
-    boolean disable = checked.size() <= 1;
-    for (CheckBoxPreference pref : checkBoxPrefs) {
-      pref.setEnabled(!(disable && checked.contains(pref)));
-    }
-  }
-
-  private class CustomSearchURLValidator implements Preference.OnPreferenceChangeListener {
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-      if (!isValid(newValue)) {
-        AlertDialog.Builder builder =
-            new AlertDialog.Builder(PreferencesFragment.this.getActivity());
-        builder.setTitle(R.string.msg_error);
-        builder.setMessage(R.string.msg_invalid_value);
-        builder.setCancelable(true);
-        builder.show();
-        return false;
-      }
-      return true;
-    }
-
-    private boolean isValid(Object newValue) {
-      // Allow empty/null value
-      if (newValue == null) {
-        return true;
-      }
-      String valueString = newValue.toString();
-      if (valueString.isEmpty()) {
-        return true;
-      }
-      // Before validating, remove custom placeholders, which will not
-      // be considered valid parts of the URL in some locations:
-      // Blank %t and %s:
-      valueString = valueString.replaceAll("%[st]", "");
-      // Blank %f but not if followed by digit or a-f as it may be a hex sequence
-      valueString = valueString.replaceAll("%f(?![0-9a-f])", "");
-      // Require a scheme otherwise:
-      try {
-        URI uri = new URI(valueString);
-        return uri.getScheme() != null;
-      } catch (URISyntaxException use) {
-        return false;
-      }
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/ScanFromWebPageManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/ScanFromWebPageManager.java
deleted file mode 100755
index c8d1396..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/ScanFromWebPageManager.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2012 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.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
-import android.net.Uri;
-
-import com.google.zxing.Result;
-import com.google.zxing.client.android.result.ResultHandler;
-
-/**
- * Manages functionality related to responding to requests to scan from an HTTP link in a web page.
- * See <a href="http://github.com/zxing/zxing/wiki/ScanningFromWebPages">ScanningFromWebPages</a>.
- *
- * @author Sean Owen
- */
-final class ScanFromWebPageManager {
-
-  private static final CharSequence CODE_PLACEHOLDER = "{CODE}";
-  private static final CharSequence RAW_CODE_PLACEHOLDER = "{RAWCODE}";
-  private static final CharSequence META_PLACEHOLDER = "{META}";
-  private static final CharSequence FORMAT_PLACEHOLDER = "{FORMAT}";
-  private static final CharSequence TYPE_PLACEHOLDER = "{TYPE}";
-
-  private static final String RETURN_URL_PARAM = "ret";
-  private static final String RAW_PARAM = "raw";
-
-  private final String returnUrlTemplate;
-  private final boolean returnRaw;
-
-  ScanFromWebPageManager(Uri inputUri) {
-    returnUrlTemplate = inputUri.getQueryParameter(RETURN_URL_PARAM);
-    returnRaw = inputUri.getQueryParameter(RAW_PARAM) != null;
-  }
-
-  boolean isScanFromWebPage() {
-    return returnUrlTemplate != null;
-  }
-
-  String buildReplyURL(Result rawResult, ResultHandler resultHandler) {
-    String result = returnUrlTemplate;
-    result = replace(CODE_PLACEHOLDER,
-                     returnRaw ? rawResult.getText() : resultHandler.getDisplayContents(), result);
-    result = replace(RAW_CODE_PLACEHOLDER, rawResult.getText(), result);
-    result = replace(FORMAT_PLACEHOLDER, rawResult.getBarcodeFormat().toString(), result);
-    result = replace(TYPE_PLACEHOLDER, resultHandler.getType().toString(), result);
-    result = replace(META_PLACEHOLDER, String.valueOf(rawResult.getResultMetadata()), result);
-    return result;
-  }
-
-  private static String replace(CharSequence placeholder, CharSequence with, String pattern) {
-    CharSequence escapedWith = with == null ? "" : with;
-    try {
-      escapedWith = URLEncoder.encode(escapedWith.toString(), "UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      // can't happen; UTF-8 is always supported. Continue, I guess, without encoding
-    }
-    return pattern.replace(placeholder, escapedWith);
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/ViewfinderResultPointCallback.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/ViewfinderResultPointCallback.java
deleted file mode 100755
index 48009a9..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/ViewfinderResultPointCallback.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 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.client.android;
-
-import com.google.zxing.ResultPoint;
-import com.google.zxing.ResultPointCallback;
-
-final class ViewfinderResultPointCallback implements ResultPointCallback {
-
-  private final ViewfinderView viewfinderView;
-
-  ViewfinderResultPointCallback(ViewfinderView viewfinderView) {
-    this.viewfinderView = viewfinderView;
-  }
-
-  @Override
-  public void foundPossibleResultPoint(ResultPoint point) {
-    viewfinderView.addPossibleResultPoint(point);
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/ViewfinderView.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/ViewfinderView.java
deleted file mode 100755
index 84a0e06..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/ViewfinderView.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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.annotation.SuppressLint;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-
-import com.alibaba.weex.R;
-import com.google.zxing.ResultPoint;
-import com.google.zxing.client.android.camera.CameraManager;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial
- * transparency outside it, as well as the laser scanner animation and result points.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class ViewfinderView extends View {
-
-  private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
-  private static final long ANIMATION_DELAY = 80L;
-  private static final int CURRENT_POINT_OPACITY = 0xA0;
-  private static final int MAX_RESULT_POINTS = 20;
-  private static final int POINT_SIZE = 6;
-
-  private CameraManager cameraManager;
-  private final Paint paint;
-  private Bitmap resultBitmap;
-  private final int maskColor;
-  private final int resultColor;
-  private final int laserColor;
-  private final int resultPointColor;
-  private int scannerAlpha;
-  private List<ResultPoint> possibleResultPoints;
-  private List<ResultPoint> lastPossibleResultPoints;
-
-  // This constructor is used when the class is built from an XML resource.
-  public ViewfinderView(Context context, AttributeSet attrs) {
-    super(context, attrs);
-
-    // Initialize these once for performance rather than calling them every time in onDraw().
-    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-    Resources resources = getResources();
-    maskColor = resources.getColor(R.color.viewfinder_mask);
-    resultColor = resources.getColor(R.color.result_view);
-    laserColor = resources.getColor(R.color.viewfinder_laser);
-    resultPointColor = resources.getColor(R.color.possible_result_points);
-    scannerAlpha = 0;
-    possibleResultPoints = new ArrayList<>(5);
-    lastPossibleResultPoints = null;
-  }
-
-  public void setCameraManager(CameraManager cameraManager) {
-    this.cameraManager = cameraManager;
-  }
-
-  @SuppressLint("DrawAllocation")
-  @Override
-  public void onDraw(Canvas canvas) {
-    if (cameraManager == null) {
-      return; // not ready yet, early draw before done configuring
-    }
-    Rect frame = cameraManager.getFramingRect();
-    Rect previewFrame = cameraManager.getFramingRectInPreview();    
-    if (frame == null || previewFrame == null) {
-      return;
-    }
-    int width = canvas.getWidth();
-    int height = canvas.getHeight();
-
-    // Draw the exterior (i.e. outside the framing rect) darkened
-    paint.setColor(resultBitmap != null ? resultColor : maskColor);
-    canvas.drawRect(0, 0, width, frame.top, paint);
-    canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
-    canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
-    canvas.drawRect(0, frame.bottom + 1, width, height, paint);
-
-    if (resultBitmap != null) {
-      // Draw the opaque result bitmap over the scanning rectangle
-      paint.setAlpha(CURRENT_POINT_OPACITY);
-      canvas.drawBitmap(resultBitmap, null, frame, paint);
-    } else {
-
-      // Draw a red "laser scanner" line through the middle to show decoding is active
-      paint.setColor(laserColor);
-      paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
-      scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
-      int middle = frame.height() / 2 + frame.top;
-      canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
-      
-      float scaleX = frame.width() / (float) previewFrame.width();
-      float scaleY = frame.height() / (float) previewFrame.height();
-
-      List<ResultPoint> currentPossible = possibleResultPoints;
-      List<ResultPoint> currentLast = lastPossibleResultPoints;
-      int frameLeft = frame.left;
-      int frameTop = frame.top;
-      if (currentPossible.isEmpty()) {
-        lastPossibleResultPoints = null;
-      } else {
-        possibleResultPoints = new ArrayList<>(5);
-        lastPossibleResultPoints = currentPossible;
-        paint.setAlpha(CURRENT_POINT_OPACITY);
-        paint.setColor(resultPointColor);
-        synchronized (currentPossible) {
-          for (ResultPoint point : currentPossible) {
-            canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
-                              frameTop + (int) (point.getY() * scaleY),
-                              POINT_SIZE, paint);
-          }
-        }
-      }
-      if (currentLast != null) {
-        paint.setAlpha(CURRENT_POINT_OPACITY / 2);
-        paint.setColor(resultPointColor);
-        synchronized (currentLast) {
-          float radius = POINT_SIZE / 2.0f;
-          for (ResultPoint point : currentLast) {
-            canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
-                              frameTop + (int) (point.getY() * scaleY),
-                              radius, paint);
-          }
-        }
-      }
-
-      // Request another update at the animation interval, but only repaint the laser line,
-      // not the entire viewfinder mask.
-      postInvalidateDelayed(ANIMATION_DELAY,
-                            frame.left - POINT_SIZE,
-                            frame.top - POINT_SIZE,
-                            frame.right + POINT_SIZE,
-                            frame.bottom + POINT_SIZE);
-    }
-  }
-
-  public void drawViewfinder() {
-    Bitmap resultBitmap = this.resultBitmap;
-    this.resultBitmap = null;
-    if (resultBitmap != null) {
-      resultBitmap.recycle();
-    }
-    invalidate();
-  }
-
-  /**
-   * Draw a bitmap with the result points highlighted instead of the live scanning display.
-   *
-   * @param barcode An image of the decoded barcode.
-   */
-  public void drawResultBitmap(Bitmap barcode) {
-    resultBitmap = barcode;
-    invalidate();
-  }
-
-  public void addPossibleResultPoint(ResultPoint point) {
-    List<ResultPoint> points = possibleResultPoints;
-    synchronized (points) {
-      points.add(point);
-      int size = points.size();
-      if (size > MAX_RESULT_POINTS) {
-        // trim it
-        points.subList(0, size - MAX_RESULT_POINTS / 2).clear();
-      }
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/BrowseBookListener.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/BrowseBookListener.java
deleted file mode 100755
index 7d8a7c8..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/BrowseBookListener.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 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.client.android.book;
-
-import java.util.List;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.view.View;
-import android.widget.AdapterView;
-
-import com.google.zxing.client.android.LocaleManager;
-
-final class BrowseBookListener implements AdapterView.OnItemClickListener {
-
-  private final SearchBookContentsActivity activity;
-  private final List<SearchBookContentsResult> items;
-
-  BrowseBookListener(SearchBookContentsActivity activity, List<SearchBookContentsResult> items) {
-    this.activity = activity;
-    this.items = items;
-  }
-
-  @Override
-  public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
-    if (position < 1) {
-      // Clicked header, ignore it
-      return;
-    }
-    int itemOffset = position - 1;
-    if (itemOffset >= items.size()) {
-      return;
-    }
-    String pageId = items.get(itemOffset).getPageId();
-    String query = SearchBookContentsResult.getQuery();
-    if (LocaleManager.isBookSearchUrl(activity.getISBN()) && !pageId.isEmpty()) {
-      String uri = activity.getISBN();
-      int equals = uri.indexOf('=');
-      String volumeId = uri.substring(equals + 1);
-      String readBookURI = "http://books.google." +
-          LocaleManager.getBookSearchCountryTLD(activity) +
-          "/books?id=" + volumeId + "&pg=" + pageId + "&vq=" + query;
-      Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(readBookURI));
-      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);                    
-      activity.startActivity(intent);
-    }
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsActivity.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsActivity.java
deleted file mode 100755
index c33dbac..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsActivity.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * 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.book;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.webkit.CookieManager;
-import android.webkit.CookieSyncManager;
-import android.widget.EditText;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.android.HttpHelper;
-import com.google.zxing.client.android.Intents;
-import com.google.zxing.client.android.LocaleManager;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-
-/**
- * Uses Google Book Search to find a word or phrase in the requested book.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class SearchBookContentsActivity extends Activity {
-
-  private static final String TAG = SearchBookContentsActivity.class.getSimpleName();
-
-  private static final Pattern TAG_PATTERN = Pattern.compile("\\<.*?\\>");
-  private static final Pattern LT_ENTITY_PATTERN = Pattern.compile("&lt;");
-  private static final Pattern GT_ENTITY_PATTERN = Pattern.compile("&gt;");
-  private static final Pattern QUOTE_ENTITY_PATTERN = Pattern.compile("&#39;");
-  private static final Pattern QUOT_ENTITY_PATTERN = Pattern.compile("&quot;");
-
-  private String isbn;
-  private EditText queryTextView;
-  private View queryButton;
-  private ListView resultListView;
-  private TextView headerView;
-  private AsyncTask<String,?,?> networkTask;
-
-  private final View.OnClickListener buttonListener = new View.OnClickListener() {
-    @Override
-    public void onClick(View view) {
-      launchSearch();
-    }
-  };
-
-  private final View.OnKeyListener keyListener = new View.OnKeyListener() {
-    @Override
-    public boolean onKey(View view, int keyCode, KeyEvent event) {
-      if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
-        launchSearch();
-        return true;
-      }
-      return false;
-    }
-  };
-
-  String getISBN() {
-    return isbn;
-  }
-
-  @Override
-  public void onCreate(Bundle icicle) {
-    super.onCreate(icicle);
-
-    // Make sure that expired cookies are removed on launch.
-    CookieSyncManager.createInstance(this);
-    CookieManager.getInstance().removeExpiredCookie();
-
-    Intent intent = getIntent();
-    if (intent == null || !intent.getAction().equals(Intents.SearchBookContents.ACTION)) {
-      finish();
-      return;
-    }
-
-    isbn = intent.getStringExtra(Intents.SearchBookContents.ISBN);
-    if (LocaleManager.isBookSearchUrl(isbn)) {
-      setTitle(getString(R.string.sbc_name));
-    } else {
-      setTitle(getString(R.string.sbc_name) + ": ISBN " + isbn);
-    }
-
-    setContentView(R.layout.search_book_contents);
-    queryTextView = (EditText) findViewById(R.id.query_text_view);
-
-    String initialQuery = intent.getStringExtra(Intents.SearchBookContents.QUERY);
-    if (initialQuery != null && !initialQuery.isEmpty()) {
-      // Populate the search box but don't trigger the search
-      queryTextView.setText(initialQuery);
-    }
-    queryTextView.setOnKeyListener(keyListener);
-
-    queryButton = findViewById(R.id.query_button);
-    queryButton.setOnClickListener(buttonListener);
-
-    resultListView = (ListView) findViewById(R.id.result_list_view);
-    LayoutInflater factory = LayoutInflater.from(this);
-    headerView = (TextView) factory.inflate(R.layout.search_book_contents_header,
-        resultListView, false);
-    resultListView.addHeaderView(headerView);
-  }
-
-  @Override
-  protected void onResume() {
-    super.onResume();
-    queryTextView.selectAll();
-  }
-
-  @Override
-  protected void onPause() {
-    AsyncTask<?,?,?> oldTask = networkTask;
-    if (oldTask != null) {
-      oldTask.cancel(true);
-      networkTask = null;
-    }
-    super.onPause();
-  }
-
-  private void launchSearch() {
-    String query = queryTextView.getText().toString();
-    if (query != null && !query.isEmpty()) {
-      AsyncTask<?,?,?> oldTask = networkTask;
-      if (oldTask != null) {
-        oldTask.cancel(true);
-      }
-      networkTask = new NetworkTask();
-      networkTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, query, isbn);
-      headerView.setText(R.string.msg_sbc_searching_book);
-      resultListView.setAdapter(null);
-      queryTextView.setEnabled(false);
-      queryButton.setEnabled(false);
-    }
-  }
-
-  private final class NetworkTask extends AsyncTask<String,Object,JSONObject> {
-
-    @Override
-    protected JSONObject doInBackground(String... args) {
-      try {
-        // These return a JSON result which describes if and where the query was found. This API may
-        // break or disappear at any time in the future. Since this is an API call rather than a
-        // website, we don't use LocaleManager to change the TLD.
-        String theQuery = args[0];
-        String theIsbn = args[1];
-        String uri;
-        if (LocaleManager.isBookSearchUrl(theIsbn)) {
-          int equals = theIsbn.indexOf('=');
-          String volumeId = theIsbn.substring(equals + 1);
-          uri = "http://www.google.com/books?id=" + volumeId + "&jscmd=SearchWithinVolume2&q=" + theQuery;
-        } else {
-          uri = "http://www.google.com/books?vid=isbn" + theIsbn + "&jscmd=SearchWithinVolume2&q=" + theQuery;
-        }
-        CharSequence content = HttpHelper.downloadViaHttp(uri, HttpHelper.ContentType.JSON);
-        return new JSONObject(content.toString());
-      } catch (IOException ioe) {
-        Log.w(TAG, "Error accessing book search", ioe);
-        return null;
-      } catch (JSONException je) {
-        Log.w(TAG, "Error accessing book search", je);
-        return null;
-      }
-    }
-
-    @Override
-    protected void onPostExecute(JSONObject result) {
-      if (result == null) {
-        headerView.setText(R.string.msg_sbc_failed);
-      } else {
-        handleSearchResults(result);
-      }
-      queryTextView.setEnabled(true);
-      queryTextView.selectAll();
-      queryButton.setEnabled(true);
-    }
-
-    // Currently there is no way to distinguish between a query which had no results and a book
-    // which is not searchable - both return zero results.
-    private void handleSearchResults(JSONObject json) {
-      try {
-        int count = json.getInt("number_of_results");
-        headerView.setText(getString(R.string.msg_sbc_results) + " : " + count);
-        if (count > 0) {
-          JSONArray results = json.getJSONArray("search_results");
-          SearchBookContentsResult.setQuery(queryTextView.getText().toString());
-          List<SearchBookContentsResult> items = new ArrayList<>(count);
-          for (int x = 0; x < count; x++) {
-            items.add(parseResult(results.getJSONObject(x)));
-          }
-          resultListView.setOnItemClickListener(new BrowseBookListener(SearchBookContentsActivity.this, items));
-          resultListView.setAdapter(new SearchBookContentsAdapter(SearchBookContentsActivity.this, items));
-        } else {
-          String searchable = json.optString("searchable");
-          if ("false".equals(searchable)) {
-            headerView.setText(R.string.msg_sbc_book_not_searchable);
-          }
-          resultListView.setAdapter(null);
-        }
-      } catch (JSONException e) {
-        Log.w(TAG, "Bad JSON from book search", e);
-        resultListView.setAdapter(null);
-        headerView.setText(R.string.msg_sbc_failed);
-      }
-    }
-
-    // Available fields: page_id, page_number, snippet_text
-    private SearchBookContentsResult parseResult(JSONObject json) {
-
-      String pageId;
-      String pageNumber;
-      String snippet;
-      try {
-        pageId = json.getString("page_id");
-        pageNumber = json.optString("page_number");
-        snippet = json.optString("snippet_text");        
-      } catch (JSONException e) {
-        Log.w(TAG, e);
-        // Never seen in the wild, just being complete.
-        return new SearchBookContentsResult(getString(R.string.msg_sbc_no_page_returned), "", "", false);
-      }
-      
-      if (pageNumber == null || pageNumber.isEmpty()) {
-        // This can happen for text on the jacket, and possibly other reasons.
-        pageNumber = "";
-      } else {
-        pageNumber = getString(R.string.msg_sbc_page) + ' ' + pageNumber;
-      }
-      
-      boolean valid = snippet != null && !snippet.isEmpty();
-      if (valid) {
-        // Remove all HTML tags and encoded characters.          
-        snippet = TAG_PATTERN.matcher(snippet).replaceAll("");
-        snippet = LT_ENTITY_PATTERN.matcher(snippet).replaceAll("<");
-        snippet = GT_ENTITY_PATTERN.matcher(snippet).replaceAll(">");
-        snippet = QUOTE_ENTITY_PATTERN.matcher(snippet).replaceAll("'");
-        snippet = QUOT_ENTITY_PATTERN.matcher(snippet).replaceAll("\"");
-      } else {
-        snippet = '(' + getString(R.string.msg_sbc_snippet_unavailable) + ')';        
-      }
-
-      return new SearchBookContentsResult(pageId, pageNumber, snippet, valid);
-    }
-
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsAdapter.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsAdapter.java
deleted file mode 100755
index 49eaba7..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsAdapter.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.book;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-
-import com.alibaba.weex.R;
-
-import java.util.List;
-
-
-/**
- * Manufactures list items which represent SBC results.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-final class SearchBookContentsAdapter extends ArrayAdapter<SearchBookContentsResult> {
-
-  SearchBookContentsAdapter(Context context, List<SearchBookContentsResult> items) {
-    super(context, R.layout.search_book_contents_list_item, 0, items);
-  }
-
-  @Override
-  public View getView(int position, View view, ViewGroup viewGroup) {
-    SearchBookContentsListItem listItem;
-
-    if (view == null) {
-      LayoutInflater factory = LayoutInflater.from(getContext());
-      listItem = (SearchBookContentsListItem) factory.inflate(
-          R.layout.search_book_contents_list_item, viewGroup, false);
-    } else {
-      if (view instanceof SearchBookContentsListItem) {
-        listItem = (SearchBookContentsListItem) view;
-      } else {
-        return view;
-      }
-    }
-
-    SearchBookContentsResult result = getItem(position);
-    listItem.set(result);
-    return listItem;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsListItem.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsListItem.java
deleted file mode 100755
index 357d7ef..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsListItem.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.book;
-
-import android.content.Context;
-import android.graphics.Typeface;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.style.StyleSpan;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.alibaba.weex.R;
-
-import java.util.Locale;
-
-
-/**
- * A list item which displays the page number and snippet of this search result.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class SearchBookContentsListItem extends LinearLayout {
-  private TextView pageNumberView;
-  private TextView snippetView;
-
-  SearchBookContentsListItem(Context context) {
-    super(context);
-  }
-
-  public SearchBookContentsListItem(Context context, AttributeSet attrs) {
-    super(context, attrs);
-  }
-
-  @Override
-  protected void onFinishInflate() {
-    super.onFinishInflate();
-    pageNumberView = (TextView) findViewById(R.id.page_number_view);
-    snippetView = (TextView) findViewById(R.id.snippet_view);
-  }
-
-  public void set(SearchBookContentsResult result) {
-    pageNumberView.setText(result.getPageNumber());
-    String snippet = result.getSnippet();
-    if (snippet.isEmpty()) {
-      snippetView.setText("");
-    } else {
-      if (result.getValidSnippet()) {
-        String lowerQuery = SearchBookContentsResult.getQuery().toLowerCase(Locale.getDefault());
-        String lowerSnippet = snippet.toLowerCase(Locale.getDefault());
-        Spannable styledSnippet = new SpannableString(snippet);
-        StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
-        int queryLength = lowerQuery.length();
-        int offset = 0;
-        while (true) {
-          int pos = lowerSnippet.indexOf(lowerQuery, offset);
-          if (pos < 0) {
-            break;
-          }
-          styledSnippet.setSpan(boldSpan, pos, pos + queryLength, 0);
-          offset = pos + queryLength;
-        }
-        snippetView.setText(styledSnippet);
-      } else {
-        // This may be an error message, so don't try to bold the query terms within it
-        snippetView.setText(snippet);
-      }
-    }
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsResult.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsResult.java
deleted file mode 100755
index ffaafb3..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/book/SearchBookContentsResult.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.book;
-
-/**
- * The underlying data for a SBC result.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-final class SearchBookContentsResult {
-
-  private static String query = null;
-
-  private final String pageId;
-  private final String pageNumber;
-  private final String snippet;
-  private final boolean validSnippet;
-
-    SearchBookContentsResult(String pageId,
-                             String pageNumber,
-                             String snippet,
-                             boolean validSnippet) {
-    this.pageId = pageId;
-    this.pageNumber = pageNumber;
-    this.snippet = snippet;
-    this.validSnippet = validSnippet;
-  }
-
-  public static void setQuery(String query) {
-    SearchBookContentsResult.query = query;
-  }
-
-  public String getPageId() {
-    return pageId;
-  }
-
-  public String getPageNumber() {
-    return pageNumber;
-  }
-
-  public String getSnippet() {
-    return snippet;
-  }
-
-  public boolean getValidSnippet() {
-    return validSnippet;
-  }
-
-  public static String getQuery() {
-    return query;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/AutoFocusManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/AutoFocusManager.java
deleted file mode 100755
index b83e7ca..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/AutoFocusManager.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2012 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.camera;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.concurrent.RejectedExecutionException;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.hardware.Camera;
-import android.os.AsyncTask;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-import com.google.zxing.client.android.PreferencesActivity;
-
-final class AutoFocusManager implements Camera.AutoFocusCallback {
-
-  private static final String TAG = AutoFocusManager.class.getSimpleName();
-
-  private static final long AUTO_FOCUS_INTERVAL_MS = 2000L;
-  private static final Collection<String> FOCUS_MODES_CALLING_AF;
-  static {
-    FOCUS_MODES_CALLING_AF = new ArrayList<>(2);
-    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO);
-    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO);
-  }
-
-  private boolean stopped;
-  private boolean focusing;
-  private final boolean useAutoFocus;
-  private final Camera camera;
-  private AsyncTask<?,?,?> outstandingTask;
-
-  AutoFocusManager(Context context, Camera camera) {
-    this.camera = camera;
-    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
-    String currentFocusMode = camera.getParameters().getFocusMode();
-    useAutoFocus =
-        sharedPrefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true) &&
-        FOCUS_MODES_CALLING_AF.contains(currentFocusMode);
-    Log.i(TAG, "Current focus mode '" + currentFocusMode + "'; use auto focus? " + useAutoFocus);
-    start();
-  }
-
-  @Override
-  public synchronized void onAutoFocus(boolean success, Camera theCamera) {
-    focusing = false;
-    autoFocusAgainLater();
-  }
-
-  private synchronized void autoFocusAgainLater() {
-    if (!stopped && outstandingTask == null) {
-      AutoFocusTask newTask = new AutoFocusTask();
-      try {
-        newTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-        outstandingTask = newTask;
-      } catch (RejectedExecutionException ree) {
-        Log.w(TAG, "Could not request auto focus", ree);
-      }
-    }
-  }
-
-  synchronized void start() {
-    if (useAutoFocus) {
-      outstandingTask = null;
-      if (!stopped && !focusing) {
-        try {
-          camera.autoFocus(this);
-          focusing = true;
-        } catch (RuntimeException re) {
-          // Have heard RuntimeException reported in Android 4.0.x+; continue?
-          Log.w(TAG, "Unexpected exception while focusing", re);
-          // Try again later to keep cycle going
-          autoFocusAgainLater();
-        }
-      }
-    }
-  }
-
-  private synchronized void cancelOutstandingTask() {
-    if (outstandingTask != null) {
-      if (outstandingTask.getStatus() != AsyncTask.Status.FINISHED) {
-        outstandingTask.cancel(true);
-      }
-      outstandingTask = null;
-    }
-  }
-
-  synchronized void stop() {
-    stopped = true;
-    if (useAutoFocus) {
-      cancelOutstandingTask();
-      // Doesn't hurt to call this even if not focusing
-      try {
-        camera.cancelAutoFocus();
-      } catch (RuntimeException re) {
-        // Have heard RuntimeException reported in Android 4.0.x+; continue?
-        Log.w(TAG, "Unexpected exception while cancelling focusing", re);
-      }
-    }
-  }
-
-  private final class AutoFocusTask extends AsyncTask<Object,Object,Object> {
-    @Override
-    protected Object doInBackground(Object... voids) {
-      try {
-        Thread.sleep(AUTO_FOCUS_INTERVAL_MS);
-      } catch (InterruptedException e) {
-        // continue
-      }
-      start();
-      return null;
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraConfigurationManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraConfigurationManager.java
deleted file mode 100755
index 45af1a0..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraConfigurationManager.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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.camera;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.graphics.Point;
-import android.hardware.Camera;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.view.Display;
-import android.view.Surface;
-import android.view.WindowManager;
-
-import com.google.zxing.client.android.PreferencesActivity;
-import com.google.zxing.client.android.camera.open.CameraFacing;
-import com.google.zxing.client.android.camera.open.OpenCamera;
-
-/**
- * A class which deals with reading, parsing, and setting the camera parameters which are used to
- * configure the camera hardware.
- */
-final class CameraConfigurationManager {
-
-  private static final String TAG = "CameraConfiguration";
-
-  private final Context context;
-  private int cwNeededRotation;
-  private int cwRotationFromDisplayToCamera;
-  private Point screenResolution;
-  private Point cameraResolution;
-  private Point bestPreviewSize;
-  private Point previewSizeOnScreen;
-
-  CameraConfigurationManager(Context context) {
-    this.context = context;
-  }
-
-  /**
-   * Reads, one time, values from the camera that are needed by the app.
-   */
-  void initFromCameraParameters(OpenCamera camera) {
-    Camera.Parameters parameters = camera.getCamera().getParameters();
-    WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-    Display display = manager.getDefaultDisplay();
-
-    int displayRotation = display.getRotation();
-    int cwRotationFromNaturalToDisplay;
-    switch (displayRotation) {
-      case Surface.ROTATION_0:
-        cwRotationFromNaturalToDisplay = 0;
-        break;
-      case Surface.ROTATION_90:
-        cwRotationFromNaturalToDisplay = 90;
-        break;
-      case Surface.ROTATION_180:
-        cwRotationFromNaturalToDisplay = 180;
-        break;
-      case Surface.ROTATION_270:
-        cwRotationFromNaturalToDisplay = 270;
-        break;
-      default:
-        // Have seen this return incorrect values like -90
-        if (displayRotation % 90 == 0) {
-          cwRotationFromNaturalToDisplay = (360 + displayRotation) % 360;
-        } else {
-          throw new IllegalArgumentException("Bad rotation: " + displayRotation);
-        }
-    }
-    Log.i(TAG, "Display at: " + cwRotationFromNaturalToDisplay);
-
-    int cwRotationFromNaturalToCamera = camera.getOrientation();
-    Log.i(TAG, "Camera at: " + cwRotationFromNaturalToCamera);
-
-    // Still not 100% sure about this. But acts like we need to flip this:
-    if (camera.getFacing() == CameraFacing.FRONT) {
-      cwRotationFromNaturalToCamera = (360 - cwRotationFromNaturalToCamera) % 360;
-      Log.i(TAG, "Front camera overriden to: " + cwRotationFromNaturalToCamera);
-    }
-
-    /*
-    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-    String overrideRotationString;
-    if (camera.getFacing() == CameraFacing.FRONT) {
-      overrideRotationString = prefs.getString(PreferencesActivity.KEY_FORCE_CAMERA_ORIENTATION_FRONT, null);
-    } else {
-      overrideRotationString = prefs.getString(PreferencesActivity.KEY_FORCE_CAMERA_ORIENTATION, null);
-    }
-    if (overrideRotationString != null && !"-".equals(overrideRotationString)) {
-      Log.i(TAG, "Overriding camera manually to " + overrideRotationString);
-      cwRotationFromNaturalToCamera = Integer.parseInt(overrideRotationString);
-    }
-     */
-
-    cwRotationFromDisplayToCamera =
-        (360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360;
-    Log.i(TAG, "Final display orientation: " + cwRotationFromDisplayToCamera);
-    if (camera.getFacing() == CameraFacing.FRONT) {
-      Log.i(TAG, "Compensating rotation for front camera");
-      cwNeededRotation = (360 - cwRotationFromDisplayToCamera) % 360;
-    } else {
-      cwNeededRotation = cwRotationFromDisplayToCamera;
-    }
-    Log.i(TAG, "Clockwise rotation from display to camera: " + cwNeededRotation);
-
-    Point theScreenResolution = new Point();
-    display.getSize(theScreenResolution);
-    screenResolution = theScreenResolution;
-    Log.i(TAG, "Screen resolution in current orientation: " + screenResolution);
-    cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
-    Log.i(TAG, "Camera resolution: " + cameraResolution);
-    bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
-    Log.i(TAG, "Best available preview size: " + bestPreviewSize);
-
-    boolean isScreenPortrait = screenResolution.x < screenResolution.y;
-    boolean isPreviewSizePortrait = bestPreviewSize.x < bestPreviewSize.y;
-
-    if (isScreenPortrait == isPreviewSizePortrait) {
-      previewSizeOnScreen = bestPreviewSize;
-    } else {
-      previewSizeOnScreen = new Point(bestPreviewSize.y, bestPreviewSize.x);
-    }
-    Log.i(TAG, "Preview size on screen: " + previewSizeOnScreen);
-  }
-
-  void setDesiredCameraParameters(OpenCamera camera, boolean safeMode) {
-
-    Camera theCamera = camera.getCamera();
-    Camera.Parameters parameters = theCamera.getParameters();
-
-    if (parameters == null) {
-      Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
-      return;
-    }
-
-    Log.i(TAG, "Initial camera parameters: " + parameters.flatten());
-
-    if (safeMode) {
-      Log.w(TAG, "In camera config safe mode -- most settings will not be honored");
-    }
-
-    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-
-    initializeTorch(parameters, prefs, safeMode);
-
-    CameraConfigurationUtils.setFocus(
-        parameters,
-        prefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true),
-        prefs.getBoolean(PreferencesActivity.KEY_DISABLE_CONTINUOUS_FOCUS, true),
-        safeMode);
-
-    if (!safeMode) {
-      if (prefs.getBoolean(PreferencesActivity.KEY_INVERT_SCAN, false)) {
-        CameraConfigurationUtils.setInvertColor(parameters);
-      }
-
-      if (!prefs.getBoolean(PreferencesActivity.KEY_DISABLE_BARCODE_SCENE_MODE, true)) {
-        CameraConfigurationUtils.setBarcodeSceneMode(parameters);
-      }
-
-      if (!prefs.getBoolean(PreferencesActivity.KEY_DISABLE_METERING, true)) {
-        CameraConfigurationUtils.setVideoStabilization(parameters);
-        CameraConfigurationUtils.setFocusArea(parameters);
-        CameraConfigurationUtils.setMetering(parameters);
-      }
-
-    }
-
-    parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y);
-
-    theCamera.setDisplayOrientation(90);
-    theCamera.setParameters(parameters);
-
-    theCamera.setDisplayOrientation(cwRotationFromDisplayToCamera);
-
-    Camera.Parameters afterParameters = theCamera.getParameters();
-    Camera.Size afterSize = afterParameters.getPreviewSize();
-    if (afterSize != null && (bestPreviewSize.x != afterSize.width || bestPreviewSize.y != afterSize.height)) {
-      Log.w(TAG, "Camera said it supported preview size " + bestPreviewSize.x + 'x' + bestPreviewSize.y +
-          ", but after setting it, preview size is " + afterSize.width + 'x' + afterSize.height);
-      bestPreviewSize.x = afterSize.width;
-      bestPreviewSize.y = afterSize.height;
-    }
-  }
-
-  Point getBestPreviewSize() {
-    return bestPreviewSize;
-  }
-
-  Point getPreviewSizeOnScreen() {
-    return previewSizeOnScreen;
-  }
-
-  Point getCameraResolution() {
-    return cameraResolution;
-  }
-
-  Point getScreenResolution() {
-    return screenResolution;
-  }
-
-  int getCWNeededRotation() {
-    return cwNeededRotation;
-  }
-
-  boolean getTorchState(Camera camera) {
-    if (camera != null) {
-      Camera.Parameters parameters = camera.getParameters();
-      if (parameters != null) {
-        String flashMode = camera.getParameters().getFlashMode();
-        return flashMode != null &&
-            (Camera.Parameters.FLASH_MODE_ON.equals(flashMode) ||
-             Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode));
-      }
-    }
-    return false;
-  }
-
-  void setTorch(Camera camera, boolean newSetting) {
-    Camera.Parameters parameters = camera.getParameters();
-    doSetTorch(parameters, newSetting, false);
-    camera.setParameters(parameters);
-  }
-
-  private void initializeTorch(Camera.Parameters parameters, SharedPreferences prefs, boolean safeMode) {
-    boolean currentSetting = FrontLightMode.readPref(prefs) == FrontLightMode.ON;
-    doSetTorch(parameters, currentSetting, safeMode);
-  }
-
-  private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolean safeMode) {
-    CameraConfigurationUtils.setTorch(parameters, newSetting);
-    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-    if (!safeMode && !prefs.getBoolean(PreferencesActivity.KEY_DISABLE_EXPOSURE, true)) {
-      CameraConfigurationUtils.setBestExposure(parameters, newSetting);
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraConfigurationUtils.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraConfigurationUtils.java
deleted file mode 100755
index 32260a1..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraConfigurationUtils.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright (C) 2014 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.camera;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import android.annotation.TargetApi;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.os.Build;
-import android.util.Log;
-
-/**
- * Utility methods for configuring the Android camera.
- *
- * @author Sean Owen
- */
-@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
-public final class CameraConfigurationUtils {
-
-  private static final String TAG = "CameraConfiguration";
-
-  private static final Pattern SEMICOLON = Pattern.compile(";");
-
-  private static final int MIN_PREVIEW_PIXELS = 480 * 320; // normal screen
-  private static final float MAX_EXPOSURE_COMPENSATION = 1.5f;
-  private static final float MIN_EXPOSURE_COMPENSATION = 0.0f;
-  private static final double MAX_ASPECT_DISTORTION = 0.15;
-  private static final int MIN_FPS = 10;
-  private static final int MAX_FPS = 20;
-  private static final int AREA_PER_1000 = 400;
-
-  private CameraConfigurationUtils() {
-  }
-
-  public static void setFocus(Camera.Parameters parameters,
-                              boolean autoFocus,
-                              boolean disableContinuous,
-                              boolean safeMode) {
-    List<String> supportedFocusModes = parameters.getSupportedFocusModes();
-    String focusMode = null;
-    if (autoFocus) {
-      if (safeMode || disableContinuous) {
-        focusMode = findSettableValue("focus mode",
-                                       supportedFocusModes,
-                                       Camera.Parameters.FOCUS_MODE_AUTO);
-      } else {
-        focusMode = findSettableValue("focus mode",
-                                      supportedFocusModes,
-                                      Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
-                                      Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO,
-                                      Camera.Parameters.FOCUS_MODE_AUTO);
-      }
-    }
-    // Maybe selected auto-focus but not available, so fall through here:
-    if (!safeMode && focusMode == null) {
-      focusMode = findSettableValue("focus mode",
-                                    supportedFocusModes,
-                                    Camera.Parameters.FOCUS_MODE_MACRO,
-                                    Camera.Parameters.FOCUS_MODE_EDOF);
-    }
-    if (focusMode != null) {
-      if (focusMode.equals(parameters.getFocusMode())) {
-        Log.i(TAG, "Focus mode already set to " + focusMode);
-      } else {
-        parameters.setFocusMode(focusMode);
-      }
-    }
-  }
-
-  public static void setTorch(Camera.Parameters parameters, boolean on) {
-    List<String> supportedFlashModes = parameters.getSupportedFlashModes();
-    String flashMode;
-    if (on) {
-      flashMode = findSettableValue("flash mode",
-                                    supportedFlashModes,
-                                    Camera.Parameters.FLASH_MODE_TORCH,
-                                    Camera.Parameters.FLASH_MODE_ON);
-    } else {
-      flashMode = findSettableValue("flash mode",
-                                    supportedFlashModes,
-                                    Camera.Parameters.FLASH_MODE_OFF);
-    }
-    if (flashMode != null) {
-      if (flashMode.equals(parameters.getFlashMode())) {
-        Log.i(TAG, "Flash mode already set to " + flashMode);
-      } else {
-        Log.i(TAG, "Setting flash mode to " + flashMode);
-        parameters.setFlashMode(flashMode);
-      }
-    }
-  }
-
-  public static void setBestExposure(Camera.Parameters parameters, boolean lightOn) {
-    int minExposure = parameters.getMinExposureCompensation();
-    int maxExposure = parameters.getMaxExposureCompensation();
-    float step = parameters.getExposureCompensationStep();
-    if ((minExposure != 0 || maxExposure != 0) && step > 0.0f) {
-      // Set low when light is on
-      float targetCompensation = lightOn ? MIN_EXPOSURE_COMPENSATION : MAX_EXPOSURE_COMPENSATION;
-      int compensationSteps = Math.round(targetCompensation / step);
-      float actualCompensation = step * compensationSteps;
-      // Clamp value:
-      compensationSteps = Math.max(Math.min(compensationSteps, maxExposure), minExposure);
-      if (parameters.getExposureCompensation() == compensationSteps) {
-        Log.i(TAG, "Exposure compensation already set to " + compensationSteps + " / " + actualCompensation);
-      } else {
-        Log.i(TAG, "Setting exposure compensation to " + compensationSteps + " / " + actualCompensation);
-        parameters.setExposureCompensation(compensationSteps);
-      }
-    } else {
-      Log.i(TAG, "Camera does not support exposure compensation");
-    }
-  }
-
-  public static void setBestPreviewFPS(Camera.Parameters parameters) {
-    setBestPreviewFPS(parameters, MIN_FPS, MAX_FPS);
-  }
-
-  public static void setBestPreviewFPS(Camera.Parameters parameters, int minFPS, int maxFPS) {
-    List<int[]> supportedPreviewFpsRanges = parameters.getSupportedPreviewFpsRange();
-    Log.i(TAG, "Supported FPS ranges: " + toString(supportedPreviewFpsRanges));
-    if (supportedPreviewFpsRanges != null && !supportedPreviewFpsRanges.isEmpty()) {
-      int[] suitableFPSRange = null;
-      for (int[] fpsRange : supportedPreviewFpsRanges) {
-        int thisMin = fpsRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX];
-        int thisMax = fpsRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX];
-        if (thisMin >= minFPS * 1000 && thisMax <= maxFPS * 1000) {
-          suitableFPSRange = fpsRange;
-          break;
-        }
-      }
-      if (suitableFPSRange == null) {
-        Log.i(TAG, "No suitable FPS range?");
-      } else {
-        int[] currentFpsRange = new int[2];
-        parameters.getPreviewFpsRange(currentFpsRange);
-        if (Arrays.equals(currentFpsRange, suitableFPSRange)) {
-          Log.i(TAG, "FPS range already set to " + Arrays.toString(suitableFPSRange));
-        } else {
-          Log.i(TAG, "Setting FPS range to " + Arrays.toString(suitableFPSRange));
-          parameters.setPreviewFpsRange(suitableFPSRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
-                                        suitableFPSRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
-        }
-      }
-    }
-  }
-
-  public static void setFocusArea(Camera.Parameters parameters) {
-    if (parameters.getMaxNumFocusAreas() > 0) {
-      Log.i(TAG, "Old focus areas: " + toString(parameters.getFocusAreas()));
-      List<Camera.Area> middleArea = buildMiddleArea(AREA_PER_1000);
-      Log.i(TAG, "Setting focus area to : " + toString(middleArea));
-      parameters.setFocusAreas(middleArea);
-    } else {
-      Log.i(TAG, "Device does not support focus areas");
-    }
-  }
-
-  public static void setMetering(Camera.Parameters parameters) {
-    if (parameters.getMaxNumMeteringAreas() > 0) {
-      Log.i(TAG, "Old metering areas: " + parameters.getMeteringAreas());
-      List<Camera.Area> middleArea = buildMiddleArea(AREA_PER_1000);
-      Log.i(TAG, "Setting metering area to : " + toString(middleArea));
-      parameters.setMeteringAreas(middleArea);
-    } else {
-      Log.i(TAG, "Device does not support metering areas");
-    }
-  }
-
-  private static List<Camera.Area> buildMiddleArea(int areaPer1000) {
-    return Collections.singletonList(
-        new Camera.Area(new Rect(-areaPer1000, -areaPer1000, areaPer1000, areaPer1000), 1));
-  }
-
-  public static void setVideoStabilization(Camera.Parameters parameters) {
-    if (parameters.isVideoStabilizationSupported()) {
-      if (parameters.getVideoStabilization()) {
-        Log.i(TAG, "Video stabilization already enabled");
-      } else {
-        Log.i(TAG, "Enabling video stabilization...");
-        parameters.setVideoStabilization(true);
-      }
-    } else {
-      Log.i(TAG, "This device does not support video stabilization");
-    }
-  }
-
-  public static void setBarcodeSceneMode(Camera.Parameters parameters) {
-    if (Camera.Parameters.SCENE_MODE_BARCODE.equals(parameters.getSceneMode())) {
-      Log.i(TAG, "Barcode scene mode already set");
-      return;
-    }
-    String sceneMode = findSettableValue("scene mode",
-                                         parameters.getSupportedSceneModes(),
-                                         Camera.Parameters.SCENE_MODE_BARCODE);
-    if (sceneMode != null) {
-      parameters.setSceneMode(sceneMode);
-    }
-  }
-
-  public static void setZoom(Camera.Parameters parameters, double targetZoomRatio) {
-    if (parameters.isZoomSupported()) {
-      Integer zoom = indexOfClosestZoom(parameters, targetZoomRatio);
-      if (zoom == null) {
-        return;
-      }
-      if (parameters.getZoom() == zoom) {
-        Log.i(TAG, "Zoom is already set to " + zoom);
-      } else {
-        Log.i(TAG, "Setting zoom to " + zoom);
-        parameters.setZoom(zoom);
-      }
-    } else {
-      Log.i(TAG, "Zoom is not supported");
-    }
-  }
-
-  private static Integer indexOfClosestZoom(Camera.Parameters parameters, double targetZoomRatio) {
-    List<Integer> ratios = parameters.getZoomRatios();
-    Log.i(TAG, "Zoom ratios: " + ratios);
-    int maxZoom = parameters.getMaxZoom();
-    if (ratios == null || ratios.isEmpty() || ratios.size() != maxZoom + 1) {
-      Log.w(TAG, "Invalid zoom ratios!");
-      return null;
-    }
-    double target100 = 100.0 * targetZoomRatio;
-    double smallestDiff = Double.POSITIVE_INFINITY;
-    int closestIndex = 0;
-    for (int i = 0; i < ratios.size(); i++) {
-      double diff = Math.abs(ratios.get(i) - target100);
-      if (diff < smallestDiff) {
-        smallestDiff = diff;
-        closestIndex = i;
-      }
-    }
-    Log.i(TAG, "Chose zoom ratio of " + (ratios.get(closestIndex) / 100.0));
-    return closestIndex;
-  }
-
-  public static void setInvertColor(Camera.Parameters parameters) {
-    if (Camera.Parameters.EFFECT_NEGATIVE.equals(parameters.getColorEffect())) {
-      Log.i(TAG, "Negative effect already set");
-      return;
-    }
-    String colorMode = findSettableValue("color effect",
-                                         parameters.getSupportedColorEffects(),
-                                         Camera.Parameters.EFFECT_NEGATIVE);
-    if (colorMode != null) {
-      parameters.setColorEffect(colorMode);
-    }
-  }
-
-  public static Point findBestPreviewSizeValue(Camera.Parameters parameters, Point screenResolution) {
-
-    List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes();
-    if (rawSupportedSizes == null) {
-      Log.w(TAG, "Device returned no supported preview sizes; using default");
-      Camera.Size defaultSize = parameters.getPreviewSize();
-      if (defaultSize == null) {
-        throw new IllegalStateException("Parameters contained no preview size!");
-      }
-      return new Point(defaultSize.width, defaultSize.height);
-    }
-
-    // Sort by size, descending
-    List<Camera.Size> supportedPreviewSizes = new ArrayList<Camera.Size>(rawSupportedSizes);
-    Collections.sort(supportedPreviewSizes, new Comparator<Camera.Size>() {
-      @Override
-      public int compare(Camera.Size a, Camera.Size b) {
-        int aPixels = a.height * a.width;
-        int bPixels = b.height * b.width;
-        if (bPixels < aPixels) {
-          return -1;
-        }
-        if (bPixels > aPixels) {
-          return 1;
-        }
-        return 0;
-      }
-    });
-
-    if (Log.isLoggable(TAG, Log.INFO)) {
-      StringBuilder previewSizesString = new StringBuilder();
-      for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {
-        previewSizesString.append(supportedPreviewSize.width).append('x')
-            .append(supportedPreviewSize.height).append(' ');
-      }
-      Log.i(TAG, "Supported preview sizes: " + previewSizesString);
-    }
-
-    double screenAspectRatio = (double) screenResolution.x / (double) screenResolution.y;
-
-    // Remove sizes that are unsuitable
-    Iterator<Camera.Size> it = supportedPreviewSizes.iterator();
-    while (it.hasNext()) {
-      Camera.Size supportedPreviewSize = it.next();
-      int realWidth = supportedPreviewSize.width;
-      int realHeight = supportedPreviewSize.height;
-      if (realWidth * realHeight < MIN_PREVIEW_PIXELS) {
-        it.remove();
-        continue;
-      }
-
-      boolean isCandidatePortrait = realWidth < realHeight;
-      int maybeFlippedWidth = isCandidatePortrait ? realHeight : realWidth;
-      int maybeFlippedHeight = isCandidatePortrait ? realWidth : realHeight;
-      double aspectRatio = (double) maybeFlippedWidth / (double) maybeFlippedHeight;
-      double distortion = Math.abs(aspectRatio - screenAspectRatio);
-      if (distortion > MAX_ASPECT_DISTORTION) {
-        it.remove();
-        continue;
-      }
-
-      if (maybeFlippedWidth == screenResolution.x && maybeFlippedHeight == screenResolution.y) {
-        Point exactPoint = new Point(realWidth, realHeight);
-        Log.i(TAG, "Found preview size exactly matching screen size: " + exactPoint);
-        return exactPoint;
-      }
-    }
-
-    // If no exact match, use largest preview size. This was not a great idea on older devices because
-    // of the additional computation needed. We're likely to get here on newer Android 4+ devices, where
-    // the CPU is much more powerful.
-    if (!supportedPreviewSizes.isEmpty()) {
-      Camera.Size largestPreview = supportedPreviewSizes.get(0);
-      Point largestSize = new Point(largestPreview.width, largestPreview.height);
-      Log.i(TAG, "Using largest suitable preview size: " + largestSize);
-      return largestSize;
-    }
-
-    // If there is nothing at all suitable, return current preview size
-    Camera.Size defaultPreview = parameters.getPreviewSize();
-    if (defaultPreview == null) {
-      throw new IllegalStateException("Parameters contained no preview size!");
-    }
-    Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
-    Log.i(TAG, "No suitable preview sizes, using default: " + defaultSize);
-    return defaultSize;
-  }
-
-  private static String findSettableValue(String name,
-                                          Collection<String> supportedValues,
-                                          String... desiredValues) {
-    Log.i(TAG, "Requesting " + name + " value from among: " + Arrays.toString(desiredValues));
-    Log.i(TAG, "Supported " + name + " values: " + supportedValues);
-    if (supportedValues != null) {
-      for (String desiredValue : desiredValues) {
-        if (supportedValues.contains(desiredValue)) {
-          Log.i(TAG, "Can set " + name + " to: " + desiredValue);
-          return desiredValue;
-        }
-      }
-    }
-    Log.i(TAG, "No supported values match");
-    return null;
-  }
-
-  private static String toString(Collection<int[]> arrays) {
-    if (arrays == null || arrays.isEmpty()) {
-      return "[]";
-    }
-    StringBuilder buffer = new StringBuilder();
-    buffer.append('[');
-    Iterator<int[]> it = arrays.iterator();
-    while (it.hasNext()) {
-      buffer.append(Arrays.toString(it.next()));
-      if (it.hasNext()) {
-        buffer.append(", ");
-      }
-    }
-    buffer.append(']');
-    return buffer.toString();
-  }
-
-  private static String toString(Iterable<Camera.Area> areas) {
-    if (areas == null) {
-      return null;
-    }
-    StringBuilder result = new StringBuilder();
-    for (Camera.Area area : areas) {
-      result.append(area.rect).append(':').append(area.weight).append(' ');
-    }
-    return result.toString();
-  }
-
-  public static String collectStats(Camera.Parameters parameters) {
-    return collectStats(parameters.flatten());
-  }
-
-  public static String collectStats(CharSequence flattenedParams) {
-    StringBuilder result = new StringBuilder(1000);
-
-    result.append("BOARD=").append(Build.BOARD).append('\n');
-    result.append("BRAND=").append(Build.BRAND).append('\n');
-    result.append("CPU_ABI=").append(Build.CPU_ABI).append('\n');
-    result.append("DEVICE=").append(Build.DEVICE).append('\n');
-    result.append("DISPLAY=").append(Build.DISPLAY).append('\n');
-    result.append("FINGERPRINT=").append(Build.FINGERPRINT).append('\n');
-    result.append("HOST=").append(Build.HOST).append('\n');
-    result.append("ID=").append(Build.ID).append('\n');
-    result.append("MANUFACTURER=").append(Build.MANUFACTURER).append('\n');
-    result.append("MODEL=").append(Build.MODEL).append('\n');
-    result.append("PRODUCT=").append(Build.PRODUCT).append('\n');
-    result.append("TAGS=").append(Build.TAGS).append('\n');
-    result.append("TIME=").append(Build.TIME).append('\n');
-    result.append("TYPE=").append(Build.TYPE).append('\n');
-    result.append("USER=").append(Build.USER).append('\n');
-    result.append("VERSION.CODENAME=").append(Build.VERSION.CODENAME).append('\n');
-    result.append("VERSION.INCREMENTAL=").append(Build.VERSION.INCREMENTAL).append('\n');
-    result.append("VERSION.RELEASE=").append(Build.VERSION.RELEASE).append('\n');
-    result.append("VERSION.SDK_INT=").append(Build.VERSION.SDK_INT).append('\n');
-
-    if (flattenedParams != null) {
-      String[] params = SEMICOLON.split(flattenedParams);
-      Arrays.sort(params);
-      for (String param : params) {
-        result.append(param).append('\n');
-      }
-    }
-
-    return result.toString();
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraManager.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraManager.java
deleted file mode 100755
index 110f661..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/CameraManager.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * 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.camera;
-
-import java.io.IOException;
-
-import android.content.Context;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.os.Handler;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import com.google.zxing.PlanarYUVLuminanceSource;
-import com.google.zxing.client.android.camera.open.OpenCamera;
-import com.google.zxing.client.android.camera.open.OpenCameraInterface;
-
-/**
- * This object wraps the Camera service object and expects to be the only one talking to it. The
- * implementation encapsulates the steps needed to take preview-sized images, which are used for
- * both preview and decoding.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class CameraManager {
-
-  private static final String TAG = CameraManager.class.getSimpleName();
-
-  private static final int MIN_FRAME_WIDTH = 240;
-  private static final int MIN_FRAME_HEIGHT = 240;
-  private static final int MAX_FRAME_WIDTH = 1200; // = 5/8 * 1920
-  private static final int MAX_FRAME_HEIGHT = 675; // = 5/8 * 1080
-
-  private final Context context;
-  private final CameraConfigurationManager configManager;
-  private OpenCamera camera;
-  private AutoFocusManager autoFocusManager;
-  private Rect framingRect;
-  private Rect framingRectInPreview;
-  private boolean initialized;
-  private boolean previewing;
-  private int requestedCameraId = OpenCameraInterface.NO_REQUESTED_CAMERA;
-  private int requestedFramingRectWidth;
-  private int requestedFramingRectHeight;
-  /**
-   * Preview frames are delivered here, which we pass on to the registered handler. Make sure to
-   * clear the handler so it will only receive one message.
-   */
-  private final PreviewCallback previewCallback;
-
-  public CameraManager(Context context) {
-    this.context = context;
-    this.configManager = new CameraConfigurationManager(context);
-    previewCallback = new PreviewCallback(configManager);
-  }
-  
-  /**
-   * Opens the camera driver and initializes the hardware parameters.
-   *
-   * @param holder The surface object which the camera will draw preview frames into.
-   * @throws IOException Indicates the camera driver failed to open.
-   */
-  public synchronized void openDriver(SurfaceHolder holder) throws IOException {
-    OpenCamera theCamera = camera;
-    if (theCamera == null) {
-      theCamera = OpenCameraInterface.open(requestedCameraId);
-      if (theCamera == null) {
-        throw new IOException("Camera.open() failed to return object from driver");
-      }
-      camera = theCamera;
-    }
-
-    if (!initialized) {
-      initialized = true;
-      configManager.initFromCameraParameters(theCamera);
-      if (requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) {
-        setManualFramingRect(requestedFramingRectWidth, requestedFramingRectHeight);
-        requestedFramingRectWidth = 0;
-        requestedFramingRectHeight = 0;
-      }
-    }
-
-    Camera cameraObject = theCamera.getCamera();
-    Camera.Parameters parameters = cameraObject.getParameters();
-    String parametersFlattened = parameters == null ? null : parameters.flatten(); // Save these, temporarily
-    try {
-      configManager.setDesiredCameraParameters(theCamera, false);
-    } catch (RuntimeException re) {
-      // Driver failed
-      Log.w(TAG, "Camera rejected parameters. Setting only minimal safe-mode parameters");
-      Log.i(TAG, "Resetting to saved camera params: " + parametersFlattened);
-      // Reset:
-      if (parametersFlattened != null) {
-        parameters = cameraObject.getParameters();
-        parameters.unflatten(parametersFlattened);
-        try {
-          cameraObject.setParameters(parameters);
-          configManager.setDesiredCameraParameters(theCamera, true);
-        } catch (RuntimeException re2) {
-          // Well, darn. Give up
-          Log.w(TAG, "Camera rejected even safe-mode parameters! No configuration");
-        }
-      }
-    }
-    cameraObject.setPreviewDisplay(holder);
-
-  }
-
-  public synchronized boolean isOpen() {
-    return camera != null;
-  }
-
-  /**
-   * Closes the camera driver if still in use.
-   */
-  public synchronized void closeDriver() {
-    if (camera != null) {
-      camera.getCamera().release();
-      camera = null;
-      // Make sure to clear these each time we close the camera, so that any scanning rect
-      // requested by intent is forgotten.
-      framingRect = null;
-      framingRectInPreview = null;
-    }
-  }
-
-  /**
-   * Asks the camera hardware to begin drawing preview frames to the screen.
-   */
-  public synchronized void startPreview() {
-    OpenCamera theCamera = camera;
-    if (theCamera != null && !previewing) {
-      theCamera.getCamera().startPreview();
-      previewing = true;
-      autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
-    }
-  }
-
-  /**
-   * Tells the camera to stop drawing preview frames.
-   */
-  public synchronized void stopPreview() {
-    if (autoFocusManager != null) {
-      autoFocusManager.stop();
-      autoFocusManager = null;
-    }
-    if (camera != null && previewing) {
-      camera.getCamera().stopPreview();
-      previewCallback.setHandler(null, 0);
-      previewing = false;
-    }
-  }
-
-  /**
-   * Convenience method for {@link com.google.zxing.client.android.CaptureActivity}
-   *
-   * @param newSetting if {@code true}, light should be turned on if currently off. And vice versa.
-   */
-  public synchronized void setTorch(boolean newSetting) {
-    OpenCamera theCamera = camera;
-    if (theCamera != null) {
-      if (newSetting != configManager.getTorchState(theCamera.getCamera())) {
-        boolean wasAutoFocusManager = autoFocusManager != null;
-        if (wasAutoFocusManager) {
-          autoFocusManager.stop();
-          autoFocusManager = null;
-        }
-        configManager.setTorch(theCamera.getCamera(), newSetting);
-        if (wasAutoFocusManager) {
-          autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
-          autoFocusManager.start();
-        }
-      }
-    }
-  }
-
-  /**
-   * A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
-   * in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
-   * respectively.
-   *
-   * @param handler The handler to send the message to.
-   * @param message The what field of the message to be sent.
-   */
-  public synchronized void requestPreviewFrame(Handler handler, int message) {
-    OpenCamera theCamera = camera;
-    if (theCamera != null && previewing) {
-      previewCallback.setHandler(handler, message);
-      theCamera.getCamera().setOneShotPreviewCallback(previewCallback);
-    }
-  }
-
-  /**
-   * Calculates the framing rect which the UI should draw to show the user where to place the
-   * barcode. This target helps with alignment as well as forces the user to hold the device
-   * far enough away to ensure the image will be in focus.
-   *
-   * @return The rectangle to draw on screen in window coordinates.
-   */
-  public synchronized Rect getFramingRect() {
-    if (framingRect == null) {
-      if (camera == null) {
-        return null;
-      }
-      Point screenResolution = configManager.getScreenResolution();
-      if (screenResolution == null) {
-        // Called early, before init even finished
-        return null;
-      }
-
-      int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
-      int height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
-
-      int leftOffset = (screenResolution.x - width) / 2;
-      int topOffset = (screenResolution.y - height) / 2;
-      framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
-      Log.d(TAG, "Calculated framing rect: " + framingRect);
-    }
-    return framingRect;
-  }
-  
-  private static int findDesiredDimensionInRange(int resolution, int hardMin, int hardMax) {
-    int dim = 5 * resolution / 8; // Target 5/8 of each dimension
-    if (dim < hardMin) {
-      return hardMin;
-    }
-    if (dim > hardMax) {
-      return hardMax;
-    }
-    return dim;
-  }
-
-  /**
-   * Like {@link #getFramingRect} but coordinates are in terms of the preview frame,
-   * not UI / screen.
-   *
-   * @return {@link Rect} expressing barcode scan area in terms of the preview size
-   */
-  public synchronized Rect getFramingRectInPreview() {
-    if (framingRectInPreview == null) {
-      Rect framingRect = getFramingRect();
-      if (framingRect == null) {
-        return null;
-      }
-      Rect rect = new Rect(framingRect);
-      Point cameraResolution = configManager.getCameraResolution();
-      Point screenResolution = configManager.getScreenResolution();
-      if (cameraResolution == null || screenResolution == null) {
-        // Called early, before init even finished
-        return null;
-      }
-//      rect.left = rect.left * cameraResolution.x / screenResolution.x;
-//      rect.right = rect.right * cameraResolution.x / screenResolution.x;
-//      rect.top = rect.top * cameraResolution.y / screenResolution.y;
-//      rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
-      rect.left = rect.left * cameraResolution.y / screenResolution.x;
-      rect.right = rect.right * cameraResolution.y / screenResolution.x;
-      rect.top = rect.top * cameraResolution.x / screenResolution.y;
-      rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
-      
-      framingRectInPreview = rect;
-    }
-    return framingRectInPreview;
-  }
-
-  
-  /**
-   * Allows third party apps to specify the camera ID, rather than determine
-   * it automatically based on available cameras and their orientation.
-   *
-   * @param cameraId camera ID of the camera to use. A negative value means "no preference".
-   */
-  public synchronized void setManualCameraId(int cameraId) {
-    requestedCameraId = cameraId;
-  }
-  
-  /**
-   * Allows third party apps to specify the scanning rectangle dimensions, rather than determine
-   * them automatically based on screen resolution.
-   *
-   * @param width The width in pixels to scan.
-   * @param height The height in pixels to scan.
-   */
-  public synchronized void setManualFramingRect(int width, int height) {
-    if (initialized) {
-      Point screenResolution = configManager.getScreenResolution();
-      if (width > screenResolution.x) {
-        width = screenResolution.x;
-      }
-      if (height > screenResolution.y) {
-        height = screenResolution.y;
-      }
-      int leftOffset = (screenResolution.x - width) / 2;
-      int topOffset = (screenResolution.y - height) / 2;
-      framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
-      Log.d(TAG, "Calculated manual framing rect: " + framingRect);
-      framingRectInPreview = null;
-    } else {
-      requestedFramingRectWidth = width;
-      requestedFramingRectHeight = height;
-    }
-  }
-
-  /**
-   * A factory method to build the appropriate LuminanceSource object based on the format
-   * of the preview buffers, as described by Camera.Parameters.
-   *
-   * @param data A preview frame.
-   * @param width The width of the image.
-   * @param height The height of the image.
-   * @return A PlanarYUVLuminanceSource instance.
-   */
-  public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
-    Rect rect = getFramingRectInPreview();
-    if (rect == null) {
-      return null;
-    }
-    // Go ahead and assume it's YUV rather than die.
-    return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
-                                        rect.width(), rect.height(), false);
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/FrontLightMode.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/FrontLightMode.java
deleted file mode 100755
index 013339a..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/FrontLightMode.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 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.camera;
-
-import android.content.SharedPreferences;
-
-import com.google.zxing.client.android.PreferencesActivity;
-
-/**
- * Enumerates settings of the preference controlling the front light.
- */
-public enum FrontLightMode {
-
-  /** Always on. */
-  ON,
-  /** On only when ambient light is low. */
-  AUTO,
-  /** Always off. */
-  OFF;
-
-  private static FrontLightMode parse(String modeString) {
-    return modeString == null ? OFF : valueOf(modeString);
-  }
-
-  public static FrontLightMode readPref(SharedPreferences sharedPrefs) {
-    return parse(sharedPrefs.getString(PreferencesActivity.KEY_FRONT_LIGHT_MODE, OFF.toString()));
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/PreviewCallback.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/PreviewCallback.java
deleted file mode 100755
index 7dc7035..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/PreviewCallback.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.camera;
-
-import android.graphics.Point;
-import android.hardware.Camera;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-final class PreviewCallback implements Camera.PreviewCallback {
-
-  private static final String TAG = PreviewCallback.class.getSimpleName();
-
-  private final CameraConfigurationManager configManager;
-  private Handler previewHandler;
-  private int previewMessage;
-
-  PreviewCallback(CameraConfigurationManager configManager) {
-    this.configManager = configManager;
-  }
-
-  void setHandler(Handler previewHandler, int previewMessage) {
-    this.previewHandler = previewHandler;
-    this.previewMessage = previewMessage;
-  }
-
-  @Override
-  public void onPreviewFrame(byte[] data, Camera camera) {
-    Point cameraResolution = configManager.getCameraResolution();
-    Handler thePreviewHandler = previewHandler;
-    if (cameraResolution != null && thePreviewHandler != null) {
-      Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
-          cameraResolution.y, data);
-      message.sendToTarget();
-      previewHandler = null;
-    } else {
-      Log.d(TAG, "Got preview callback, but no handler or resolution available");
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/CameraFacing.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/CameraFacing.java
deleted file mode 100755
index 20fd4e3..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/CameraFacing.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.camera.open;
-
-public enum CameraFacing {
-
-  BACK,  // must be value 0!
-  FRONT, // must be value 1!
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/OpenCamera.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/OpenCamera.java
deleted file mode 100755
index ddac734..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/OpenCamera.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 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.camera.open;
-
-import android.hardware.Camera;
-
-public final class OpenCamera {
-  
-  private final int index;
-  private final Camera camera;
-  private final CameraFacing facing;
-  private final int orientation;
-  
-  public OpenCamera(int index, Camera camera, CameraFacing facing, int orientation) {
-    this.index = index;
-    this.camera = camera;
-    this.facing = facing;
-    this.orientation = orientation;
-  }
-
-  public Camera getCamera() {
-    return camera;
-  }
-
-  public CameraFacing getFacing() {
-    return facing;
-  }
-
-  public int getOrientation() {
-    return orientation;
-  }
-
-  @Override
-  public String toString() {
-    return "Camera #" + index + " : " + facing + ',' + orientation;
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/OpenCameraInterface.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/OpenCameraInterface.java
deleted file mode 100755
index 24e0f13..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/camera/open/OpenCameraInterface.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012 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.camera.open;
-
-import android.hardware.Camera;
-import android.util.Log;
-
-public final class OpenCameraInterface {
-
-  private static final String TAG = OpenCameraInterface.class.getName();
-
-  private OpenCameraInterface() {
-  }
-
-  /** For {@link #open(int)}, means no preference for which camera to open. */
-  public static final int NO_REQUESTED_CAMERA = -1;
-
-  /**
-   * Opens the requested camera with {@link Camera#open(int)}, if one exists.
-   *
-   * @param cameraId camera ID of the camera to use. A negative value
-   *  or {@link #NO_REQUESTED_CAMERA} means "no preference", in which case a rear-facing
-   *  camera is returned if possible or else any camera
-   * @return handle to {@link OpenCamera} that was opened
-   */
-  public static OpenCamera open(int cameraId) {
-
-    int numCameras = Camera.getNumberOfCameras();
-    if (numCameras == 0) {
-      Log.w(TAG, "No cameras!");
-      return null;
-    }
-
-    boolean explicitRequest = cameraId >= 0;
-
-    Camera.CameraInfo selectedCameraInfo = null;
-    int index;
-    if (explicitRequest) {
-      index = cameraId;
-      selectedCameraInfo = new Camera.CameraInfo();
-      Camera.getCameraInfo(index, selectedCameraInfo);
-    } else {
-      index = 0;
-      while (index < numCameras) {
-        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
-        Camera.getCameraInfo(index, cameraInfo);
-        CameraFacing reportedFacing = CameraFacing.values()[cameraInfo.facing];
-        if (reportedFacing == CameraFacing.BACK) {
-          selectedCameraInfo = cameraInfo;
-          break;
-        }
-        index++;
-      }
-    }
-
-    Camera camera;
-    if (index < numCameras) {
-      Log.i(TAG, "Opening camera #" + index);
-      camera = Camera.open(index);
-    } else {
-      if (explicitRequest) {
-        Log.w(TAG, "Requested camera does not exist: " + cameraId);
-        camera = null;
-      } else {
-        Log.i(TAG, "No camera facing " + CameraFacing.BACK + "; returning camera #0");
-        camera = Camera.open(0);
-        selectedCameraInfo = new Camera.CameraInfo();
-        Camera.getCameraInfo(0, selectedCameraInfo);
-      }
-    }
-
-    if (camera == null) {
-      return null;
-    }
-    return new OpenCamera(index,
-                          camera,
-                          CameraFacing.values()[selectedCameraInfo.facing],
-                          selectedCameraInfo.orientation);
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/clipboard/ClipboardInterface.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/clipboard/ClipboardInterface.java
deleted file mode 100755
index 3ba0603..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/clipboard/ClipboardInterface.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2012 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.clipboard;
-
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.util.Log;
-
-public final class ClipboardInterface {
-  
-  private static final String TAG = ClipboardInterface.class.getSimpleName();
-
-  private ClipboardInterface() {
-  }
-
-  public static CharSequence getText(Context context) {
-    ClipboardManager clipboard = getManager(context);
-    ClipData clip = clipboard.getPrimaryClip();
-    return hasText(context) ? clip.getItemAt(0).coerceToText(context) : null;
-  }
-
-  public static void setText(CharSequence text, Context context) {
-    if (text != null) {
-      try {
-        getManager(context).setPrimaryClip(ClipData.newPlainText(null, text));
-      } catch (NullPointerException | IllegalStateException e) {
-        // Have seen this in the wild, bizarrely
-        Log.w(TAG, "Clipboard bug", e);
-      }
-    }
-  }
-
-  public static boolean hasText(Context context) {
-    ClipboardManager clipboard = getManager(context);
-    ClipData clip = clipboard.getPrimaryClip();
-    return clip != null && clip.getItemCount() > 0;
-  }
-  
-  private static ClipboardManager getManager(Context context) {
-    return (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/ContactEncoder.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/ContactEncoder.java
deleted file mode 100755
index 41639a9..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/ContactEncoder.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 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.encode;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * Implementations encode according to some scheme for encoding contact information, like VCard or
- * MECARD.
- *
- * @author Sean Owen
- */
-abstract class ContactEncoder {
-
-  /**
-   * @return first, the best effort encoding of all data in the appropriate format; second, a
-   *   display-appropriate version of the contact information
-   */
-  abstract String[] encode(List<String> names,
-                           String organization,
-                           List<String> addresses,
-                           List<String> phones,
-                           List<String> phoneTypes,
-                           List<String> emails,
-                           List<String> urls,
-                           String note);
-
-  /**
-   * @return null if s is null or empty, or result of s.trim() otherwise
-   */
-  static String trim(String s) {
-    if (s == null) {
-      return null;
-    }
-    String result = s.trim();
-    return result.isEmpty() ? null : result;
-  }
-
-  static void append(StringBuilder newContents,
-                     StringBuilder newDisplayContents,
-                     String prefix,
-                     String value,
-                     Formatter fieldFormatter,
-                     char terminator) {
-    String trimmed = trim(value);
-    if (trimmed != null) {
-      newContents.append(prefix).append(fieldFormatter.format(trimmed, 0)).append(terminator);
-      newDisplayContents.append(trimmed).append('\n');
-    }
-  }
-
-  static void appendUpToUnique(StringBuilder newContents,
-                               StringBuilder newDisplayContents,
-                               String prefix,
-                               List<String> values,
-                               int max,
-                               Formatter displayFormatter,
-                               Formatter fieldFormatter,
-                               char terminator) {
-    if (values == null) {
-      return;
-    }
-    int count = 0;
-    Collection<String> uniques = new HashSet<>(2);
-    for (int i = 0; i < values.size(); i++) {
-      String value = values.get(i);
-      String trimmed = trim(value);
-      if (trimmed != null && !trimmed.isEmpty() && !uniques.contains(trimmed)) {
-        newContents.append(prefix).append(fieldFormatter.format(trimmed, i)).append(terminator);
-        CharSequence display = displayFormatter == null ? trimmed : displayFormatter.format(trimmed, i);
-        newDisplayContents.append(display).append('\n');
-        if (++count == max) {
-          break;
-        }
-        uniques.add(trimmed);
-      }
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/EncodeActivity.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/EncodeActivity.java
deleted file mode 100755
index 28866aa..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/EncodeActivity.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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.encode;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-import android.view.Display;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.WindowManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.alibaba.weex.R;
-import com.google.zxing.WriterException;
-import com.google.zxing.client.android.Contents;
-import com.google.zxing.client.android.FinishListener;
-import com.google.zxing.client.android.Intents;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.regex.Pattern;
-
-/**
- * This class encodes data from an Intent into a QR code, and then displays it full screen so that
- * another person can scan it with their device.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class EncodeActivity extends Activity {
-
-  private static final String TAG = EncodeActivity.class.getSimpleName();
-
-  private static final int MAX_BARCODE_FILENAME_LENGTH = 24;
-  private static final Pattern NOT_ALPHANUMERIC = Pattern.compile("[^A-Za-z0-9]");
-  private static final String USE_VCARD_KEY = "USE_VCARD";
-
-  private QRCodeEncoder qrCodeEncoder;
-
-  @Override
-  public void onCreate(Bundle icicle) {
-    super.onCreate(icicle);
-    Intent intent = getIntent();
-    if (intent == null) {
-      finish();
-    } else {
-      String action = intent.getAction();
-      if (Intents.Encode.ACTION.equals(action) || Intent.ACTION_SEND.equals(action)) {
-        setContentView(R.layout.encode);
-      } else {
-        finish();
-      }
-    }
-  }
-
-  @Override
-  public boolean onCreateOptionsMenu(Menu menu) {
-    MenuInflater menuInflater = getMenuInflater();
-    menuInflater.inflate(R.menu.encode, menu);
-    boolean useVcard = qrCodeEncoder != null && qrCodeEncoder.isUseVCard();
-    int encodeNameResource = useVcard ? R.string.menu_encode_mecard : R.string.menu_encode_vcard;
-    MenuItem encodeItem = menu.findItem(R.id.menu_encode);
-    encodeItem.setTitle(encodeNameResource);
-    Intent intent = getIntent();
-    if (intent != null) {
-      String type = intent.getStringExtra(Intents.Encode.TYPE);
-      encodeItem.setVisible(Contents.Type.CONTACT.equals(type));
-    }
-    return super.onCreateOptionsMenu(menu);
-  }
-
-  @Override
-  public boolean onOptionsItemSelected(MenuItem item) {
-    int i = item.getItemId();
-    if (i == R.id.menu_share) {
-      share();
-      return true;
-    } else if (i == R.id.menu_encode) {
-      Intent intent = getIntent();
-      if (intent == null) {
-        return false;
-      }
-      intent.putExtra(USE_VCARD_KEY, !qrCodeEncoder.isUseVCard());
-      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-      startActivity(intent);
-      finish();
-      return true;
-    } else {
-      return false;
-    }
-  }
-  
-  private void share() {
-    QRCodeEncoder encoder = qrCodeEncoder;
-    if (encoder == null) { // Odd
-      Log.w(TAG, "No existing barcode to send?");
-      return;
-    }
-
-    String contents = encoder.getContents();
-    if (contents == null) {
-      Log.w(TAG, "No existing barcode to send?");
-      return;
-    }
-
-    Bitmap bitmap;
-    try {
-      bitmap = encoder.encodeAsBitmap();
-    } catch (WriterException we) {
-      Log.w(TAG, we);
-      return;
-    }
-    if (bitmap == null) {
-      return;
-    }
-
-    File bsRoot = new File(Environment.getExternalStorageDirectory(), "BarcodeScanner");
-    File barcodesRoot = new File(bsRoot, "Barcodes");
-    if (!barcodesRoot.exists() && !barcodesRoot.mkdirs()) {
-      Log.w(TAG, "Couldn't make dir " + barcodesRoot);
-      showErrorMessage(R.string.msg_unmount_usb);
-      return;
-    }
-    File barcodeFile = new File(barcodesRoot, makeBarcodeFileName(contents) + ".png");
-    if (!barcodeFile.delete()) {
-      Log.w(TAG, "Could not delete " + barcodeFile);
-      // continue anyway
-    }
-    FileOutputStream fos = null;
-    try {
-      fos = new FileOutputStream(barcodeFile);
-      bitmap.compress(Bitmap.CompressFormat.PNG, 0, fos);
-    } catch (FileNotFoundException fnfe) {
-      Log.w(TAG, "Couldn't access file " + barcodeFile + " due to " + fnfe);
-      showErrorMessage(R.string.msg_unmount_usb);
-      return;
-    } finally {
-      if (fos != null) {
-        try {
-          fos.close();
-        } catch (IOException ioe) {
-          // do nothing
-        }
-      }
-    }
-
-    Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
-    intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name) + " - " + encoder.getTitle());
-    intent.putExtra(Intent.EXTRA_TEXT, contents);
-    intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + barcodeFile.getAbsolutePath()));
-    intent.setType("image/png");
-    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-    startActivity(Intent.createChooser(intent, null));
-  }
-
-  private static CharSequence makeBarcodeFileName(CharSequence contents) {
-    String fileName = NOT_ALPHANUMERIC.matcher(contents).replaceAll("_");
-    if (fileName.length() > MAX_BARCODE_FILENAME_LENGTH) {
-      fileName = fileName.substring(0, MAX_BARCODE_FILENAME_LENGTH);
-    }
-    return fileName;
-  }
-
-  @Override
-  protected void onResume() {
-    super.onResume();
-    // This assumes the view is full screen, which is a good assumption
-    WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
-    Display display = manager.getDefaultDisplay();
-    Point displaySize = new Point();
-    display.getSize(displaySize);
-    int width = displaySize.x;
-    int height = displaySize.y;
-    int smallerDimension = width < height ? width : height;
-    smallerDimension = smallerDimension * 7 / 8;
-
-    Intent intent = getIntent();
-    if (intent == null) {
-      return;
-    }
-
-    try {
-      boolean useVCard = intent.getBooleanExtra(USE_VCARD_KEY, false);
-      qrCodeEncoder = new QRCodeEncoder(this, intent, smallerDimension, useVCard);
-      Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();
-      if (bitmap == null) {
-        Log.w(TAG, "Could not encode barcode");
-        showErrorMessage(R.string.msg_encode_contents_failed);
-        qrCodeEncoder = null;
-        return;
-      }
-
-      ImageView view = (ImageView) findViewById(R.id.image_view);
-      view.setImageBitmap(bitmap);
-
-      TextView contents = (TextView) findViewById(R.id.contents_text_view);
-      if (intent.getBooleanExtra(Intents.Encode.SHOW_CONTENTS, true)) {
-        contents.setText(qrCodeEncoder.getDisplayContents());
-        setTitle(qrCodeEncoder.getTitle());
-      } else {
-        contents.setText("");
-        setTitle("");
-      }
-    } catch (WriterException e) {
-      Log.w(TAG, "Could not encode barcode", e);
-      showErrorMessage(R.string.msg_encode_contents_failed);
-      qrCodeEncoder = null;
-    }
-  }
-
-  private void showErrorMessage(int message) {
-    AlertDialog.Builder builder = new AlertDialog.Builder(this);
-    builder.setMessage(message);
-    builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
-    builder.setOnCancelListener(new FinishListener(this));
-    builder.show();
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/Formatter.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/Formatter.java
deleted file mode 100755
index 9e0ae85..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/Formatter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 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.encode;
-
-/**
- * Encapsulates some simple formatting logic, to aid refactoring in {@link ContactEncoder}.
- *
- * @author Sean Owen
- */
-interface Formatter {
-
-  /**
-   * @param value value to format
-   * @param index index of value in a list of values to be formatted
-   * @return formatted value
-   */
-  CharSequence format(CharSequence value, int index);
-  
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/MECARDContactEncoder.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/MECARDContactEncoder.java
deleted file mode 100755
index 4facf77..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/MECARDContactEncoder.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 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.encode;
-
-import java.util.List;
-import java.util.regex.Pattern;
-
-import android.telephony.PhoneNumberUtils;
-
-/**
- * Encodes contact information according to the MECARD format.
- *
- * @author Sean Owen
- */
-final class MECARDContactEncoder extends ContactEncoder {
-
-  private static final char TERMINATOR = ';';
-
-  @Override
-  public String[] encode(List<String> names,
-                         String organization,
-                         List<String> addresses,
-                         List<String> phones,
-                         List<String> phoneTypes,
-                         List<String> emails,
-                         List<String> urls,
-                         String note) {
-    StringBuilder newContents = new StringBuilder(100);
-    newContents.append("MECARD:");
-
-    StringBuilder newDisplayContents = new StringBuilder(100);
-
-    Formatter fieldFormatter = new MECARDFieldFormatter();
-
-    appendUpToUnique(newContents, newDisplayContents, "N", names, 1, new
-                     MECARDNameDisplayFormatter(), fieldFormatter, TERMINATOR);
-
-    append(newContents, newDisplayContents, "ORG", organization, fieldFormatter, TERMINATOR);
-
-    appendUpToUnique(newContents, newDisplayContents, "ADR", addresses, 1, null, fieldFormatter, TERMINATOR);
-
-    appendUpToUnique(newContents, newDisplayContents, "TEL", phones, Integer.MAX_VALUE,
-                     new MECARDTelDisplayFormatter(), fieldFormatter, TERMINATOR);
-
-    appendUpToUnique(newContents, newDisplayContents, "EMAIL", emails, Integer.MAX_VALUE, null,
-                     fieldFormatter, TERMINATOR);
-
-    appendUpToUnique(newContents, newDisplayContents, "URL", urls, Integer.MAX_VALUE, null,
-                     fieldFormatter, TERMINATOR);
-
-    append(newContents, newDisplayContents, "NOTE", note, fieldFormatter, TERMINATOR);
-
-    newContents.append(';');
-
-    return new String[] { newContents.toString(), newDisplayContents.toString() };
-  }
-
-  private static class MECARDFieldFormatter implements Formatter {
-    private static final Pattern RESERVED_MECARD_CHARS = Pattern.compile("([\\\\:;])");
-    private static final Pattern NEWLINE = Pattern.compile("\\n");
-    @Override
-    public CharSequence format(CharSequence value, int index) {
-      return ':' + NEWLINE.matcher(RESERVED_MECARD_CHARS.matcher(value).replaceAll("\\\\$1")).replaceAll("");
-    }
-  }
-
-  private static class MECARDTelDisplayFormatter implements Formatter {
-    private static final Pattern NOT_DIGITS = Pattern.compile("[^0-9]+");
-    @Override
-    public CharSequence format(CharSequence value, int index) {
-      return NOT_DIGITS.matcher(PhoneNumberUtils.formatNumber(value.toString())).replaceAll("");
-    }
-  }
-
-  private static class MECARDNameDisplayFormatter implements Formatter {
-    private static final Pattern COMMA = Pattern.compile(",");
-    @Override
-    public CharSequence format(CharSequence value, int index) {
-      return COMMA.matcher(value).replaceAll("");
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/QRCodeEncoder.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/QRCodeEncoder.java
deleted file mode 100755
index d4d8bd2..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/QRCodeEncoder.java
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * 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.encode;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import com.alibaba.weex.R;
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.EncodeHintType;
-import com.google.zxing.MultiFormatWriter;
-import com.google.zxing.Result;
-import com.google.zxing.WriterException;
-import com.google.zxing.client.android.Contents;
-import com.google.zxing.client.android.Intents;
-import com.google.zxing.client.result.AddressBookParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.ResultParser;
-import com.google.zxing.common.BitMatrix;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class does the work of decoding the user's request and extracting all the data
- * to be encoded in a barcode.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-final class QRCodeEncoder {
-
-  private static final String TAG = QRCodeEncoder.class.getSimpleName();
-
-  private static final int WHITE = 0xFFFFFFFF;
-  private static final int BLACK = 0xFF000000;
-
-  private final Context activity;
-  private String contents;
-  private String displayContents;
-  private String title;
-  private BarcodeFormat format;
-  private final int dimension;
-  private final boolean useVCard;
-
-  QRCodeEncoder(Context activity, Intent intent, int dimension, boolean useVCard) throws WriterException {
-    this.activity = activity;
-    this.dimension = dimension;
-    this.useVCard = useVCard;
-    String action = intent.getAction();
-    if (action.equals(Intents.Encode.ACTION)) {
-      encodeContentsFromZXingIntent(intent);
-    } else if (action.equals(Intent.ACTION_SEND)) {
-      encodeContentsFromShareIntent(intent);
-    }
-  }
-
-  String getContents() {
-    return contents;
-  }
-
-  String getDisplayContents() {
-    return displayContents;
-  }
-
-  String getTitle() {
-    return title;
-  }
-
-  boolean isUseVCard() {
-    return useVCard;
-  }
-
-  // It would be nice if the string encoding lived in the core ZXing library,
-  // but we use platform specific code like PhoneNumberUtils, so it can't.
-  private boolean encodeContentsFromZXingIntent(Intent intent) {
-     // Default to QR_CODE if no format given.
-    String formatString = intent.getStringExtra(Intents.Encode.FORMAT);
-    format = null;
-    if (formatString != null) {
-      try {
-        format = BarcodeFormat.valueOf(formatString);
-      } catch (IllegalArgumentException iae) {
-        // Ignore it then
-      }
-    }
-    if (format == null || format == BarcodeFormat.QR_CODE) {
-      String type = intent.getStringExtra(Intents.Encode.TYPE);
-      if (type == null || type.isEmpty()) {
-        return false;
-      }
-      this.format = BarcodeFormat.QR_CODE;
-      encodeQRCodeContents(intent, type);
-    } else {
-      String data = intent.getStringExtra(Intents.Encode.DATA);
-      if (data != null && !data.isEmpty()) {
-        contents = data;
-        displayContents = data;
-        title = activity.getString(R.string.contents_text);
-      }
-    }
-    return contents != null && !contents.isEmpty();
-  }
-
-  // Handles send intents from multitude of Android applications
-  private void encodeContentsFromShareIntent(Intent intent) throws WriterException {
-    // Check if this is a plain text encoding, or contact
-    if (intent.hasExtra(Intent.EXTRA_STREAM)) {
-      encodeFromStreamExtra(intent);
-    } else {
-      encodeFromTextExtras(intent);
-    }
-  }
-
-  private void encodeFromTextExtras(Intent intent) throws WriterException {
-    // Notice: Google Maps shares both URL and details in one text, bummer!
-    String theContents = ContactEncoder.trim(intent.getStringExtra(Intent.EXTRA_TEXT));
-    if (theContents == null) {
-      theContents = ContactEncoder.trim(intent.getStringExtra("android.intent.extra.HTML_TEXT"));
-      // Intent.EXTRA_HTML_TEXT
-      if (theContents == null) {
-        theContents = ContactEncoder.trim(intent.getStringExtra(Intent.EXTRA_SUBJECT));
-        if (theContents == null) {
-          String[] emails = intent.getStringArrayExtra(Intent.EXTRA_EMAIL);
-          if (emails != null) {
-            theContents = ContactEncoder.trim(emails[0]);
-          } else {
-            theContents = "?";
-          }
-        }
-      }
-    }
-
-    // Trim text to avoid URL breaking.
-    if (theContents == null || theContents.isEmpty()) {
-      throw new WriterException("Empty EXTRA_TEXT");
-    }
-    contents = theContents;
-    // We only do QR code.
-    format = BarcodeFormat.QR_CODE;
-    if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
-      displayContents = intent.getStringExtra(Intent.EXTRA_SUBJECT);
-    } else if (intent.hasExtra(Intent.EXTRA_TITLE)) {
-      displayContents = intent.getStringExtra(Intent.EXTRA_TITLE);
-    } else {
-      displayContents = contents;
-    }
-    title = activity.getString(R.string.contents_text);
-  }
-
-  // Handles send intents from the Contacts app, retrieving a contact as a VCARD.
-  private void encodeFromStreamExtra(Intent intent) throws WriterException {
-    format = BarcodeFormat.QR_CODE;
-    Bundle bundle = intent.getExtras();
-    if (bundle == null) {
-      throw new WriterException("No extras");
-    }
-    Uri uri = bundle.getParcelable(Intent.EXTRA_STREAM);
-    if (uri == null) {
-      throw new WriterException("No EXTRA_STREAM");
-    }
-    byte[] vcard;
-    String vcardString;
-    InputStream stream = null;
-    try {
-      stream = activity.getContentResolver().openInputStream(uri);
-      if (stream == null) {
-        throw new WriterException("Can't open stream for " + uri);
-      }
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      byte[] buffer = new byte[2048];
-      int bytesRead;
-      while ((bytesRead = stream.read(buffer)) > 0) {
-        baos.write(buffer, 0, bytesRead);
-      }
-      vcard = baos.toByteArray();
-      vcardString = new String(vcard, 0, vcard.length, "UTF-8");
-    } catch (IOException ioe) {
-      throw new WriterException(ioe);
-    } finally {
-      if (stream != null) {
-        try {
-          stream.close();
-        } catch (IOException e) {
-          // continue
-        }
-      }
-    }
-    Log.d(TAG, "Encoding share intent content:");
-    Log.d(TAG, vcardString);
-    Result result = new Result(vcardString, vcard, null, BarcodeFormat.QR_CODE);
-    ParsedResult parsedResult = ResultParser.parseResult(result);
-    if (!(parsedResult instanceof AddressBookParsedResult)) {
-      throw new WriterException("Result was not an address");
-    }
-    encodeQRCodeContents((AddressBookParsedResult) parsedResult);
-    if (contents == null || contents.isEmpty()) {
-      throw new WriterException("No content to encode");
-    }
-  }
-
-  private void encodeQRCodeContents(Intent intent, String type) {
-    switch (type) {
-      case Contents.Type.TEXT:
-        String textData = intent.getStringExtra(Intents.Encode.DATA);
-        if (textData != null && !textData.isEmpty()) {
-          contents = textData;
-          displayContents = textData;
-          title = activity.getString(R.string.contents_text);
-        }
-        break;
-
-      case Contents.Type.EMAIL:
-        String emailData = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));
-        if (emailData != null) {
-          contents = "mailto:" + emailData;
-          displayContents = emailData;
-          title = activity.getString(R.string.contents_email);
-        }
-        break;
-
-      case Contents.Type.PHONE:
-        String phoneData = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));
-        if (phoneData != null) {
-          contents = "tel:" + phoneData;
-          displayContents = PhoneNumberUtils.formatNumber(phoneData);
-          title = activity.getString(R.string.contents_phone);
-        }
-        break;
-
-      case Contents.Type.SMS:
-        String smsData = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));
-        if (smsData != null) {
-          contents = "sms:" + smsData;
-          displayContents = PhoneNumberUtils.formatNumber(smsData);
-          title = activity.getString(R.string.contents_sms);
-        }
-        break;
-
-      case Contents.Type.CONTACT:
-        Bundle contactBundle = intent.getBundleExtra(Intents.Encode.DATA);
-        if (contactBundle != null) {
-
-          String name = contactBundle.getString(ContactsContract.Intents.Insert.NAME);
-          String organization = contactBundle.getString(ContactsContract.Intents.Insert.COMPANY);
-          String address = contactBundle.getString(ContactsContract.Intents.Insert.POSTAL);
-          List<String> phones = getAllBundleValues(contactBundle, Contents.PHONE_KEYS);
-          List<String> phoneTypes = getAllBundleValues(contactBundle, Contents.PHONE_TYPE_KEYS);
-          List<String> emails = getAllBundleValues(contactBundle, Contents.EMAIL_KEYS);
-          String url = contactBundle.getString(Contents.URL_KEY);
-          List<String> urls = url == null ? null : Collections.singletonList(url);
-          String note = contactBundle.getString(Contents.NOTE_KEY);
-
-          ContactEncoder encoder = useVCard ? new VCardContactEncoder() : new MECARDContactEncoder();
-          String[] encoded = encoder.encode(Collections.singletonList(name),
-                                            organization,
-                                            Collections.singletonList(address),
-                                            phones,
-                                            phoneTypes,
-                                            emails,
-                                            urls,
-                                            note);
-          // Make sure we've encoded at least one field.
-          if (!encoded[1].isEmpty()) {
-            contents = encoded[0];
-            displayContents = encoded[1];
-            title = activity.getString(R.string.contents_contact);
-          }
-
-        }
-        break;
-
-      case Contents.Type.LOCATION:
-        Bundle locationBundle = intent.getBundleExtra(Intents.Encode.DATA);
-        if (locationBundle != null) {
-          // These must use Bundle.getFloat(), not getDouble(), it's part of the API.
-          float latitude = locationBundle.getFloat("LAT", Float.MAX_VALUE);
-          float longitude = locationBundle.getFloat("LONG", Float.MAX_VALUE);
-          if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {
-            contents = "geo:" + latitude + ',' + longitude;
-            displayContents = latitude + "," + longitude;
-            title = activity.getString(R.string.contents_location);
-          }
-        }
-        break;
-    }
-  }
-
-  private static List<String> getAllBundleValues(Bundle bundle, String[] keys) {
-    List<String> values = new ArrayList<>(keys.length);
-    for (String key : keys) {
-      Object value = bundle.get(key);
-      values.add(value == null ? null : value.toString());
-    }
-    return values;
-  }
-
-  private void encodeQRCodeContents(AddressBookParsedResult contact) {
-    ContactEncoder encoder = useVCard ? new VCardContactEncoder() : new MECARDContactEncoder();
-    String[] encoded = encoder.encode(toList(contact.getNames()),
-                                      contact.getOrg(),
-                                      toList(contact.getAddresses()),
-                                      toList(contact.getPhoneNumbers()),
-                                      null,
-                                      toList(contact.getEmails()),
-                                      toList(contact.getURLs()),
-                                      null);
-    // Make sure we've encoded at least one field.
-    if (!encoded[1].isEmpty()) {
-      contents = encoded[0];
-      displayContents = encoded[1];
-      title = activity.getString(R.string.contents_contact);
-    }
-  }
-
-  private static List<String> toList(String[] values) {
-    return values == null ? null : Arrays.asList(values);
-  }
-
-  Bitmap encodeAsBitmap() throws WriterException {
-    String contentsToEncode = contents;
-    if (contentsToEncode == null) {
-      return null;
-    }
-    Map<EncodeHintType,Object> hints = null;
-    String encoding = guessAppropriateEncoding(contentsToEncode);
-    if (encoding != null) {
-      hints = new EnumMap<>(EncodeHintType.class);
-      hints.put(EncodeHintType.CHARACTER_SET, encoding);
-    }
-    BitMatrix result;
-    try {
-      result = new MultiFormatWriter().encode(contentsToEncode, format, dimension, dimension, hints);
-    } catch (IllegalArgumentException iae) {
-      // Unsupported format
-      return null;
-    }
-    int width = result.getWidth();
-    int height = result.getHeight();
-    int[] pixels = new int[width * height];
-    for (int y = 0; y < height; y++) {
-      int offset = y * width;
-      for (int x = 0; x < width; x++) {
-        pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
-      }
-    }
-
-    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
-    return bitmap;
-  }
-
-  private static String guessAppropriateEncoding(CharSequence contents) {
-    // Very crude at the moment
-    for (int i = 0; i < contents.length(); i++) {
-      if (contents.charAt(i) > 0xFF) {
-        return "UTF-8";
-      }
-    }
-    return null;
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardContactEncoder.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardContactEncoder.java
deleted file mode 100755
index 00bd9e2..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardContactEncoder.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 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.encode;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import android.provider.ContactsContract;
-
-/**
- * Encodes contact information according to the vCard format.
- *
- * @author Sean Owen
- */
-final class VCardContactEncoder extends ContactEncoder {
-
-  private static final char TERMINATOR = '\n';
-
-  @Override
-  public String[] encode(List<String> names,
-                         String organization,
-                         List<String> addresses,
-                         List<String> phones,
-                         List<String> phoneTypes,
-                         List<String> emails,
-                         List<String> urls,
-                         String note) {
-    StringBuilder newContents = new StringBuilder(100);
-    newContents.append("BEGIN:VCARD").append(TERMINATOR);
-    newContents.append("VERSION:3.0").append(TERMINATOR);
-
-    StringBuilder newDisplayContents = new StringBuilder(100);
-
-    Formatter fieldFormatter = new VCardFieldFormatter();
-
-    appendUpToUnique(newContents, newDisplayContents, "N", names, 1, null, fieldFormatter, TERMINATOR);
-
-    append(newContents, newDisplayContents, "ORG", organization, fieldFormatter, TERMINATOR);
-
-    appendUpToUnique(newContents, newDisplayContents, "ADR", addresses, 1, null, fieldFormatter, TERMINATOR);
-
-    List<Map<String,Set<String>>> phoneMetadata = buildPhoneMetadata(phones, phoneTypes);
-    appendUpToUnique(newContents, newDisplayContents, "TEL", phones, Integer.MAX_VALUE,
-                     new VCardTelDisplayFormatter(phoneMetadata),
-                     new VCardFieldFormatter(phoneMetadata), TERMINATOR);
-
-    appendUpToUnique(newContents, newDisplayContents, "EMAIL", emails, Integer.MAX_VALUE, null,
-                     fieldFormatter, TERMINATOR);
-
-    appendUpToUnique(newContents, newDisplayContents, "URL", urls, Integer.MAX_VALUE, null,
-                     fieldFormatter, TERMINATOR);
-
-    append(newContents, newDisplayContents, "NOTE", note, fieldFormatter, TERMINATOR);
-
-    newContents.append("END:VCARD").append(TERMINATOR);
-
-    return new String[] { newContents.toString(), newDisplayContents.toString() };
-  }
-
-  static List<Map<String,Set<String>>> buildPhoneMetadata(Collection<String> phones, List<String> phoneTypes) {
-    if (phoneTypes == null || phoneTypes.isEmpty()) {
-      return null;
-    }
-    List<Map<String,Set<String>>> metadataForIndex = new ArrayList<>();
-    for (int i = 0; i < phones.size(); i++) {
-      if (phoneTypes.size() <= i) {
-        metadataForIndex.add(null);
-      } else {
-        Map<String,Set<String>> metadata = new HashMap<>();
-        metadataForIndex.add(metadata);
-        Set<String> typeTokens = new HashSet<>();
-        metadata.put("TYPE", typeTokens);
-        String typeString = phoneTypes.get(i);
-        Integer androidType = maybeIntValue(typeString);
-        if (androidType == null) {
-          typeTokens.add(typeString);
-        } else {
-          String purpose = vCardPurposeLabelForAndroidType(androidType);
-          String context = vCardContextLabelForAndroidType(androidType);
-          if (purpose != null) {
-            typeTokens.add(purpose);
-          }
-          if (context != null) {
-            typeTokens.add(context);
-          }
-        }
-      }
-    }
-    return metadataForIndex;
-  }
-
-  private static Integer maybeIntValue(String value) {
-    try {
-      return Integer.valueOf(value);
-    } catch (NumberFormatException nfe) {
-      return null;
-    }
-  }
-
-  private static String vCardPurposeLabelForAndroidType(int androidType) {
-    switch (androidType) {
-      case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_OTHER_FAX:
-        return "fax";
-      case ContactsContract.CommonDataKinds.Phone.TYPE_PAGER:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_PAGER:
-        return "pager";
-      case ContactsContract.CommonDataKinds.Phone.TYPE_TTY_TDD:
-        return "textphone";
-      case ContactsContract.CommonDataKinds.Phone.TYPE_MMS:
-        return "text";
-      default:
-        return null;
-    }
-  }
-
-  private static String vCardContextLabelForAndroidType(int androidType) {
-    switch (androidType) {
-      case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_PAGER:
-        return "home";
-      case ContactsContract.CommonDataKinds.Phone.TYPE_COMPANY_MAIN:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK:
-      case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_PAGER:
-        return "work";
-      default:
-        return null;
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardFieldFormatter.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardFieldFormatter.java
deleted file mode 100755
index 070a4cd..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardFieldFormatter.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2014 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.encode;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-/**
- * @author Sean Owen
- */
-final class VCardFieldFormatter implements Formatter {
-
-  private static final Pattern RESERVED_VCARD_CHARS = Pattern.compile("([\\\\,;])");
-  private static final Pattern NEWLINE = Pattern.compile("\\n");
-
-  private final List<Map<String,Set<String>>> metadataForIndex;
-
-  VCardFieldFormatter() {
-    this(null);
-  }
-
-  VCardFieldFormatter(List<Map<String,Set<String>>> metadataForIndex) {
-    this.metadataForIndex = metadataForIndex;
-  }
-
-  @Override
-  public CharSequence format(CharSequence value, int index) {
-    value = RESERVED_VCARD_CHARS.matcher(value).replaceAll("\\\\$1");
-    value = NEWLINE.matcher(value).replaceAll("");
-    Map<String,Set<String>> metadata =
-        metadataForIndex == null || metadataForIndex.size() <= index ? null : metadataForIndex.get(index);
-    value = formatMetadata(value, metadata);
-    return value;
-  }
-
-  private static CharSequence formatMetadata(CharSequence value, Map<String,Set<String>> metadata) {
-    StringBuilder withMetadata = new StringBuilder();
-    if (metadata != null) {
-      for (Map.Entry<String,Set<String>> metadatum : metadata.entrySet()) {
-        Set<String> values = metadatum.getValue();
-        if (values == null || values.isEmpty()) {
-          continue;
-        }
-        withMetadata.append(';').append(metadatum.getKey()).append('=');
-        if (values.size() > 1) {
-          withMetadata.append('"');
-        }
-        Iterator<String> valuesIt = values.iterator();
-        withMetadata.append(valuesIt.next());
-        while (valuesIt.hasNext()) {
-          withMetadata.append(',').append(valuesIt.next());
-        }
-        if (values.size() > 1) {
-          withMetadata.append('"');
-        }
-      }
-    }
-    withMetadata.append(':').append(value);
-    return withMetadata;
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardTelDisplayFormatter.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardTelDisplayFormatter.java
deleted file mode 100755
index 21d2e7f..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/encode/VCardTelDisplayFormatter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2014 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.encode;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import android.telephony.PhoneNumberUtils;
-
-/**
- * @author Sean Owen
- */
-final class VCardTelDisplayFormatter implements Formatter {
-
-  private final List<Map<String,Set<String>>> metadataForIndex;
-
-  VCardTelDisplayFormatter() {
-    this(null);
-  }
-
-  VCardTelDisplayFormatter(List<Map<String,Set<String>>> metadataForIndex) {
-    this.metadataForIndex = metadataForIndex;
-  }
-
-  @Override
-  public CharSequence format(CharSequence value, int index) {
-    value = PhoneNumberUtils.formatNumber(value.toString());
-    Map<String,Set<String>> metadata =
-        metadataForIndex == null || metadataForIndex.size() <= index ? null : metadataForIndex.get(index);
-    value = formatMetadata(value, metadata);
-    return value;
-  }
-
-  private static CharSequence formatMetadata(CharSequence value, Map<String,Set<String>> metadata) {
-    if (metadata == null || metadata.isEmpty()) {
-      return value;
-    }
-    StringBuilder withMetadata = new StringBuilder();
-    for (Map.Entry<String,Set<String>> metadatum : metadata.entrySet()) {
-      Set<String> values = metadatum.getValue();
-      if (values == null || values.isEmpty()) {
-        continue;
-      }
-      Iterator<String> valuesIt = values.iterator();
-      withMetadata.append(valuesIt.next());
-      while (valuesIt.hasNext()) {
-        withMetadata.append(',').append(valuesIt.next());
-      }
-    }
-    if (withMetadata.length() > 0) {
-      withMetadata.append(' ');
-    }
-    withMetadata.append(value);
-    return withMetadata;
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/AddressBookResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/AddressBookResultHandler.java
deleted file mode 100755
index 70d48a2..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/AddressBookResultHandler.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-import android.telephony.PhoneNumberUtils;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.style.StyleSpan;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.result.AddressBookParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * Handles address book entries.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class AddressBookResultHandler extends ResultHandler {
-
-  private static final DateFormat[] DATE_FORMATS = {
-    new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH),
-    new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH),
-    new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH),
-    new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH),
-  };
-  static {
-    for (DateFormat format : DATE_FORMATS) {
-      format.setLenient(false);
-    }
-  }
-
-  private static final int[] BUTTON_TEXTS = {
-    R.string.button_add_contact,
-    R.string.button_show_map,
-    R.string.button_dial,
-    R.string.button_email,
-  };
-
-  private final boolean[] fields;
-  private int buttonCount;
-
-  // This takes all the work out of figuring out which buttons/actions should be in which
-  // positions, based on which fields are present in this barcode.
-  private int mapIndexToAction(int index) {
-    if (index < buttonCount) {
-      int count = -1;
-      for (int x = 0; x < MAX_BUTTON_COUNT; x++) {
-        if (fields[x]) {
-          count++;
-        }
-        if (count == index) {
-          return x;
-        }
-      }
-    }
-    return -1;
-  }
-
-  public AddressBookResultHandler(Activity activity, ParsedResult result) {
-    super(activity, result);
-    AddressBookParsedResult addressResult = (AddressBookParsedResult) result;
-    String[] addresses = addressResult.getAddresses();
-    boolean hasAddress = addresses != null && addresses.length > 0 && addresses[0] != null && !addresses[0].isEmpty();
-    String[] phoneNumbers = addressResult.getPhoneNumbers();
-    boolean hasPhoneNumber = phoneNumbers != null && phoneNumbers.length > 0;
-    String[] emails = addressResult.getEmails();
-    boolean hasEmailAddress = emails != null && emails.length > 0;
-
-    fields = new boolean[MAX_BUTTON_COUNT];
-    fields[0] = true; // Add contact is always available
-    fields[1] = hasAddress;
-    fields[2] = hasPhoneNumber;
-    fields[3] = hasEmailAddress;
-
-    buttonCount = 0;
-    for (int x = 0; x < MAX_BUTTON_COUNT; x++) {
-      if (fields[x]) {
-        buttonCount++;
-      }
-    }
-  }
-
-  @Override
-  public int getButtonCount() {
-    return buttonCount;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return BUTTON_TEXTS[mapIndexToAction(index)];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    AddressBookParsedResult addressResult = (AddressBookParsedResult) getResult();
-    String[] addresses = addressResult.getAddresses();
-    String address1 = addresses == null || addresses.length < 1 ? null : addresses[0];
-    String[] addressTypes = addressResult.getAddressTypes();
-    String address1Type = addressTypes == null || addressTypes.length < 1 ? null : addressTypes[0];
-    int action = mapIndexToAction(index);
-    switch (action) {
-      case 0:
-        addContact(addressResult.getNames(),
-                   addressResult.getNicknames(),
-                   addressResult.getPronunciation(),
-                   addressResult.getPhoneNumbers(),
-                   addressResult.getPhoneTypes(),
-                   addressResult.getEmails(),
-                   addressResult.getEmailTypes(),
-                   addressResult.getNote(),
-                   addressResult.getInstantMessenger(),
-                   address1,
-                   address1Type,
-                   addressResult.getOrg(),
-                   addressResult.getTitle(),
-                   addressResult.getURLs(),
-                   addressResult.getBirthday(),
-                   addressResult.getGeo());
-        break;
-      case 1:
-        searchMap(address1);
-        break;
-      case 2:
-        dialPhone(addressResult.getPhoneNumbers()[0]);
-        break;
-      case 3:
-        sendEmail(addressResult.getEmails(), null, null, null, null);
-        break;
-      default:
-        break;
-    }
-  }
-
-  private static Date parseDate(String s) {
-    for (DateFormat currentFormat : DATE_FORMATS) {
-      try {
-        return currentFormat.parse(s);
-      } catch (ParseException e) {
-        // continue
-      }
-    }
-    return null;
-  }
-
-  // Overriden so we can hyphenate phone numbers, format birthdays, and bold the name.
-  @Override
-  public CharSequence getDisplayContents() {
-    AddressBookParsedResult result = (AddressBookParsedResult) getResult();
-    StringBuilder contents = new StringBuilder(100);
-    ParsedResult.maybeAppend(result.getNames(), contents);
-    int namesLength = contents.length();
-
-    String pronunciation = result.getPronunciation();
-    if (pronunciation != null && !pronunciation.isEmpty()) {
-      contents.append("\n(");
-      contents.append(pronunciation);
-      contents.append(')');
-    }
-
-    ParsedResult.maybeAppend(result.getTitle(), contents);
-    ParsedResult.maybeAppend(result.getOrg(), contents);
-    ParsedResult.maybeAppend(result.getAddresses(), contents);
-    String[] numbers = result.getPhoneNumbers();
-    if (numbers != null) {
-      for (String number : numbers) {
-        if (number != null) {
-          ParsedResult.maybeAppend(PhoneNumberUtils.formatNumber(number), contents);
-        }
-      }
-    }
-    ParsedResult.maybeAppend(result.getEmails(), contents);
-    ParsedResult.maybeAppend(result.getURLs(), contents);
-
-    String birthday = result.getBirthday();
-    if (birthday != null && !birthday.isEmpty()) {
-      Date date = parseDate(birthday);
-      if (date != null) {
-        ParsedResult.maybeAppend(DateFormat.getDateInstance(DateFormat.MEDIUM).format(date.getTime()), contents);
-      }
-    }
-    ParsedResult.maybeAppend(result.getNote(), contents);
-
-    if (namesLength > 0) {
-      // Bold the full name to make it stand out a bit.
-      Spannable styled = new SpannableString(contents.toString());
-      styled.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, namesLength, 0);
-      return styled;
-    } else {
-      return contents.toString();
-    }
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_address_book;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/CalendarResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/CalendarResultHandler.java
deleted file mode 100755
index 29d9520..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/CalendarResultHandler.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
-import android.util.Log;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.result.CalendarParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-
-import java.text.DateFormat;
-import java.util.Date;
-
-/**
- * Handles calendar entries encoded in QR Codes.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- * @author Sean Owen
- */
-public final class CalendarResultHandler extends ResultHandler {
-
-  private static final String TAG = CalendarResultHandler.class.getSimpleName();
-
-  private static final int[] buttons = {
-      R.string.button_add_calendar
-  };
-
-  public CalendarResultHandler(Activity activity, ParsedResult result) {
-    super(activity, result);
-  }
-
-  @Override
-  public int getButtonCount() {
-    return buttons.length;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    if (index == 0) {
-      CalendarParsedResult calendarResult = (CalendarParsedResult) getResult();
-
-      String description = calendarResult.getDescription();
-      String organizer = calendarResult.getOrganizer();
-      if (organizer != null) { // No separate Intent key, put in description
-        if (description == null) {
-          description = organizer;
-        } else {
-          description = description + '\n' + organizer;
-        }
-      }
-
-      addCalendarEvent(calendarResult.getSummary(),
-                       calendarResult.getStart(),
-                       calendarResult.isStartAllDay(),
-                       calendarResult.getEnd(),
-                       calendarResult.getLocation(),
-                       description,
-                       calendarResult.getAttendees());
-    }
-  }
-
-  /**
-   * Sends an intent to create a new calendar event by prepopulating the Add Event UI. Older
-   * versions of the system have a bug where the event title will not be filled out.
-   *
-   * @param summary A description of the event
-   * @param start   The start time
-   * @param allDay  if true, event is considered to be all day starting from start time
-   * @param end     The end time (optional)
-   * @param location a text description of the event location
-   * @param description a text description of the event itself
-   * @param attendees attendees to invite
-   */
-  private void addCalendarEvent(String summary,
-                                Date start,
-                                boolean allDay,
-                                Date end,
-                                String location,
-                                String description,
-                                String[] attendees) {
-    Intent intent = new Intent(Intent.ACTION_INSERT);
-    intent.setType("vnd.android.cursor.item/event");
-    long startMilliseconds = start.getTime();
-    intent.putExtra("beginTime", startMilliseconds);
-    if (allDay) {
-      intent.putExtra("allDay", true);
-    }
-    long endMilliseconds;
-    if (end == null) {
-      if (allDay) {
-        // + 1 day
-        endMilliseconds = startMilliseconds + 24 * 60 * 60 * 1000;
-      } else {
-        endMilliseconds = startMilliseconds;
-      }
-    } else {
-      endMilliseconds = end.getTime();
-    }
-    intent.putExtra("endTime", endMilliseconds);
-    intent.putExtra("title", summary);
-    intent.putExtra("eventLocation", location);
-    intent.putExtra("description", description);
-    if (attendees != null) {
-      intent.putExtra(Intent.EXTRA_EMAIL, attendees);
-      // Documentation says this is either a String[] or comma-separated String, which is right?
-    }
-
-    try {
-      // Do this manually at first
-      rawLaunchIntent(intent);
-    } catch (ActivityNotFoundException anfe) {
-      Log.w(TAG, "No calendar app available that responds to " + Intent.ACTION_INSERT);
-      // For calendar apps that don't like "INSERT":
-      intent.setAction(Intent.ACTION_EDIT);
-      launchIntent(intent); // Fail here for real if nothing can handle it
-    }
-  }
-
-
-  @Override
-  public CharSequence getDisplayContents() {
-
-    CalendarParsedResult calResult = (CalendarParsedResult) getResult();
-    StringBuilder result = new StringBuilder(100);
-
-    ParsedResult.maybeAppend(calResult.getSummary(), result);
-
-    Date start = calResult.getStart();
-    ParsedResult.maybeAppend(format(calResult.isStartAllDay(), start), result);
-
-    Date end = calResult.getEnd();
-    if (end != null) {
-      if (calResult.isEndAllDay() && !start.equals(end)) {
-        // Show only year/month/day
-        // if it's all-day and this is the end date, it's exclusive, so show the user
-        // that it ends on the day before to make more intuitive sense.
-        // But don't do it if the event already (incorrectly?) specifies the same start/end
-        end = new Date(end.getTime() - 24 * 60 * 60 * 1000);
-      }
-      ParsedResult.maybeAppend(format(calResult.isEndAllDay(), end), result);
-    }
-
-    ParsedResult.maybeAppend(calResult.getLocation(), result);
-    ParsedResult.maybeAppend(calResult.getOrganizer(), result);
-    ParsedResult.maybeAppend(calResult.getAttendees(), result);
-    ParsedResult.maybeAppend(calResult.getDescription(), result);
-    return result.toString();
-  }
-
-  private static String format(boolean allDay, Date date) {
-    if (date == null) {
-      return null;
-    }
-    DateFormat format = allDay
-        ? DateFormat.getDateInstance(DateFormat.MEDIUM)
-        : DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
-    return format.format(date);
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_calendar;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/EmailAddressResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/EmailAddressResultHandler.java
deleted file mode 100755
index d05db00..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/EmailAddressResultHandler.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.result.EmailAddressParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-
-/**
- * Handles email addresses.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class EmailAddressResultHandler extends ResultHandler {
-  private static final int[] buttons = {
-      R.string.button_email,
-      R.string.button_add_contact
-  };
-
-  public EmailAddressResultHandler(Activity activity, ParsedResult result) {
-    super(activity, result);
-  }
-
-  @Override
-  public int getButtonCount() {
-    return buttons.length;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    EmailAddressParsedResult emailResult = (EmailAddressParsedResult) getResult();
-    switch (index) {
-      case 0:
-        sendEmail(emailResult.getTos(),
-                  emailResult.getCCs(),
-                  emailResult.getBCCs(),
-                  emailResult.getSubject(),
-                  emailResult.getBody());
-        break;
-      case 1:
-        addEmailOnlyContact(emailResult.getTos(), null);
-        break;
-    }
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_email_address;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/GeoResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/GeoResultHandler.java
deleted file mode 100755
index 1fed4e5..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/GeoResultHandler.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.result.GeoParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-
-/**
- * Handles geographic coordinates (typically encoded as geo: URLs).
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class GeoResultHandler extends ResultHandler {
-  private static final int[] buttons = {
-      R.string.button_show_map,
-      R.string.button_get_directions
-  };
-
-  public GeoResultHandler(Activity activity, ParsedResult result) {
-    super(activity, result);
-  }
-
-  @Override
-  public int getButtonCount() {
-    return buttons.length;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    GeoParsedResult geoResult = (GeoParsedResult) getResult();
-    switch (index) {
-      case 0:
-        openMap(geoResult.getGeoURI());
-        break;
-      case 1:
-        getDirections(geoResult.getLatitude(), geoResult.getLongitude());
-        break;
-    }
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_geo;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ISBNResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ISBNResultHandler.java
deleted file mode 100755
index dbe2f1b..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ISBNResultHandler.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-
-import com.alibaba.weex.R;
-import com.google.zxing.Result;
-import com.google.zxing.client.result.ISBNParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-
-/**
- * Handles books encoded by their ISBN values.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class ISBNResultHandler extends ResultHandler {
-  private static final int[] buttons = {
-      R.string.button_product_search,
-      R.string.button_book_search,
-      R.string.button_search_book_contents,
-      R.string.button_custom_product_search
-  };
-
-  public ISBNResultHandler(Activity activity, ParsedResult result, Result rawResult) {
-    super(activity, result, rawResult);
-  }
-
-  @Override
-  public int getButtonCount() {
-    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();
-    switch (index) {
-      case 0:
-        openProductSearch(isbnResult.getISBN());
-        break;
-      case 1:
-        openBookSearch(isbnResult.getISBN());
-        break;
-      case 2:
-        searchBookContents(isbnResult.getISBN());
-        break;
-      case 3:
-        openURL(fillInCustomSearchURL(isbnResult.getISBN()));
-        break;
-    }
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_isbn;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ProductResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ProductResultHandler.java
deleted file mode 100755
index c8e5159..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ProductResultHandler.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-
-import com.alibaba.weex.R;
-import com.google.zxing.Result;
-import com.google.zxing.client.result.ExpandedProductParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.ProductParsedResult;
-
-/**
- * Handles generic products which are not books.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class ProductResultHandler extends ResultHandler {
-  private static final int[] buttons = {
-      R.string.button_product_search,
-      R.string.button_web_search,
-      R.string.button_custom_product_search
-  };
-
-  public ProductResultHandler(Activity activity, ParsedResult result, Result rawResult) {
-    super(activity, result, rawResult);
-  }
-
-  @Override
-  public int getButtonCount() {
-    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    String productID = getProductIDFromResult(getResult());
-    switch (index) {
-      case 0:
-        openProductSearch(productID);
-        break;
-      case 1:
-        webSearch(productID);
-        break;
-      case 2:
-        openURL(fillInCustomSearchURL(productID));
-        break;
-    }
-  }
-
-  private static String getProductIDFromResult(ParsedResult rawResult) {
-    if (rawResult instanceof ProductParsedResult) {
-      return ((ProductParsedResult) rawResult).getNormalizedProductID();
-    }
-    if (rawResult instanceof ExpandedProductParsedResult) {
-      return ((ExpandedProductParsedResult) rawResult).getRawText();
-    }
-    throw new IllegalArgumentException(rawResult.getClass().toString());
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_product;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultButtonListener.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultButtonListener.java
deleted file mode 100755
index 2e107c4..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultButtonListener.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.result;
-
-import android.view.View;
-
-/**
- * Handles the result of barcode decoding in the context of the Android platform, by dispatching the
- * proper intents to open other activities like GMail, Maps, etc.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class ResultButtonListener implements View.OnClickListener {
-  private final ResultHandler resultHandler;
-  private final int index;
-
-  public ResultButtonListener(ResultHandler resultHandler, int index) {
-    this.resultHandler = resultHandler;
-    this.index = index;
-  }
-
-  @Override
-  public void onClick(View view) {
-    resultHandler.handleButtonPress(index);
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultHandler.java
deleted file mode 100755
index 92187e8..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultHandler.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.preference.PreferenceManager;
-import android.provider.ContactsContract;
-import android.util.Log;
-
-import com.alibaba.weex.R;
-import com.google.zxing.Result;
-import com.google.zxing.client.android.Contents;
-import com.google.zxing.client.android.Intents;
-import com.google.zxing.client.android.LocaleManager;
-import com.google.zxing.client.android.PreferencesActivity;
-import com.google.zxing.client.android.book.SearchBookContentsActivity;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.ParsedResultType;
-import com.google.zxing.client.result.ResultParser;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Locale;
-
-/**
- * A base class for the Android-specific barcode handlers. These allow the app to polymorphically
- * suggest the appropriate actions for each data type.
- *
- * This class also contains a bunch of utility methods to take common actions like opening a URL.
- * They could easily be moved into a helper object, but it can't be static because the Activity
- * instance is needed to launch an intent.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- * @author Sean Owen
- */
-public abstract class ResultHandler {
-
-  private static final String TAG = ResultHandler.class.getSimpleName();
-
-  private static final String[] EMAIL_TYPE_STRINGS = {"home", "work", "mobile"};
-  private static final String[] PHONE_TYPE_STRINGS = {"home", "work", "mobile", "fax", "pager", "main"};
-  private static final String[] ADDRESS_TYPE_STRINGS = {"home", "work"};
-  private static final int[] EMAIL_TYPE_VALUES = {
-      ContactsContract.CommonDataKinds.Email.TYPE_HOME,
-      ContactsContract.CommonDataKinds.Email.TYPE_WORK,
-      ContactsContract.CommonDataKinds.Email.TYPE_MOBILE,
-  };
-  private static final int[] PHONE_TYPE_VALUES = {
-      ContactsContract.CommonDataKinds.Phone.TYPE_HOME,
-      ContactsContract.CommonDataKinds.Phone.TYPE_WORK,
-      ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE,
-      ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK,
-      ContactsContract.CommonDataKinds.Phone.TYPE_PAGER,
-      ContactsContract.CommonDataKinds.Phone.TYPE_MAIN,
-  };
-  private static final int[] ADDRESS_TYPE_VALUES = {
-      ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME,
-      ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK,
-  };
-  private static final int NO_TYPE = -1;
-
-  public static final int MAX_BUTTON_COUNT = 4;
-
-  private final ParsedResult result;
-  private final Activity activity;
-  private final Result rawResult;
-  private final String customProductSearch;
-
-  ResultHandler(Activity activity, ParsedResult result) {
-    this(activity, result, null);
-  }
-
-  ResultHandler(Activity activity, ParsedResult result, Result rawResult) {
-    this.result = result;
-    this.activity = activity;
-    this.rawResult = rawResult;
-    this.customProductSearch = parseCustomSearchURL();
-  }
-
-  public final ParsedResult getResult() {
-    return result;
-  }
-
-  final boolean hasCustomProductSearch() {
-    return customProductSearch != null;
-  }
-
-  final Activity getActivity() {
-    return activity;
-  }
-
-  /**
-   * Indicates how many buttons the derived class wants shown.
-   *
-   * @return The integer button count.
-   */
-  public abstract int getButtonCount();
-
-  /**
-   * The text of the nth action button.
-   *
-   * @param index From 0 to getButtonCount() - 1
-   * @return The button text as a resource ID
-   */
-  public abstract int getButtonText(int index);
-
-  public Integer getDefaultButtonID() {
-    return null;
-  }
-
-  /**
-   * Execute the action which corresponds to the nth button.
-   *
-   * @param index The button that was clicked.
-   */
-  public abstract void handleButtonPress(int index);
-
-  /**
-   * Some barcode contents are considered secure, and should not be saved to history, copied to
-   * the clipboard, or otherwise persisted.
-   *
-   * @return If true, do not create any permanent record of these contents.
-   */
-  public boolean areContentsSecure() {
-    return false;
-  }
-
-  /**
-   * Create a possibly styled string for the contents of the current barcode.
-   *
-   * @return The text to be displayed.
-   */
-  public CharSequence getDisplayContents() {
-    String contents = result.getDisplayResult();
-    return contents.replace("\r", "");
-  }
-
-  /**
-   * A string describing the kind of barcode that was found, e.g. "Found contact info".
-   *
-   * @return The resource ID of the string.
-   */
-  public abstract int getDisplayTitle();
-
-  /**
-   * A convenience method to get the parsed type. Should not be overridden.
-   *
-   * @return The parsed type, e.g. URI or ISBN
-   */
-  public final ParsedResultType getType() {
-    return result.getType();
-  }
-
-  final void addPhoneOnlyContact(String[] phoneNumbers,String[] phoneTypes) {
-    addContact(null, null, null, phoneNumbers, phoneTypes, null, null, null, null, null, null, null, null, null, null, null);
-  }
-
-  final void addEmailOnlyContact(String[] emails, String[] emailTypes) {
-    addContact(null, null, null, null, null, emails, emailTypes, null, null, null, null, null, null, null, null, null);
-  }
-
-  final void addContact(String[] names,
-                        String[] nicknames,
-                        String pronunciation,
-                        String[] phoneNumbers,
-                        String[] phoneTypes,
-                        String[] emails,
-                        String[] emailTypes,
-                        String note,
-                        String instantMessenger,
-                        String address,
-                        String addressType,
-                        String org,
-                        String title,
-                        String[] urls,
-                        String birthday,
-                        String[] geo) {
-
-    // Only use the first name in the array, if present.
-    Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT, ContactsContract.Contacts.CONTENT_URI);
-    intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
-    putExtra(intent, ContactsContract.Intents.Insert.NAME, names != null ? names[0] : null);
-
-    putExtra(intent, ContactsContract.Intents.Insert.PHONETIC_NAME, pronunciation);
-
-    int phoneCount = Math.min(phoneNumbers != null ? phoneNumbers.length : 0, Contents.PHONE_KEYS.length);
-    for (int x = 0; x < phoneCount; x++) {
-      putExtra(intent, Contents.PHONE_KEYS[x], phoneNumbers[x]);
-      if (phoneTypes != null && x < phoneTypes.length) {
-        int type = toPhoneContractType(phoneTypes[x]);
-        if (type >= 0) {
-          intent.putExtra(Contents.PHONE_TYPE_KEYS[x], type);
-        }
-      }
-    }
-
-    int emailCount = Math.min(emails != null ? emails.length : 0, Contents.EMAIL_KEYS.length);
-    for (int x = 0; x < emailCount; x++) {
-      putExtra(intent, Contents.EMAIL_KEYS[x], emails[x]);
-      if (emailTypes != null && x < emailTypes.length) {
-        int type = toEmailContractType(emailTypes[x]);
-        if (type >= 0) {
-          intent.putExtra(Contents.EMAIL_TYPE_KEYS[x], type);
-        }
-      }
-    }
-
-    ArrayList<ContentValues> data = new ArrayList<>();
-    if (urls != null) {
-      for (String url : urls) {
-        if (url != null && !url.isEmpty()) {
-          ContentValues row = new ContentValues(2);
-          row.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE);
-          row.put(ContactsContract.CommonDataKinds.Website.URL, url);
-          data.add(row);
-          break;
-        }
-      }
-    }
-
-    if (birthday != null) {
-      ContentValues row = new ContentValues(3);
-      row.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE);
-      row.put(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY);
-      row.put(ContactsContract.CommonDataKinds.Event.START_DATE, birthday);
-      data.add(row);
-    }
-
-    if (nicknames != null) {
-      for (String nickname : nicknames) {
-        if (nickname != null && !nickname.isEmpty()) {
-          ContentValues row = new ContentValues(3);
-          row.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE);
-          row.put(ContactsContract.CommonDataKinds.Nickname.TYPE,
-                  ContactsContract.CommonDataKinds.Nickname.TYPE_DEFAULT);
-          row.put(ContactsContract.CommonDataKinds.Nickname.NAME, nickname);
-          data.add(row);
-          break;
-        }
-      }
-    }
-
-    if (!data.isEmpty()) {
-      intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, data);
-    }
-
-    StringBuilder aggregatedNotes = new StringBuilder();
-    if (note != null) {
-      aggregatedNotes.append('\n').append(note);
-    }
-    if (geo != null) {
-      aggregatedNotes.append('\n').append(geo[0]).append(',').append(geo[1]);
-    }
-
-    if (aggregatedNotes.length() > 0) {
-      // Remove extra leading '\n'
-      putExtra(intent, ContactsContract.Intents.Insert.NOTES, aggregatedNotes.substring(1));
-    }
-    
-    putExtra(intent, ContactsContract.Intents.Insert.IM_HANDLE, instantMessenger);
-    putExtra(intent, ContactsContract.Intents.Insert.POSTAL, address);
-    if (addressType != null) {
-      int type = toAddressContractType(addressType);
-      if (type >= 0) {
-        intent.putExtra(ContactsContract.Intents.Insert.POSTAL_TYPE, type);
-      }
-    }
-    putExtra(intent, ContactsContract.Intents.Insert.COMPANY, org);
-    putExtra(intent, ContactsContract.Intents.Insert.JOB_TITLE, title);
-    launchIntent(intent);
-  }
-
-  private static int toEmailContractType(String typeString) {
-    return doToContractType(typeString, EMAIL_TYPE_STRINGS, EMAIL_TYPE_VALUES);
-  }
-
-  private static int toPhoneContractType(String typeString) {
-    return doToContractType(typeString, PHONE_TYPE_STRINGS, PHONE_TYPE_VALUES);
-  }
-
-  private static int toAddressContractType(String typeString) {
-    return doToContractType(typeString, ADDRESS_TYPE_STRINGS, ADDRESS_TYPE_VALUES);
-  }
-
-  private static int doToContractType(String typeString, String[] types, int[] values) {
-    if (typeString == null) {
-      return NO_TYPE;
-    }
-    for (int i = 0; i < types.length; i++) {
-      String type = types[i];
-      if (typeString.startsWith(type) || typeString.startsWith(type.toUpperCase(Locale.ENGLISH))) {
-        return values[i];
-      }
-    }
-    return NO_TYPE;
-  }
-
-  final void shareByEmail(String contents) {
-    sendEmail(null, null, null, null, contents);
-  }
-
-  final void sendEmail(String[] to,
-                       String[] cc,
-                       String[] bcc,
-                       String subject,
-                       String body) {
-    Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
-    if (to != null && to.length != 0) {
-      intent.putExtra(Intent.EXTRA_EMAIL, to);
-    }
-    if (cc != null && cc.length != 0) {
-      intent.putExtra(Intent.EXTRA_CC, cc);
-    }
-    if (bcc != null && bcc.length != 0) {
-      intent.putExtra(Intent.EXTRA_BCC, bcc);
-    }
-    putExtra(intent, Intent.EXTRA_SUBJECT, subject);
-    putExtra(intent, Intent.EXTRA_TEXT, body);
-    intent.setType("text/plain");
-    launchIntent(intent);
-  }
-
-  final void shareBySMS(String contents) {
-    sendSMSFromUri("smsto:", contents);
-  }
-
-  final void sendSMS(String phoneNumber, String body) {
-    sendSMSFromUri("smsto:" + phoneNumber, body);
-  }
-
-  final void sendSMSFromUri(String uri, String body) {
-    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));
-    putExtra(intent, "sms_body", body);
-    // Exit the app once the SMS is sent
-    intent.putExtra("compose_mode", true);
-    launchIntent(intent);
-  }
-
-  final void sendMMS(String phoneNumber, String subject, String body) {
-    sendMMSFromUri("mmsto:" + phoneNumber, subject, body);
-  }
-
-  final void sendMMSFromUri(String uri, String subject, String body) {
-    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));
-    // The Messaging app needs to see a valid subject or else it will treat this an an SMS.
-    if (subject == null || subject.isEmpty()) {
-      putExtra(intent, "subject", activity.getString(R.string.msg_default_mms_subject));
-    } else {
-      putExtra(intent, "subject", subject);
-    }
-    putExtra(intent, "sms_body", body);
-    intent.putExtra("compose_mode", true);
-    launchIntent(intent);
-  }
-
-  final void dialPhone(String phoneNumber) {
-    launchIntent(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)));
-  }
-
-  final void dialPhoneFromUri(String uri) {
-    launchIntent(new Intent(Intent.ACTION_DIAL, Uri.parse(uri)));
-  }
-
-  final void openMap(String geoURI) {
-    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(geoURI)));
-  }
-
-  /**
-   * Do a geo search using the address as the query.
-   *
-   * @param address The address to find
-   */
-  final void searchMap(String address) {
-    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + Uri.encode(address))));
-  }
-
-  final void getDirections(double latitude, double longitude) {
-    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("http://maps.google." +
-        LocaleManager.getCountryTLD(activity) + "/maps?f=d&daddr=" + latitude + ',' + longitude)));
-  }
-
-  // Uses the mobile-specific version of Product Search, which is formatted for small screens.
-  final void openProductSearch(String upc) {
-    Uri uri = Uri.parse("http://www.google." + LocaleManager.getProductSearchCountryTLD(activity) +
-        "/m/products?q=" + upc + "&source=zxing");
-    launchIntent(new Intent(Intent.ACTION_VIEW, uri));
-  }
-
-  final void openBookSearch(String isbn) {
-    Uri uri = Uri.parse("http://books.google." + LocaleManager.getBookSearchCountryTLD(activity) +
-        "/books?vid=isbn" + isbn);
-    launchIntent(new Intent(Intent.ACTION_VIEW, uri));
-  }
-
-  final void searchBookContents(String isbnOrUrl) {
-    Intent intent = new Intent(Intents.SearchBookContents.ACTION);
-    intent.setClassName(activity, SearchBookContentsActivity.class.getName());
-    putExtra(intent, Intents.SearchBookContents.ISBN, isbnOrUrl);
-    launchIntent(intent);
-  }
-
-  final void openURL(String url) {
-    // Strangely, some Android browsers don't seem to register to handle HTTP:// or HTTPS://.
-    // Lower-case these as it should always be OK to lower-case these schemes.
-    if (url.startsWith("HTTP://")) {
-      url = "http" + url.substring(4);
-    } else if (url.startsWith("HTTPS://")) {
-      url = "https" + url.substring(5);
-    }
-    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
-    try {
-      launchIntent(intent);
-    } catch (ActivityNotFoundException ignored) {
-      Log.w(TAG, "Nothing available to handle " + intent);
-    }
-  }
-
-  final void webSearch(String query) {
-    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
-    intent.putExtra("query", query);
-    launchIntent(intent);
-  }
-
-  /**
-   * Like {@link #launchIntent(Intent)} but will tell you if it is not handle-able
-   * via {@link ActivityNotFoundException}.
-   *
-   * @throws ActivityNotFoundException
-   */
-  final void rawLaunchIntent(Intent intent) {
-    if (intent != null) {
-      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-      Log.d(TAG, "Launching intent: " + intent + " with extras: " + intent.getExtras());
-      activity.startActivity(intent);
-    }
-  }
-
-  /**
-   * Like {@link #rawLaunchIntent(Intent)} but will show a user dialog if nothing is available to handle.
-   */
-  final void launchIntent(Intent intent) {
-    try {
-      rawLaunchIntent(intent);
-    } catch (ActivityNotFoundException ignored) {
-      AlertDialog.Builder builder = new AlertDialog.Builder(activity);
-      builder.setTitle(R.string.app_name);
-      builder.setMessage(R.string.msg_intent_failed);
-      builder.setPositiveButton(R.string.button_ok, null);
-      builder.show();
-    }
-  }
-
-  private static void putExtra(Intent intent, String key, String value) {
-    if (value != null && !value.isEmpty()) {
-      intent.putExtra(key, value);
-    }
-  }
-
-  private String parseCustomSearchURL() {
-    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
-    String customProductSearch = prefs.getString(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH,
-        null);
-    if (customProductSearch != null && customProductSearch.trim().isEmpty()) {
-      return null;
-    }
-    return customProductSearch;
-  }
-
-  final String fillInCustomSearchURL(String text) {
-    if (customProductSearch == null) {
-      return text; // ?
-    }
-    try {
-      text = URLEncoder.encode(text, "UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      // can't happen; UTF-8 is always supported. Continue, I guess, without encoding      
-    }
-    String url = customProductSearch;
-    if (rawResult != null) {
-      // Replace %f but only if it doesn't seem to be a hex escape sequence. This remains
-      // problematic but avoids the more surprising problem of breaking escapes
-      url = url.replaceFirst("%f(?![0-9a-f])", rawResult.getBarcodeFormat().toString());
-      if (url.contains("%t")) {
-        ParsedResult parsedResultAgain = ResultParser.parseResult(rawResult);
-        url = url.replace("%t", parsedResultAgain.getType().toString());
-      }
-    }
-    // Replace %s last as it might contain itself %f or %t
-    return url.replace("%s", text);
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultHandlerFactory.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultHandlerFactory.java
deleted file mode 100755
index a31d089..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/ResultHandlerFactory.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.result;
-
-import com.google.zxing.Result;
-import com.google.zxing.client.android.CaptureActivity;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.ResultParser;
-
-/**
- * Manufactures Android-specific handlers based on the barcode content's type.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class ResultHandlerFactory {
-  private ResultHandlerFactory() {
-  }
-
-  public static ResultHandler makeResultHandler(CaptureActivity activity, Result rawResult) {
-    ParsedResult result = parseResult(rawResult);
-    switch (result.getType()) {
-      case ADDRESSBOOK:
-        return new AddressBookResultHandler(activity, result);
-      case EMAIL_ADDRESS:
-        return new EmailAddressResultHandler(activity, result);
-      case PRODUCT:
-        return new ProductResultHandler(activity, result, rawResult);
-      case URI:
-        return new URIResultHandler(activity, result);
-      case WIFI:
-        return new WifiResultHandler(activity, result);
-      case GEO:
-        return new GeoResultHandler(activity, result);
-      case TEL:
-        return new TelResultHandler(activity, result);
-      case SMS:
-        return new SMSResultHandler(activity, result);
-      case CALENDAR:
-        return new CalendarResultHandler(activity, result);
-      case ISBN:
-        return new ISBNResultHandler(activity, result, rawResult);
-      default:
-        return new TextResultHandler(activity, result, rawResult);
-    }
-  }
-
-  private static ParsedResult parseResult(Result rawResult) {
-    return ResultParser.parseResult(rawResult);
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/SMSResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/SMSResultHandler.java
deleted file mode 100755
index 22bce75..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/SMSResultHandler.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-import android.telephony.PhoneNumberUtils;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.SMSParsedResult;
-
-/**
- * Handles SMS addresses, offering a choice of composing a new SMS or MMS message.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class SMSResultHandler extends ResultHandler {
-  private static final int[] buttons = {
-      R.string.button_sms,
-      R.string.button_mms
-  };
-
-  public SMSResultHandler(Activity activity, ParsedResult result) {
-    super(activity, result);
-  }
-
-  @Override
-  public int getButtonCount() {
-    return buttons.length;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    SMSParsedResult smsResult = (SMSParsedResult) getResult();
-    String number = smsResult.getNumbers()[0];
-    switch (index) {
-      case 0:
-        // Don't know of a way yet to express a SENDTO intent with multiple recipients
-        sendSMS(number, smsResult.getBody());
-        break;
-      case 1:
-        sendMMS(number, smsResult.getSubject(), smsResult.getBody());
-        break;
-    }
-  }
-
-  @Override
-  public CharSequence getDisplayContents() {
-    SMSParsedResult smsResult = (SMSParsedResult) getResult();
-    String[] rawNumbers = smsResult.getNumbers();
-    String[] formattedNumbers = new String[rawNumbers.length];
-    for (int i = 0; i < rawNumbers.length; i++) {
-      formattedNumbers[i] = PhoneNumberUtils.formatNumber(rawNumbers[i]);
-    }
-    StringBuilder contents = new StringBuilder(50);
-    ParsedResult.maybeAppend(formattedNumbers, contents);
-    ParsedResult.maybeAppend(smsResult.getSubject(), contents);
-    ParsedResult.maybeAppend(smsResult.getBody(), contents);
-    return contents.toString();
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_sms;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/TelResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/TelResultHandler.java
deleted file mode 100755
index a42e7cf..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/TelResultHandler.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-import android.telephony.PhoneNumberUtils;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.TelParsedResult;
-
-/**
- * Offers relevant actions for telephone numbers.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class TelResultHandler extends ResultHandler {
-  private static final int[] buttons = {
-      R.string.button_dial,
-      R.string.button_add_contact
-  };
-
-  public TelResultHandler(Activity activity, ParsedResult result) {
-    super(activity, result);
-  }
-
-  @Override
-  public int getButtonCount() {
-    return buttons.length;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    TelParsedResult telResult = (TelParsedResult) getResult();
-    switch (index) {
-      case 0:
-        dialPhoneFromUri(telResult.getTelURI());
-        // When dialer comes up, it allows underlying display activity to continue or something,
-        // but app can't get camera in this state. Avoid issues by just quitting, only in the
-        // case of a phone number
-        getActivity().finish();
-        break;
-      case 1:
-        String[] numbers = new String[1];
-        numbers[0] = telResult.getNumber();
-        addPhoneOnlyContact(numbers, null);
-        break;
-    }
-  }
-
-  // Overriden so we can take advantage of Android's phone number hyphenation routines.
-  @Override
-  public CharSequence getDisplayContents() {
-    String contents = getResult().getDisplayResult();
-    contents = contents.replace("\r", "");
-    return PhoneNumberUtils.formatNumber(contents);
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_tel;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/TextResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/TextResultHandler.java
deleted file mode 100755
index 32bda84..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/TextResultHandler.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-
-import com.alibaba.weex.R;
-import com.google.zxing.Result;
-import com.google.zxing.client.result.ParsedResult;
-
-/**
- * This class handles TextParsedResult as well as unknown formats. It's the fallback handler.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class TextResultHandler extends ResultHandler {
-
-  private static final int[] buttons = {
-      R.string.button_web_search,
-      R.string.button_share_by_email,
-      R.string.button_share_by_sms,
-      R.string.button_custom_product_search,
-  };
-
-  public TextResultHandler(Activity activity, ParsedResult result, Result rawResult) {
-    super(activity, result, rawResult);
-  }
-
-  @Override
-  public int getButtonCount() {
-    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    String text = getResult().getDisplayResult();
-    switch (index) {
-      case 0:
-        webSearch(text);
-        break;
-      case 1:
-        shareByEmail(text);
-        break;
-      case 2:
-        shareBySMS(text);
-        break;
-      case 3:
-        openURL(fillInCustomSearchURL(text));
-        break;
-    }
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_text;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/URIResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/URIResultHandler.java
deleted file mode 100755
index 6d06583..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/URIResultHandler.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.android.LocaleManager;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.URIParsedResult;
-
-import java.util.Locale;
-
-/**
- * Offers appropriate actions for URLS.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class URIResultHandler extends ResultHandler {
-  // URIs beginning with entries in this array will not be saved to history or copied to the
-  // clipboard for security.
-  private static final String[] SECURE_PROTOCOLS = {
-    "otpauth:"
-  };
-
-  private static final int[] buttons = {
-      R.string.button_open_browser,
-      R.string.button_share_by_email,
-      R.string.button_share_by_sms,
-      R.string.button_search_book_contents,
-  };
-
-  public URIResultHandler(Activity activity, ParsedResult result) {
-    super(activity, result);
-  }
-
-  @Override
-  public int getButtonCount() {
-    if (LocaleManager.isBookSearchUrl(((URIParsedResult) getResult()).getURI())) {
-      return buttons.length;
-    }
-    return buttons.length - 1;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return buttons[index];
-  }
-
-  @Override
-  public Integer getDefaultButtonID() {
-    return 0;
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    URIParsedResult uriResult = (URIParsedResult) getResult();
-    String uri = uriResult.getURI();
-    switch (index) {
-      case 0:
-        openURL(uri);
-        break;
-      case 1:
-        shareByEmail(uri);
-        break;
-      case 2:
-        shareBySMS(uri);
-        break;
-      case 3:
-        searchBookContents(uri);
-        break;
-    }
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_uri;
-  }
-
-  @Override
-  public boolean areContentsSecure() {
-    URIParsedResult uriResult = (URIParsedResult) getResult();
-    String uri = uriResult.getURI().toLowerCase(Locale.ENGLISH);
-    for (String secure : SECURE_PROTOCOLS) {
-      if (uri.startsWith(secure)) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/WifiResultHandler.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/WifiResultHandler.java
deleted file mode 100755
index ab76af3..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/WifiResultHandler.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.result;
-
-import android.app.Activity;
-import android.content.Context;
-import android.net.wifi.WifiManager;
-import android.os.AsyncTask;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.android.CaptureActivity;
-import com.google.zxing.client.android.wifi.WifiConfigManager;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.WifiParsedResult;
-
-/**
- * Handles wifi access information.
- *
- * @author Vikram Aggarwal
- * @author Sean Owen
- */
-public final class WifiResultHandler extends ResultHandler {
-
-  private static final String TAG = WifiResultHandler.class.getSimpleName();
-
-  private final CaptureActivity parent;
-
-  public WifiResultHandler(CaptureActivity activity, ParsedResult result) {
-    super(activity, result);
-    parent = activity;
-  }
-
-  @Override
-  public int getButtonCount() {
-    // We just need one button, and that is to configure the wireless.  This could change in the future.
-    return 1;
-  }
-
-  @Override
-  public int getButtonText(int index) {
-    return R.string.button_wifi;
-  }
-
-  @Override
-  public void handleButtonPress(int index) {
-    if (index == 0) {
-      WifiParsedResult wifiResult = (WifiParsedResult) getResult();
-      WifiManager wifiManager = (WifiManager) getActivity().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
-      if (wifiManager == null) {
-        Log.w(TAG, "No WifiManager available from device");
-        return;
-      }
-      final Activity activity = getActivity();
-      activity.runOnUiThread(new Runnable() {
-        @Override
-        public void run() {
-          Toast.makeText(activity.getApplicationContext(), R.string.wifi_changing_network, Toast.LENGTH_SHORT).show();
-        }
-      });
-      new WifiConfigManager(wifiManager).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, wifiResult);
-      parent.restartPreviewAfterDelay(0L);
-    }
-  }
-
-  // Display the name of the network and the network type to the user.
-  @Override
-  public CharSequence getDisplayContents() {
-    WifiParsedResult wifiResult = (WifiParsedResult) getResult();
-    return wifiResult.getSsid() + " (" + wifiResult.getNetworkEncryption() + ')';
-  }
-
-  @Override
-  public int getDisplayTitle() {
-    return R.string.result_wifi;
-  }
-}
\ No newline at end of file
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/BookResultInfoRetriever.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/BookResultInfoRetriever.java
deleted file mode 100755
index 769f770..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/BookResultInfoRetriever.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.result.supplement;
-
-import android.content.Context;
-import android.widget.TextView;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.android.HttpHelper;
-import com.google.zxing.client.android.LocaleManager;
-import com.google.zxing.client.android.history.HistoryManager;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * @author Kamil Kaczmarczyk
- * @author Sean Owen
- */
-final class BookResultInfoRetriever extends SupplementalInfoRetriever {
-
-  private final String isbn;
-  private final String source;
-  private final Context context;
-  
-  BookResultInfoRetriever(TextView textView, String isbn, HistoryManager historyManager, Context context) {
-    super(textView, historyManager);
-    this.isbn = isbn;
-    this.source = context.getString(R.string.msg_google_books);
-    this.context = context;
-  }
-
-  @Override
-  void retrieveSupplementalInfo() throws IOException {
-
-    CharSequence contents = HttpHelper.downloadViaHttp("https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn,
-                                                       HttpHelper.ContentType.JSON);
-
-    if (contents.length() == 0) {
-      return;
-    }
-
-    String title;
-    String pages;
-    Collection<String> authors = null;
-
-    try {
-
-      JSONObject topLevel = (JSONObject) new JSONTokener(contents.toString()).nextValue();
-      JSONArray items = topLevel.optJSONArray("items");
-      if (items == null || items.isNull(0)) {
-        return;
-      }
-
-      JSONObject volumeInfo = ((JSONObject) items.get(0)).getJSONObject("volumeInfo");
-      if (volumeInfo == null) {
-        return;
-      }
-
-      title = volumeInfo.optString("title");
-      pages = volumeInfo.optString("pageCount");
-
-      JSONArray authorsArray = volumeInfo.optJSONArray("authors");
-      if (authorsArray != null && !authorsArray.isNull(0)) {
-        authors = new ArrayList<>(authorsArray.length());
-        for (int i = 0; i < authorsArray.length(); i++) {
-          authors.add(authorsArray.getString(i));
-        }
-      }
-
-    } catch (JSONException e) {
-      throw new IOException(e);
-    }
-
-    Collection<String> newTexts = new ArrayList<>();
-    maybeAddText(title, newTexts);
-    maybeAddTextSeries(authors, newTexts);
-    maybeAddText(pages == null || pages.isEmpty() ? null : pages + "pp.", newTexts);
-    
-    String baseBookUri = "http://www.google." + LocaleManager.getBookSearchCountryTLD(context)
-        + "/search?tbm=bks&source=zxing&q=";
-
-    append(isbn, source, newTexts.toArray(new String[newTexts.size()]), baseBookUri + isbn);
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/ProductResultInfoRetriever.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/ProductResultInfoRetriever.java
deleted file mode 100755
index ad6fe8e..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/ProductResultInfoRetriever.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.result.supplement;
-
-import android.content.Context;
-import android.text.Html;
-import android.widget.TextView;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.android.HttpHelper;
-import com.google.zxing.client.android.LocaleManager;
-import com.google.zxing.client.android.history.HistoryManager;
-
-import java.io.IOException;
-import java.net.URLEncoder;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * <p>Retrieves product information from Google Product search.</p>
- *
- * <p><strong>Please do not reuse this code.</strong> Using results in this way requires permission
- * from Google, and that is not granted to users via this project.</p>
- *
- * @author Sean Owen
- */
-final class ProductResultInfoRetriever extends SupplementalInfoRetriever {
-
-  private static final Pattern[] PRODUCT_NAME_PRICE_PATTERNS = {
-    Pattern.compile(",event\\)\">([^<]+)</a></h3>.+<span class=psrp>([^<]+)</span>"),
-    Pattern.compile("owb63p\">([^<]+).+zdi3pb\">([^<]+)"),
-  };
-
-  private final String productID;
-  private final String source;
-  private final Context context;
-
-  ProductResultInfoRetriever(TextView textView, String productID, HistoryManager historyManager, Context context) {
-    super(textView, historyManager);
-    this.productID = productID;
-    this.source = context.getString(R.string.msg_google_product);
-    this.context = context;
-  }
-
-  @Override
-  void retrieveSupplementalInfo() throws IOException {
-
-    String encodedProductID = URLEncoder.encode(productID, "UTF-8");
-    String uri = "https://www.google." + LocaleManager.getProductSearchCountryTLD(context)
-            + "/m/products?ie=utf8&oe=utf8&scoring=p&source=zxing&q=" + encodedProductID;
-    CharSequence content = HttpHelper.downloadViaHttp(uri, HttpHelper.ContentType.HTML);
-
-    for (Pattern p : PRODUCT_NAME_PRICE_PATTERNS) {
-      Matcher matcher = p.matcher(content);
-      if (matcher.find()) {
-        append(productID,
-               source,
-               new String[] { unescapeHTML(matcher.group(1)), unescapeHTML(matcher.group(2)) },
-               uri);
-        break;
-      }
-    }
-  }
-
-  private static String unescapeHTML(String raw) {
-    return Html.fromHtml(raw).toString();
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/SupplementalInfoRetriever.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/SupplementalInfoRetriever.java
deleted file mode 100755
index 8791be8..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/SupplementalInfoRetriever.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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.result.supplement;
-
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.concurrent.RejectedExecutionException;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.method.LinkMovementMethod;
-import android.text.style.URLSpan;
-import android.util.Log;
-import android.widget.TextView;
-
-import com.google.zxing.client.android.history.HistoryManager;
-import com.google.zxing.client.result.ISBNParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.ProductParsedResult;
-import com.google.zxing.client.result.URIParsedResult;
-
-public abstract class SupplementalInfoRetriever extends AsyncTask<Object,Object,Object> {
-
-  private static final String TAG = "SupplementalInfo";
-
-  public static void maybeInvokeRetrieval(TextView textView,
-                                          ParsedResult result,
-                                          HistoryManager historyManager,
-                                          Context context) {
-    try {
-      if (result instanceof URIParsedResult) {
-        SupplementalInfoRetriever uriRetriever =
-            new URIResultInfoRetriever(textView, (URIParsedResult) result, historyManager, context);
-        uriRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-        SupplementalInfoRetriever titleRetriever =
-            new TitleRetriever(textView, (URIParsedResult) result, historyManager);
-        titleRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-      } else if (result instanceof ProductParsedResult) {
-        ProductParsedResult productParsedResult = (ProductParsedResult) result;
-        String productID = productParsedResult.getProductID();
-        SupplementalInfoRetriever productRetriever =
-            new ProductResultInfoRetriever(textView, productID, historyManager, context);
-        productRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-      } else if (result instanceof ISBNParsedResult) {
-        String isbn = ((ISBNParsedResult) result).getISBN();
-        SupplementalInfoRetriever productInfoRetriever =
-            new ProductResultInfoRetriever(textView, isbn, historyManager, context);
-        productInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-        SupplementalInfoRetriever bookInfoRetriever =
-            new BookResultInfoRetriever(textView, isbn, historyManager, context);
-        bookInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-      }
-    } catch (RejectedExecutionException ree) {
-      // do nothing
-    }
-  }
-
-  private final WeakReference<TextView> textViewRef;
-  private final WeakReference<HistoryManager> historyManagerRef;
-  private final Collection<Spannable> newContents;
-  private final Collection<String[]> newHistories;
-
-  SupplementalInfoRetriever(TextView textView, HistoryManager historyManager) {
-    textViewRef = new WeakReference<>(textView);
-    historyManagerRef = new WeakReference<>(historyManager);
-    newContents = new ArrayList<>();
-    newHistories = new ArrayList<>();
-  }
-
-  @Override
-  public final Object doInBackground(Object... args) {
-    try {
-      retrieveSupplementalInfo();
-    } catch (IOException e) {
-      Log.w(TAG, e);
-    }
-    return null;
-  }
-
-  @Override
-  protected final void onPostExecute(Object arg) {
-    TextView textView = textViewRef.get();
-    if (textView != null) {
-      for (CharSequence content : newContents) {
-        textView.append(content);
-      }
-      textView.setMovementMethod(LinkMovementMethod.getInstance());
-    }
-    HistoryManager historyManager = historyManagerRef.get();
-    if (historyManager != null) {
-      for (String[] text : newHistories) {
-        historyManager.addHistoryItemDetails(text[0], text[1]);
-      }
-    }
-  }
-
-  abstract void retrieveSupplementalInfo() throws IOException;
-
-  final void append(String itemID, String source, String[] newTexts, String linkURL) {
-
-    StringBuilder newTextCombined = new StringBuilder();
-
-    if (source != null) {
-      newTextCombined.append(source).append(' ');
-    }
-
-    int linkStart = newTextCombined.length();
-
-    boolean first = true;
-    for (String newText : newTexts) {
-      if (first) {
-        newTextCombined.append(newText);
-        first = false;
-      } else {
-        newTextCombined.append(" [");
-        newTextCombined.append(newText);
-        newTextCombined.append(']');
-      }
-    }
-
-    int linkEnd = newTextCombined.length();
-
-    String newText = newTextCombined.toString();
-    Spannable content = new SpannableString(newText + "\n\n");
-    if (linkURL != null) {
-      // Strangely, some Android browsers don't seem to register to handle HTTP:// or HTTPS://.
-      // Lower-case these as it should always be OK to lower-case these schemes.
-      if (linkURL.startsWith("HTTP://")) {
-        linkURL = "http" + linkURL.substring(4);
-      } else if (linkURL.startsWith("HTTPS://")) {
-        linkURL = "https" + linkURL.substring(5);
-      }
-      content.setSpan(new URLSpan(linkURL), linkStart, linkEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-    }
-
-    newContents.add(content);
-    newHistories.add(new String[] {itemID, newText});
-  }
-  
-  static void maybeAddText(String text, Collection<String> texts) {
-    if (text != null && !text.isEmpty()) {
-      texts.add(text);
-    }
-  }
-  
-  static void maybeAddTextSeries(Collection<String> textSeries, Collection<String> texts) {
-    if (textSeries != null && !textSeries.isEmpty()) {
-      boolean first = true;
-      StringBuilder authorsText = new StringBuilder();
-      for (String author : textSeries) {
-        if (first) {
-          first = false;
-        } else {
-          authorsText.append(", ");
-        }
-        authorsText.append(author);
-      }
-      texts.add(authorsText.toString());
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/TitleRetriever.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/TitleRetriever.java
deleted file mode 100755
index 7d0f7e2..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/TitleRetriever.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2012 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.result.supplement;
-
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import android.text.Html;
-import android.widget.TextView;
-
-import com.google.zxing.client.android.HttpHelper;
-import com.google.zxing.client.android.history.HistoryManager;
-import com.google.zxing.client.result.URIParsedResult;
-
-/**
- * Retrieves the title of a web page as supplemental info.
- *
- * @author Sean Owen
- */
-final class TitleRetriever extends SupplementalInfoRetriever {
-
-  private static final Pattern TITLE_PATTERN = Pattern.compile("<title>([^<]+)");
-  private static final int MAX_TITLE_LEN = 100;
-
-  private final String httpUrl;
-
-  TitleRetriever(TextView textView, URIParsedResult result, HistoryManager historyManager) {
-    super(textView, historyManager);
-    this.httpUrl = result.getURI();
-  }
-
-  @Override
-  void retrieveSupplementalInfo() {
-    CharSequence contents;
-    try {
-      contents = HttpHelper.downloadViaHttp(httpUrl, HttpHelper.ContentType.HTML, 4096);
-    } catch (IOException ioe) {
-      // ignore this
-      return;
-    }
-    if (contents != null && contents.length() > 0) {
-      Matcher m = TITLE_PATTERN.matcher(contents);
-      if (m.find()) {
-        String title = m.group(1);
-        if (title != null && !title.isEmpty()) {
-          title = Html.fromHtml(title).toString();
-          if (title.length() > MAX_TITLE_LEN) {
-            title = title.substring(0, MAX_TITLE_LEN) + "...";
-          }
-          append(httpUrl, null, new String[] {title}, httpUrl);
-        }
-      }
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/URIResultInfoRetriever.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/URIResultInfoRetriever.java
deleted file mode 100755
index bebf3be..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/result/supplement/URIResultInfoRetriever.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.result.supplement;
-
-import android.content.Context;
-import android.widget.TextView;
-
-import com.alibaba.weex.R;
-import com.google.zxing.client.android.HttpHelper;
-import com.google.zxing.client.android.history.HistoryManager;
-import com.google.zxing.client.result.URIParsedResult;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-final class URIResultInfoRetriever extends SupplementalInfoRetriever {
-
-  private static final int MAX_REDIRECTS = 5;
-
-  private final URIParsedResult result;
-  private final String redirectString;
-
-  URIResultInfoRetriever(TextView textView, URIParsedResult result, HistoryManager historyManager, Context context) {
-    super(textView, historyManager);
-    redirectString = context.getString(R.string.msg_redirect);
-    this.result = result;
-  }
-
-  @Override
-  void retrieveSupplementalInfo() throws IOException {
-    URI oldURI;
-    try {
-      oldURI = new URI(result.getURI());
-    } catch (URISyntaxException ignored) {
-      return;
-    }
-    URI newURI = HttpHelper.unredirect(oldURI);
-    int count = 0;
-    while (count++ < MAX_REDIRECTS && !oldURI.equals(newURI)) {
-      append(result.getDisplayResult(), 
-             null, 
-             new String[] { redirectString + " : " + newURI }, 
-             newURI.toString());
-      oldURI = newURI;
-      newURI = HttpHelper.unredirect(newURI);
-    }
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/AppInfo.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/AppInfo.java
deleted file mode 100755
index 94bde9b..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/AppInfo.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 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.share;
-
-import android.graphics.drawable.Drawable;
-
-final class AppInfo implements Comparable<AppInfo> {
-  
-  private final String packageName;
-  private final String label;
-  private final Drawable icon;
-
-  AppInfo(String packageName, String label, Drawable icon) {
-    this.packageName = packageName;
-    this.label = label;
-    this.icon = icon;
-  }
-
-  String getPackageName() {
-    return packageName;
-  }
-  
-  Drawable getIcon() {
-    return icon;
-  }
-
-  @Override
-  public String toString() {
-    return label;
-  }
-
-  @Override
-  public int compareTo(AppInfo another) {
-    return label.compareTo(another.label);
-  }
-  
-  @Override
-  public int hashCode() {
-    return label.hashCode();
-  }
-  
-  @Override
-  public boolean equals(Object other) {
-    if (!(other instanceof AppInfo)) {
-      return false;
-    }
-    AppInfo another = (AppInfo) other;
-    return label.equals(another.label);
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/AppPickerActivity.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/AppPickerActivity.java
deleted file mode 100755
index 319fd63..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/AppPickerActivity.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 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.client.android.share;
-
-import android.app.ListActivity;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.view.View;
-import android.widget.Adapter;
-import android.widget.ListView;
-
-import java.util.List;
-
-public final class AppPickerActivity extends ListActivity {
-
-  private AsyncTask<Object,Object,List<AppInfo>> backgroundTask;
-
-  @Override
-  protected void onResume() {
-    super.onResume();
-    backgroundTask = new LoadPackagesAsyncTask(this);
-    backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-  }
-
-  @Override
-  protected void onPause() {
-    AsyncTask<?,?,?> task = backgroundTask;
-    if (task != null) {
-      task.cancel(true);
-      backgroundTask = null;
-    }
-    super.onPause();
-  }
-
-  @Override
-  protected void onListItemClick(ListView l, View view, int position, long id) {
-    Adapter adapter = getListAdapter();
-    if (position >= 0 && position < adapter.getCount()) {
-      String packageName = ((AppInfo) adapter.getItem(position)).getPackageName();
-      Intent intent = new Intent();
-      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-      intent.putExtra("url", "market://details?id=" + packageName);
-      setResult(RESULT_OK, intent);
-    } else {
-      setResult(RESULT_CANCELED);      
-    }
-    finish();
-  }
-
-}
diff --git a/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/BookMarkColumns.java b/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/BookMarkColumns.java
deleted file mode 100755
index 0bcc262..0000000
--- a/android/playground/src/main/java_zxing/com/google/zxing/client/android/share/BookMarkColumns.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.google.zxing.client.android.share;
-
... 2214 lines suppressed ...