Ray Zhang 12 лет назад
Родитель
Сommit
962f0ad133
100 измененных файлов с 7489 добавлено и 0 удалено
  1. 9 0
      RedAnt Photo/.classpath
  2. 33 0
      RedAnt Photo/.project
  3. 2 0
      RedAnt Photo/.settings/org.eclipse.core.resources.prefs
  4. 4 0
      RedAnt Photo/.settings/org.eclipse.jdt.core.prefs
  5. 94 0
      RedAnt Photo/AndroidManifest.xml
  6. 94 0
      RedAnt Photo/bin/AndroidManifest.xml
  7. BIN
      RedAnt Photo/bin/RedAnt Photo.apk
  8. BIN
      RedAnt Photo/bin/classes.dex
  9. BIN
      RedAnt Photo/bin/dexedLibs/android-support-v4-244ae62fbeb5c51ea12edd1e7158e520.jar
  10. BIN
      RedAnt Photo/bin/dexedLibs/core-2.3.0-84c93f4ef03886c0c217796c3e60cab1.jar
  11. BIN
      RedAnt Photo/bin/dexedLibs/httpmime-4.1.1-dbad932ae6bcfab1636e85a4463b0b5c.jar
  12. 3 0
      RedAnt Photo/bin/jarlist.cache
  13. BIN
      RedAnt Photo/bin/res/crunch/drawable-hdpi/apertureblack128.png
  14. BIN
      RedAnt Photo/bin/res/crunch/drawable-hdpi/barcode_scanner128.png
  15. BIN
      RedAnt Photo/bin/res/crunch/drawable-hdpi/camera_256.png
  16. BIN
      RedAnt Photo/bin/res/crunch/drawable-hdpi/database_upload128.png
  17. BIN
      RedAnt Photo/bin/res/crunch/drawable-hdpi/ic_launcher.png
  18. BIN
      RedAnt Photo/bin/res/crunch/drawable-hdpi/ic_shipping.png
  19. BIN
      RedAnt Photo/bin/res/crunch/drawable-hdpi/no_pic.png
  20. BIN
      RedAnt Photo/bin/res/crunch/drawable-hdpi/qr_code256.png
  21. BIN
      RedAnt Photo/bin/res/crunch/drawable-mdpi/ic_launcher.png
  22. BIN
      RedAnt Photo/bin/res/crunch/drawable-xhdpi/ic_launcher.png
  23. BIN
      RedAnt Photo/bin/res/crunch/drawable-xxhdpi/ic_launcher.png
  24. BIN
      RedAnt Photo/bin/resources.ap_
  25. BIN
      RedAnt Photo/ic_launcher-web.png
  26. BIN
      RedAnt Photo/libs/android-support-v4.jar
  27. BIN
      RedAnt Photo/libs/core-2.3.0.jar
  28. BIN
      RedAnt Photo/libs/httpmime-4.1.1.jar
  29. 20 0
      RedAnt Photo/proguard-project.txt
  30. 14 0
      RedAnt Photo/project.properties
  31. BIN
      RedAnt Photo/res/drawable-hdpi/apertureblack128.png
  32. BIN
      RedAnt Photo/res/drawable-hdpi/barcode_scanner128.png
  33. BIN
      RedAnt Photo/res/drawable-hdpi/camera_256.png
  34. BIN
      RedAnt Photo/res/drawable-hdpi/database_upload128.png
  35. BIN
      RedAnt Photo/res/drawable-hdpi/ic_launcher.png
  36. BIN
      RedAnt Photo/res/drawable-hdpi/ic_shipping.png
  37. 20 0
      RedAnt Photo/res/drawable-hdpi/imagebutton.xml
  38. BIN
      RedAnt Photo/res/drawable-hdpi/no_pic.png
  39. BIN
      RedAnt Photo/res/drawable-hdpi/qr_code256.png
  40. BIN
      RedAnt Photo/res/drawable-mdpi/ic_launcher.png
  41. BIN
      RedAnt Photo/res/drawable-xhdpi/ic_launcher.png
  42. BIN
      RedAnt Photo/res/drawable-xxhdpi/ic_launcher.png
  43. 89 0
      RedAnt Photo/res/layout-land/activity_main.xml
  44. 201 0
      RedAnt Photo/res/layout-ldpi/capture.xml
  45. 75 0
      RedAnt Photo/res/layout-port/activity_main.xml
  46. 76 0
      RedAnt Photo/res/layout/activity_locker.xml
  47. 76 0
      RedAnt Photo/res/layout/activity_login.xml
  48. 115 0
      RedAnt Photo/res/layout/activity_main1.xml
  49. 208 0
      RedAnt Photo/res/layout/capture.xml
  50. 21 0
      RedAnt Photo/res/layout/help.xml
  51. 26 0
      RedAnt Photo/res/layout/temp.xml
  52. 38 0
      RedAnt Photo/res/menu/capture.xml
  53. 8 0
      RedAnt Photo/res/menu/locker.xml
  54. 8 0
      RedAnt Photo/res/menu/login.xml
  55. 13 0
      RedAnt Photo/res/menu/main.xml
  56. 9 0
      RedAnt Photo/res/menu/main_activity1.xml
  57. BIN
      RedAnt Photo/res/raw/beep.ogg
  58. 10 0
      RedAnt Photo/res/values-large/styles.xml
  59. 8 0
      RedAnt Photo/res/values-sw600dp/dimens.xml
  60. 9 0
      RedAnt Photo/res/values-sw720dp-land/dimens.xml
  61. 11 0
      RedAnt Photo/res/values-v11/styles.xml
  62. 12 0
      RedAnt Photo/res/values-v14/styles.xml
  63. 47 0
      RedAnt Photo/res/values/arrays.xml
  64. 48 0
      RedAnt Photo/res/values/colors.xml
  65. 11 0
      RedAnt Photo/res/values/dimens.xml
  66. 25 0
      RedAnt Photo/res/values/ids.xml
  67. 66 0
      RedAnt Photo/res/values/strings.xml
  68. 51 0
      RedAnt Photo/res/values/styles.xml
  69. 24 0
      RedAnt Photo/res/values/themes.xml
  70. 110 0
      RedAnt Photo/res/xml/preferences.xml
  71. 112 0
      RedAnt Photo/src/com/usai/redant/camera/AutoFocusManager.java
  72. 307 0
      RedAnt Photo/src/com/usai/redant/camera/CameraConfigurationManager.java
  73. 311 0
      RedAnt Photo/src/com/usai/redant/camera/CameraManager.java
  74. 43 0
      RedAnt Photo/src/com/usai/redant/camera/FrontLightMode.java
  75. 56 0
      RedAnt Photo/src/com/usai/redant/camera/PreviewCallback.java
  76. 62 0
      RedAnt Photo/src/com/usai/redant/camera/open/OpenCameraInterface.java
  77. 87 0
      RedAnt Photo/src/com/usai/redant/photo/AmbientLightManager.java
  78. 128 0
      RedAnt Photo/src/com/usai/redant/photo/BeepManager.java
  79. 27 0
      RedAnt Photo/src/com/usai/redant/photo/BootReceiver.java
  80. 715 0
      RedAnt Photo/src/com/usai/redant/photo/CaptureActivity.java
  81. 169 0
      RedAnt Photo/src/com/usai/redant/photo/CaptureActivityHandler.java
  82. 101 0
      RedAnt Photo/src/com/usai/redant/photo/DecodeFormatManager.java
  83. 121 0
      RedAnt Photo/src/com/usai/redant/photo/DecodeHandler.java
  84. 236 0
      RedAnt Photo/src/com/usai/redant/photo/DecodeHintManager.java
  85. 104 0
      RedAnt Photo/src/com/usai/redant/photo/DecodeThread.java
  86. 49 0
      RedAnt Photo/src/com/usai/redant/photo/FinishListener.java
  87. 243 0
      RedAnt Photo/src/com/usai/redant/photo/HttpHelper.java
  88. 116 0
      RedAnt Photo/src/com/usai/redant/photo/InactivityTimer.java
  89. 261 0
      RedAnt Photo/src/com/usai/redant/photo/Intents.java
  90. 297 0
      RedAnt Photo/src/com/usai/redant/photo/LockerActivity.java
  91. 400 0
      RedAnt Photo/src/com/usai/redant/photo/LoginActivity.java
  92. 751 0
      RedAnt Photo/src/com/usai/redant/photo/MainActivity.java
  93. 56 0
      RedAnt Photo/src/com/usai/redant/photo/PreferencesActivity.java
  94. 71 0
      RedAnt Photo/src/com/usai/redant/photo/PreferencesFragment.java
  95. 15 0
      RedAnt Photo/src/com/usai/redant/photo/UploadService.java
  96. 35 0
      RedAnt Photo/src/com/usai/redant/photo/ViewfinderResultPointCallback.java
  97. 187 0
      RedAnt Photo/src/com/usai/redant/photo/ViewfinderView.java
  98. 43 0
      RedAnt Photo/src/com/usai/util/MD5.java
  99. 632 0
      RedAnt Photo/src/com/usai/util/Network.java
  100. 66 0
      RedAnt Photo/src/com/usai/util/SqlOpenHelper.java

+ 9 - 0
RedAnt Photo/.classpath

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>

+ 33 - 0
RedAnt Photo/.project

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>RedAnt Photo</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

+ 2 - 0
RedAnt Photo/.settings/org.eclipse.core.resources.prefs

@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding//src/com/usai/util=UTF-8

+ 4 - 0
RedAnt Photo/.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.source=1.6

+ 94 - 0
RedAnt Photo/AndroidManifest.xml

@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.usai.redant.photo"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="14"
+        android:targetSdkVersion="18" />
+
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_shipping"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.usai.redant.photo.MainActivity"
+            android:configChanges="orientation|keyboardHidden"
+            android:label="@string/app_name"
+            android:screenOrientation="landscape"
+            android:stateNotNeeded="true"
+            android:theme="@style/CaptureTheme" >
+
+            <!--
+                 <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            -->
+        </activity>
+        <activity
+            android:name="com.usai.redant.photo.CaptureActivity"
+            android:clearTaskOnLaunch="true"
+            android:configChanges="orientation|keyboardHidden"
+            android:label="Scan"
+            android:stateNotNeeded="true"
+            android:theme="@style/CaptureTheme"
+            android:windowSoftInputMode="stateAlwaysHidden" >
+
+            <!--
+                 <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            -->
+        </activity>
+        <activity
+            android:name="com.usai.redant.photo.LoginActivity"
+            android:label="@string/app_name"
+            android:screenOrientation="landscape"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name="com.usai.redant.photo.PreferencesActivityvity"
+            android:label="@string/preferences_name"
+            android:stateNotNeeded="true" >
+        </activity>
+        <activity
+            android:name="com.usai.redant.photo.LockerActivity"
+            android:label="@string/title_activity_locker"
+            android:screenOrientation="landscape"
+            android:windowSoftInputMode="adjustResize|stateVisible" >
+        </activity>
+
+        <receiver android:name="com.usai.redant.photo.BootReceiver" >
+            <intent-filter android:priority="2147483647" >
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+            </intent-filter>
+        </receiver>
+
+        <service
+            android:name="com.usai.redant.photo.UploadService"
+            android:label="usai upload service" >
+        </service>
+    </application>
+
+</manifest>

+ 94 - 0
RedAnt Photo/bin/AndroidManifest.xml

@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.usai.redant.photo"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="14"
+        android:targetSdkVersion="18" />
+
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_shipping"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.usai.redant.photo.MainActivity"
+            android:configChanges="orientation|keyboardHidden"
+            android:label="@string/app_name"
+            android:screenOrientation="landscape"
+            android:stateNotNeeded="true"
+            android:theme="@style/CaptureTheme" >
+
+            <!--
+                 <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            -->
+        </activity>
+        <activity
+            android:name="com.usai.redant.photo.CaptureActivity"
+            android:clearTaskOnLaunch="true"
+            android:configChanges="orientation|keyboardHidden"
+            android:label="Scan"
+            android:stateNotNeeded="true"
+            android:theme="@style/CaptureTheme"
+            android:windowSoftInputMode="stateAlwaysHidden" >
+
+            <!--
+                 <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            -->
+        </activity>
+        <activity
+            android:name="com.usai.redant.photo.LoginActivity"
+            android:label="@string/app_name"
+            android:screenOrientation="landscape"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name="com.usai.redant.photo.PreferencesActivityvity"
+            android:label="@string/preferences_name"
+            android:stateNotNeeded="true" >
+        </activity>
+        <activity
+            android:name="com.usai.redant.photo.LockerActivity"
+            android:label="@string/title_activity_locker"
+            android:screenOrientation="landscape"
+            android:windowSoftInputMode="adjustResize|stateVisible" >
+        </activity>
+
+        <receiver android:name="com.usai.redant.photo.BootReceiver" >
+            <intent-filter android:priority="2147483647" >
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+            </intent-filter>
+        </receiver>
+
+        <service
+            android:name="com.usai.redant.photo.UploadService"
+            android:label="usai upload service" >
+        </service>
+    </application>
+
+</manifest>

BIN
RedAnt Photo/bin/RedAnt Photo.apk


BIN
RedAnt Photo/bin/classes.dex


BIN
RedAnt Photo/bin/dexedLibs/android-support-v4-244ae62fbeb5c51ea12edd1e7158e520.jar


BIN
RedAnt Photo/bin/dexedLibs/core-2.3.0-84c93f4ef03886c0c217796c3e60cab1.jar


BIN
RedAnt Photo/bin/dexedLibs/httpmime-4.1.1-dbad932ae6bcfab1636e85a4463b0b5c.jar


+ 3 - 0
RedAnt Photo/bin/jarlist.cache

@@ -0,0 +1,3 @@
+# cache for current jar dependency. DO NOT EDIT.
+# format is <lastModified> <length> <SHA-1> <path>
+# Encoding is UTF-8

BIN
RedAnt Photo/bin/res/crunch/drawable-hdpi/apertureblack128.png


BIN
RedAnt Photo/bin/res/crunch/drawable-hdpi/barcode_scanner128.png


BIN
RedAnt Photo/bin/res/crunch/drawable-hdpi/camera_256.png


BIN
RedAnt Photo/bin/res/crunch/drawable-hdpi/database_upload128.png


BIN
RedAnt Photo/bin/res/crunch/drawable-hdpi/ic_launcher.png


BIN
RedAnt Photo/bin/res/crunch/drawable-hdpi/ic_shipping.png


BIN
RedAnt Photo/bin/res/crunch/drawable-hdpi/no_pic.png


BIN
RedAnt Photo/bin/res/crunch/drawable-hdpi/qr_code256.png


BIN
RedAnt Photo/bin/res/crunch/drawable-mdpi/ic_launcher.png


BIN
RedAnt Photo/bin/res/crunch/drawable-xhdpi/ic_launcher.png


BIN
RedAnt Photo/bin/res/crunch/drawable-xxhdpi/ic_launcher.png


BIN
RedAnt Photo/bin/resources.ap_


BIN
RedAnt Photo/ic_launcher-web.png


BIN
RedAnt Photo/libs/android-support-v4.jar


BIN
RedAnt Photo/libs/core-2.3.0.jar


BIN
RedAnt Photo/libs/httpmime-4.1.1.jar


+ 20 - 0
RedAnt Photo/proguard-project.txt

@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 14 - 0
RedAnt Photo/project.properties

@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-19

BIN
RedAnt Photo/res/drawable-hdpi/apertureblack128.png


BIN
RedAnt Photo/res/drawable-hdpi/barcode_scanner128.png


BIN
RedAnt Photo/res/drawable-hdpi/camera_256.png


BIN
RedAnt Photo/res/drawable-hdpi/database_upload128.png


BIN
RedAnt Photo/res/drawable-hdpi/ic_launcher.png


BIN
RedAnt Photo/res/drawable-hdpi/ic_shipping.png


+ 20 - 0
RedAnt Photo/res/drawable-hdpi/imagebutton.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true">
+           <shape android:shape="rectangle" >
+            <!-- 填充的颜色 -->
+            <solid android:color="#33C0C0C0" />
+            <!-- 设置按钮的四个角为弧形 -->
+            <!-- android:radius 弧形的半径 -->
+            <corners android:radius="15dip" />
+            <!-- padding:Button里面的文字与Button边界的间隔 -->
+            <padding android:bottom="0dp" android:left="0dp" android:right="0dp" android:top="0dp" />
+        </shape>
+    </item>
+    <item android:state_pressed="false">
+     <shape android:shape="rectangle">
+            <solid android:color="#33808080" />
+            <corners android:radius="15dip" />
+         </shape>
+    </item> 
+</selector>

BIN
RedAnt Photo/res/drawable-hdpi/no_pic.png


BIN
RedAnt Photo/res/drawable-hdpi/qr_code256.png


BIN
RedAnt Photo/res/drawable-mdpi/ic_launcher.png


BIN
RedAnt Photo/res/drawable-xhdpi/ic_launcher.png


BIN
RedAnt Photo/res/drawable-xxhdpi/ic_launcher.png


+ 89 - 0
RedAnt Photo/res/layout-land/activity_main.xml

@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <LinearLayout
+        android:id="@+id/land"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        android:visibility="visible" >
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:orientation="vertical" >
+
+            <Button
+                android:id="@+id/btnType"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="left"
+                android:layout_weight="1"
+                android:text="Type" />
+
+            <EditText
+                android:id="@+id/edit"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="left"
+                android:layout_weight="1"
+                android:editable="false"
+                android:ems="10" />
+
+            <Button
+                android:id="@+id/btnScan"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="left"
+                android:layout_weight="1"
+                android:text="Scan" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:orientation="vertical" >
+
+            <ImageView
+                android:id="@+id/ivThumbs"
+                android:layout_width="180dp"
+                android:layout_height="240dp"
+                android:layout_gravity="center_horizontal"
+                android:src="@android:drawable/ic_menu_report_image" />
+
+            <TextView
+                android:id="@+id/tvPhotoCount"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:text="no photos" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:orientation="vertical" >
+
+            <ImageButton
+                android:id="@+id/ibtnCapture"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:layout_weight="1"
+                android:src="@android:drawable/ic_menu_camera" />
+
+            <Button
+                android:id="@+id/btnOk"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:layout_weight="1"
+                android:text="OK" />
+        </LinearLayout>
+    </LinearLayout>
+</RelativeLayout>

+ 201 - 0
RedAnt Photo/res/layout-ldpi/capture.xml

@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+  <SurfaceView android:id="@+id/preview_view"
+               android:layout_width="fill_parent"
+               android:layout_height="fill_parent"/>
+
+  <com.usai.redant.photo.ViewfinderView
+      android:id="@+id/viewfinder_view"
+      android:layout_width="fill_parent"
+      android:layout_height="fill_parent"/>
+
+  <!-- <LinearLayout android:id="@+id/result_view"
+                android:orientation="vertical"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:background="@color/result_view"
+                android:visibility="gone"
+                android:baselineAligned="false">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:gravity="top"
+        android:padding="@dimen/standard_padding">
+
+      <LinearLayout
+          android:orientation="vertical"
+          android:layout_width="wrap_content"
+          android:layout_height="fill_parent"
+          android:gravity="right">
+
+        <ImageView android:id="@+id/barcode_image_view"
+                   android:layout_width="150dip"
+                   android:layout_height="wrap_content"
+                   android:maxWidth="150dip"
+                   android:maxHeight="150dip"
+                   android:layout_marginBottom="@dimen/half_padding"
+                   android:adjustViewBounds="true"
+                   android:scaleType="centerInside"/>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_format"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/format_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_type"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/type_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_time"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/time_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:id="@+id/meta_text_view_label"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_meta"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/meta_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+      </LinearLayout>
+
+      <ScrollView
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content">
+
+        <LinearLayout
+          android:orientation="vertical"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:id="@+id/contents_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_text"
+                    android:textColorLink="@color/result_text"
+                    android:textSize="22sp"
+                    android:paddingLeft="12dip"
+                    android:autoLink="web"/>
+
+          <TextView android:id="@+id/contents_supplement_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_text"
+                    android:textColorLink="@color/result_text"
+                    android:paddingLeft="12dip"
+                    android:autoLink="web"
+                    android:clickable="true"/>
+
+        </LinearLayout>
+
+      </ScrollView>
+
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/result_button_view"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center">
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+    </LinearLayout>
+
+  </LinearLayout> -->
+
+  <TextView android:id="@+id/status_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|center_horizontal"
+            android:background="@color/transparent"
+            android:text="@string/msg_default_status"
+            android:textColor="@color/status_text"/>
+
+</merge>

+ 75 - 0
RedAnt Photo/res/layout-port/activity_main.xml

@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+<LinearLayout
+    android:id="@+id/port"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:visibility="visible" >
+
+    <ImageView
+        android:id="@+id/ivThumbs"
+        android:layout_width="180dp"
+        android:layout_height="240dp"
+        android:layout_gravity="center_horizontal"
+        android:src="@android:drawable/ic_menu_report_image" />
+
+      <TextView
+        android:id="@+id/tvPhotoCount"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:text="no photos" />
+    
+
+    <ImageButton
+        android:id="@+id/ibtnCapture"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:src="@android:drawable/ic_menu_camera" />
+
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <Button
+            android:id="@+id/btnType"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="Type" />
+
+        <Button
+            android:id="@+id/btnScan"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="Scan" />
+
+    </LinearLayout>
+
+    <EditText
+        android:id="@+id/edit"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:editable="false"
+        android:ems="10" >
+
+        <requestFocus />
+    </EditText>
+
+    <Button
+        android:id="@+id/btnOK"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="OK" 
+        android:layout_gravity="center_horizontal"/>
+
+</LinearLayout>
+</RelativeLayout>

+ 76 - 0
RedAnt Photo/res/layout/activity_locker.xml

@@ -0,0 +1,76 @@
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".LockerActivity" >
+
+    <!-- Login progress -->
+
+    <LinearLayout
+        android:id="@+id/login_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:gravity="center_horizontal"
+        android:orientation="vertical"
+        android:visibility="gone" >
+
+        <ProgressBar
+            style="?android:attr/progressBarStyleLarge"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="8dp" />
+
+        <TextView
+            android:id="@+id/login_status_message"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="16dp"
+            android:fontFamily="sans-serif-light"
+            android:text="@string/login_progress_signing_in"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+    </LinearLayout>
+
+    <!-- Login form -->
+
+    <ScrollView
+        android:id="@+id/login_form"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" >
+
+        <LinearLayout
+            style="@style/LoginFormContainer"
+            android:orientation="vertical" >
+
+            <EditText
+                android:id="@+id/name"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="@string/prompt_Name"
+                android:inputType="textAutoComplete"
+                android:maxLines="1"
+                android:singleLine="true" />
+
+            <EditText
+                android:id="@+id/password"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="@string/prompt_password"
+                android:imeActionId="@+id/locker"
+                android:imeActionLabel="@string/action_sign_in_short"
+                android:imeOptions="actionUnspecified"
+                android:inputType="textPassword"
+                android:maxLines="1"
+                android:singleLine="true" />
+
+            <Button
+                android:id="@+id/sign_in_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:layout_marginTop="16dp"
+                android:paddingLeft="32dp"
+                android:paddingRight="32dp"
+                android:text="@string/action_sign_in_register" />
+        </LinearLayout>
+    </ScrollView>
+
+</merge>

+ 76 - 0
RedAnt Photo/res/layout/activity_login.xml

@@ -0,0 +1,76 @@
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".LoginActivity" >
+
+    <!-- Login progress -->
+
+    <LinearLayout
+        android:id="@+id/login_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:gravity="center_horizontal"
+        android:orientation="vertical"
+        android:visibility="gone" >
+
+        <ProgressBar
+            style="?android:attr/progressBarStyleLarge"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="8dp" />
+
+        <TextView
+            android:id="@+id/login_status_message"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="16dp"
+            android:fontFamily="sans-serif-light"
+            android:text="@string/login_progress_signing_in"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+    </LinearLayout>
+
+    <!-- Login form -->
+
+    <ScrollView
+        android:id="@+id/login_form"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" >
+
+        <LinearLayout
+            style="@style/LoginFormContainer"
+            android:orientation="vertical" >
+
+            <EditText
+                android:id="@+id/name"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="@string/prompt_Name"
+                android:inputType="textAutoComplete"
+                android:maxLines="1"
+                android:singleLine="true" />
+
+            <EditText
+                android:id="@+id/password"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="@string/prompt_password"
+                android:imeActionId="@+id/login"
+                android:imeActionLabel="@string/action_sign_in_short"
+                android:imeOptions="actionUnspecified"
+                android:inputType="textPassword"
+                android:maxLines="1"
+                android:singleLine="true" />
+
+            <Button
+                android:id="@+id/sign_in_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:layout_marginTop="16dp"
+                android:paddingLeft="32dp"
+                android:paddingRight="32dp"
+                android:text="@string/action_sign_in_register" />
+        </LinearLayout>
+    </ScrollView>
+
+</merge>

+ 115 - 0
RedAnt Photo/res/layout/activity_main1.xml

@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <RelativeLayout
+        android:id="@+id/rlside"
+        android:layout_width="wrap_content"
+        android:layout_height="fill_parent"
+        android:layout_alignParentRight="true"
+        android:layout_marginRight="0dp"
+        android:layout_marginTop="40dp"
+        android:orientation="vertical" >
+
+        <ImageButton
+            android:id="@+id/ibtnCapture"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:layout_weight="1"
+            android:background="@drawable/imagebutton"
+            android:padding="0dp"
+            android:src="@drawable/apertureblack128" />
+
+        <ImageButton
+            android:id="@+id/ibtnOk"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:layout_weight="1"
+            android:background="@drawable/imagebutton"
+            android:padding="0dp"
+            android:src="@drawable/database_upload128"
+            android:text="Scan"
+            android:visibility="invisible" />
+
+        <ImageButton
+            android:id="@+id/ibtnScan"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_weight="1"
+            android:background="@drawable/imagebutton"
+            android:padding="0dp"
+            android:src="@drawable/barcode_scanner128"
+            android:text="Scan" />
+    </RelativeLayout>
+
+    <LinearLayout
+        android:id="@+id/linearLayout1"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_marginBottom="0dp"
+        android:layout_toLeftOf="@+id/rlside" >
+
+        <TextView
+            android:id="@+id/tvPhotoCount"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:layout_weight="1"
+            android:gravity="center_horizontal"
+            android:text="no photo"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
+
+        <TextView
+            android:id="@+id/textView1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:layout_weight="0.1"
+            android:gravity="right"
+            android:text="PID:"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
+
+        <EditText
+            android:id="@+id/edit"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:ems="8" >
+
+            <requestFocus />
+        </EditText>
+    </LinearLayout>
+
+    <ImageView
+        android:id="@+id/ivThumbs"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_above="@+id/linearLayout1"
+        android:layout_alignParentTop="true"
+        android:layout_marginTop="45dp"
+        android:layout_toLeftOf="@+id/rlside"
+        android:paddingLeft="10dp"
+        android:paddingRight="10dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/no_pic" />
+
+    <TextView
+        android:id="@+id/tvalert"
+        android:layout_width="290dp"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_alignRight="@+id/ivThumbs"
+        android:layout_marginRight="5dp"
+        android:layout_marginTop="5dp"
+        android:ellipsize="marquee"
+        android:singleLine="true"
+        android:text=""
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textColor="#eeff0000" />
+
+</RelativeLayout>

+ 208 - 0
RedAnt Photo/res/layout/capture.xml

@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+  <SurfaceView android:id="@+id/preview_view"
+               android:layout_width="fill_parent"
+               android:layout_height="fill_parent"/>
+
+  <com.usai.redant.photo.ViewfinderView
+      android:id="@+id/viewfinder_view"
+      android:layout_width="fill_parent"
+      android:layout_height="fill_parent"/>
+
+  <!-- <LinearLayout android:id="@+id/result_view"
+                android:orientation="vertical"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:background="@color/result_view"
+                android:visibility="gone"
+                android:baselineAligned="false">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:padding="@dimen/standard_padding">
+
+      <LinearLayout
+          android:orientation="vertical"
+          android:layout_width="wrap_content"
+          android:layout_height="fill_parent"
+          android:gravity="right|center_vertical">
+
+        <ImageView android:id="@+id/barcode_image_view"
+                   android:layout_width="160dip"
+                   android:layout_height="wrap_content"
+                   android:maxWidth="160dip"
+                   android:maxHeight="160dip"
+                   android:layout_marginBottom="@dimen/half_padding"
+                   android:adjustViewBounds="true"
+                   android:scaleType="centerInside"/>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_format"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/format_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_type"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/type_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_time"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/time_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:id="@+id/meta_text_view_label"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_meta"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/meta_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+      </LinearLayout>
+
+      <ScrollView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+        <LinearLayout
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:orientation="vertical">
+
+          <TextView android:id="@+id/contents_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_text"
+                    android:textColorLink="@color/result_text"
+                    android:textSize="22sp"
+                    android:paddingLeft="12dip"
+                    android:autoLink="web"/>
+
+          <TextView android:id="@+id/contents_supplement_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_text"
+                    android:textColorLink="@color/result_text"
+                    android:paddingLeft="12dip"
+                    android:autoLink="web"/>
+
+        </LinearLayout>
+
+      </ScrollView>
+
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/result_button_view"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="horizontal"
+                  android:gravity="center">
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+    </LinearLayout>
+
+  </LinearLayout> -->
+
+  <TextView android:id="@+id/status_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|center_horizontal"
+            android:background="@color/transparent"
+            android:text="@string/msg_default_status"
+            android:textColor="@color/status_text"/>
+
+  <TextView
+      android:id="@+id/textView1"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:text="Large Text"
+      android:layout_gravity="center_horizontal"
+      android:textAppearance="?android:attr/textAppearanceLarge" />
+
+</merge>

+ 21 - 0
RedAnt Photo/res/layout/help.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<WebView xmlns:android="http://schemas.android.com/apk/res/android"
+         android:id="@+id/help_contents"
+         android:layout_width="fill_parent"
+         android:layout_height="fill_parent"
+         android:layout_weight="1"/>

+ 26 - 0
RedAnt Photo/res/layout/temp.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <Button
+        android:id="@+id/button1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="88dp"
+        android:text="Button" />
+
+    <Button
+        android:id="@+id/button2"
+        style="?android:attr/buttonStyleInset"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/button1"
+        android:layout_marginTop="49dp"
+        android:layout_toRightOf="@+id/button1"
+        android:text="Button" />
+
+</RelativeLayout>

+ 38 - 0
RedAnt Photo/res/menu/capture.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<!--   <item android:id="@+id/menu_share"
+        android:title="@string/menu_share"
+        android:icon="@android:drawable/ic_menu_share"
+        android:orderInCategory="1"
+        android:showAsAction="withText|ifRoom"/>
+  <item android:id="@+id/menu_history"
+        android:title="@string/menu_history"
+        android:icon="@android:drawable/ic_menu_recent_history"
+        android:orderInCategory="2"
+        android:showAsAction="withText|ifRoom"/> -->
+  <item android:id="@+id/menu_settings"
+        android:title="@string/menu_settings"
+        android:icon="@android:drawable/ic_menu_preferences"
+        android:orderInCategory="3"
+        android:showAsAction="withText"/>
+  <item android:id="@+id/menu_help"
+        android:title="@string/menu_help"
+        android:icon="@android:drawable/ic_menu_help"
+        android:orderInCategory="4"
+        android:showAsAction="withText"/>
+</menu>

+ 8 - 0
RedAnt Photo/res/menu/locker.xml

@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_forgot_password"
+        android:showAsAction="never"
+        android:title="@string/action_forgot_password"/>
+
+</menu>

+ 8 - 0
RedAnt Photo/res/menu/login.xml

@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_forgot_password"
+        android:showAsAction="never"
+        android:title="@string/action_forgot_password"/>
+
+</menu>

+ 13 - 0
RedAnt Photo/res/menu/main.xml

@@ -0,0 +1,13 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_settings"
+       
+        android:showAsAction="never"
+        android:title="@string/action_settings"/>
+    <item
+        android:id="@+id/action_orientation"
+       
+        android:showAsAction="never"
+        android:title="@string/action_orientation"/>
+</menu>

+ 9 - 0
RedAnt Photo/res/menu/main_activity1.xml

@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="@string/action_settings"/>
+
+</menu>

BIN
RedAnt Photo/res/raw/beep.ogg


+ 10 - 0
RedAnt Photo/res/values-large/styles.xml

@@ -0,0 +1,10 @@
+<resources>
+
+    <style name="LoginFormContainer">
+        <item name="android:layout_width">400dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_gravity">center</item>
+        <item name="android:padding">16dp</item>
+    </style>
+
+</resources>

+ 8 - 0
RedAnt Photo/res/values-sw600dp/dimens.xml

@@ -0,0 +1,8 @@
+<resources>
+
+    <!--
+         Customize dimensions originally defined in res/values/dimens.xml (such as
+         screen margins) for sw600dp devices (e.g. 7" tablets) here.
+    -->
+
+</resources>

+ 9 - 0
RedAnt Photo/res/values-sw720dp-land/dimens.xml

@@ -0,0 +1,9 @@
+<resources>
+
+    <!--
+         Customize dimensions originally defined in res/values/dimens.xml (such as
+         screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
+    -->
+    <dimen name="activity_horizontal_margin">128dp</dimen>
+
+</resources>

+ 11 - 0
RedAnt Photo/res/values-v11/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>

+ 12 - 0
RedAnt Photo/res/values-v14/styles.xml

@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>

+ 47 - 0
RedAnt Photo/res/values/arrays.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+  <string-array name="country_codes">
+    <item>-</item>
+    <item>AR</item>
+    <item>AU</item>
+    <item>BR</item>
+    <item>BG</item>
+    <item>CA</item>
+    <item>CH</item>
+    <item>CN</item>
+    <item>CZ</item>
+    <item>DE</item>
+    <item>DK</item>
+    <item>ES</item>
+    <item>FI</item>
+    <item>FR</item>
+    <item>GB</item>
+    <item>GR</item>
+    <item>HU</item>
+    <item>ID</item>
+    <item>IT</item>
+    <item>JP</item>
+    <item>KR</item>
+    <item>NL</item>
+    <item>PL</item>
+    <item>PT</item>
+    <item>RO</item>    
+    <item>RU</item>
+    <item>SE</item>
+    <item>SK</item>
+    <item>SI</item>
+    <item>TR</item>
+    <item>TW</item>
+    <item>US</item>
+  </string-array>
+  <string-array name="preferences_front_light_values">
+    <item>ON</item>
+    <item>AUTO</item>
+    <item>OFF</item>
+  </string-array>
+  <string-array name="preferences_front_light_options">
+    <item>@string/preferences_front_light_on</item>
+    <item>@string/preferences_front_light_auto</item>
+    <item>@string/preferences_front_light_off</item>
+  </string-array>
+</resources>

+ 48 - 0
RedAnt Photo/res/values/colors.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<resources>
+
+    <color name="transparent_background">#50000000</color>
+
+    <color name="message_success">#ee00ff00</color>
+    <color name="message_fail">#eeff0000</color>
+<!--
+  <color name="contents_text">#ff000000</color>
+  <color name="encode_view">#ffffffff</color>
+-->
+<color name="possible_result_points">
+#c0ffbd21
+</color> <!-- Android standard ICS color -->
+<!-- <color name="result_minor_text">#ffc0c0c0</color> -->
+<color name="result_points">
+#c099cc00
+</color> <!-- Android standard ICS color -->
+<!-- <color name="result_text">#ffffffff</color> -->
+<color name="result_view">
+#b0000000
+</color><color name="status_text">
+#ffffffff
+</color><color name="transparent">
+#00000000
+</color><color name="viewfinder_laser">
+#ffcc0000
+</color> <!-- Android standard ICS color -->
+<color name="viewfinder_mask">
+#60000000
+</color>
+
+</resources>

+ 11 - 0
RedAnt Photo/res/values/dimens.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+    
+    <!-- Used by CaptureActivity. -->
+    <dimen name="standard_padding">8dip</dimen>
+    <dimen name="half_padding">4dip</dimen>
+
+</resources>

+ 25 - 0
RedAnt Photo/res/values/ids.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<resources>
+  <item type="id" name="decode"/>
+  <item type="id" name="decode_failed"/>
+  <item type="id" name="decode_succeeded"/>
+  <item type="id" name="launch_product_query"/>
+  <item type="id" name="quit"/>
+  <item type="id" name="restart_preview"/>
+  <item type="id" name="return_scan_result"/>
+</resources>

+ 66 - 0
RedAnt Photo/res/values/strings.xml

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+   <string name="title_activity_login">Sign in</string>
+   <string name="title_activity_locker">Unlock App</string>
+
+    <!-- Strings related to login -->
+    <string name="prompt_email">Email</string>
+    <string name="prompt_Name">Name</string>
+    <string name="prompt_password">Password</string>
+    <string name="action_sign_in_register"><b>Sign in</b> or register</string>
+    <string name="action_sign_in_short">Sign in</string>
+    <string name="action_forgot_password">Recover lost password</string>
+    <string name="login_progress_signing_in">Signing in&#8230;</string>
+    <string name="error_invalid_email">This email address is invalid</string>
+    <string name="error_invalid_password">This password is too short</string>
+    <string name="error_incorrect_password">Not authorized or wrong password</string>
+    <string name="error_field_required">This field is required</string>
+    <string name="action_settings">Settings</string>
+    <string name="action_orientation">Change Orientation</string>
+    <string name="preferences_name">Settings</string>
+    <string name="app_name">RedAnt Photo</string>
+    <string name="button_ok">OK</string>
+    <string name="title_activity_scan">ScanActivity</string>
+    <string name="menu_help">Help</string>
+    <string name="menu_settings">Settings</string>
+    <string name="msg_camera_framework_bug">Sorry, the Android camera encountered a problem. You may need to restart the device.</string>
+    <string name="msg_default_status">Place a barcode inside the viewfinder rectangle to scan it.</string>
+    <string name="msg_net_resulterror">An error occur on server</string>
+    <string name="msg_net_error">Can not connect to server</string>
+    <string name="msg_connection_none">No available connection </string>
+    <string name="preferences_actions_title">When a barcode is found\u2026</string>
+    <string name="preferences_auto_focus_title">Use auto focus</string>
+    <string name="preferences_bulk_mode_summary">Scan and save many barcodes continuously</string>
+    <string name="preferences_bulk_mode_title">Bulk scan mode</string>
+    <string name="preferences_copy_to_clipboard_title">Copy to clipboard</string>
+    <string name="preferences_custom_product_search_summary" formatted="false">Substitutions: %s = contents, %f = format, %t = type</string>
+    <string name="preferences_custom_product_search_title">Custom search URL</string>
+    <string name="preferences_decode_1D_title">1D barcodes</string>
+    <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+    <string name="preferences_decode_QR_title">QR Codes</string>
+    <string name="preferences_device_bug_workarounds_title">Device Bug Workarounds</string>
+    <string name="preferences_disable_continuous_focus_summary">Use only standard focus mode</string>
+    <string name="preferences_disable_continuous_focus_title">No continuous focus</string>
+    <string name="preferences_front_light_summary">Improves scanning in low light on some phones, but may cause glare. Does not work on all phones.</string>
+    <string name="preferences_front_light_title">Use front light</string>
+    <string name="preferences_front_light_auto">Automatic</string>
+    <string name="preferences_front_light_off">Off</string>
+    <string name="preferences_front_light_on">On</string>
+    <string name="preferences_general_title">General settings</string>
+    <string name="preferences_invert_scan_title">Invert scan</string>
+    <string name="preferences_invert_scan_summary">Scan for white barcodes on black background. Not available on some devices.</string>
+    <string name="preferences_play_beep_title">Beep</string>
+    <string name="preferences_remember_duplicates_summary">Store multiple scans of the same barcode in History</string>
+    <string name="preferences_remember_duplicates_title">Remember duplicates</string>
+    <string name="preferences_result_title">Result settings</string>
+    <string name="preferences_scanning_title">When scanning for barcodes, decode\u2026</string>
+    <string name="preferences_search_country">Search country</string>
+    <string name="preferences_try_bsplus">Try Barcode Scanner+</string>
+    <string name="preferences_try_bsplus_summary">Enhanced with new features and interface</string>
+    <string name="preferences_supplemental_summary">Try to retrieve more information about the barcode contents</string>
+    <string name="preferences_supplemental_title">Retrieve more info</string>
+    <string name="preferences_vibrate_title">Vibrate</string>
+    <string name="title_activity_main_activity1">MainActivity1</string>
+    <string name="hello_world">Hello world!</string>
+
+</resources>

+ 51 - 0
RedAnt Photo/res/values/styles.xml

@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.

+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.

+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="android:Theme.Holo">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+        <item name="android:windowFullscreen">true</item>
+    </style>
+
+    <!-- used by CaptureActivity. -->
+
+    <style name="ResultButton" parent="@android:style/Widget.Holo.Button.Borderless.Small">
+        <item name="android:layout_width">0dip</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_weight">1</item>
+    </style>
+
+    <style name="ShareButton" parent="@android:style/Widget.Holo.Button.Borderless.Small">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+    </style>
+
+    <style name="LoginFormContainer">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:padding">16dp</item>
+    </style>
+
+<style name="TransparentBG">  
+    <item name="android:windowBackground">
+       @color/transparent_background
+    </item>  
+    <item name="android:windowNoTitle">true</item>  
+    <item name="android:windowIsTranslucent">true</item>    
+    <item name="android:windowAnimationStyle">
+         @+android:style/Animation.Translucent
+   </item>  
+  </style>  
+</resources>

+ 24 - 0
RedAnt Photo/res/values/themes.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<resources>
+  <style name="CaptureTheme" parent="android:Theme.Holo">
+    <item name="android:windowFullscreen">true</item>
+    <item name="android:windowContentOverlay">@null</item>
+    <item name="android:windowActionBarOverlay">true</item>
+    <item name="android:windowActionModeOverlay">true</item>
+  </style>
+</resources>

+ 110 - 0
RedAnt Photo/res/xml/preferences.xml

@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+  <PreferenceCategory android:title="@string/preferences_scanning_title">
+    <CheckBoxPreference
+        android:key="preferences_decode_1D"
+        android:defaultValue="true"
+        android:title="@string/preferences_decode_1D_title"/>
+    <CheckBoxPreference
+        android:key="preferences_decode_QR"
+        android:defaultValue="true"
+        android:title="@string/preferences_decode_QR_title"/>
+    <CheckBoxPreference
+        android:key="preferences_decode_Data_Matrix"
+        android:defaultValue="true"
+        android:title="@string/preferences_decode_Data_Matrix_title"/>
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_actions_title">
+    <CheckBoxPreference
+        android:key="preferences_play_beep"
+        android:defaultValue="true"
+        android:title="@string/preferences_play_beep_title"/>
+    <CheckBoxPreference
+        android:key="preferences_vibrate"
+        android:defaultValue="false"
+        android:title="@string/preferences_vibrate_title"/>
+    <CheckBoxPreference
+        android:key="preferences_copy_to_clipboard"
+        android:defaultValue="true"
+        android:title="@string/preferences_copy_to_clipboard_title"/>
+    <CheckBoxPreference
+        android:key="preferences_remember_duplicates"
+        android:defaultValue="false"
+        android:title="@string/preferences_remember_duplicates_title"
+        android:summary="@string/preferences_remember_duplicates_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_supplemental"
+        android:defaultValue="true"
+        android:title="@string/preferences_supplemental_title"
+        android:summary="@string/preferences_supplemental_summary"/>
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_result_title">
+    <EditTextPreference
+        android:key="preferences_custom_product_search"
+        android:title="@string/preferences_custom_product_search_title"
+        android:summary="@string/preferences_custom_product_search_summary"/>
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_general_title">
+    <ListPreference
+        android:entries="@array/preferences_front_light_options"
+        android:entryValues="@array/preferences_front_light_values"
+        android:key="preferences_front_light_mode"
+        android:defaultValue="OFF"
+        android:title="@string/preferences_front_light_title"
+        android:summary="@string/preferences_front_light_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_auto_focus"
+        android:defaultValue="true"
+        android:title="@string/preferences_auto_focus_title"/>
+    <CheckBoxPreference
+        android:key="preferences_invert_scan"
+        android:defaultValue="false"
+        android:title="@string/preferences_invert_scan_title"
+        android:summary="@string/preferences_invert_scan_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_bulk_mode"
+        android:defaultValue="false"
+        android:title="@string/preferences_bulk_mode_title"
+        android:summary="@string/preferences_bulk_mode_summary"/>
+    <ListPreference
+        android:key="preferences_search_country"
+        android:defaultValue="-"
+        android:entries="@array/country_codes"
+        android:entryValues="@array/country_codes"
+        android:title="@string/preferences_search_country"/>
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_device_bug_workarounds_title">
+    <CheckBoxPreference
+        android:key="preferences_disable_continuous_focus"
+        android:defaultValue="true"
+        android:title="@string/preferences_disable_continuous_focus_title"
+        android:summary="@string/preferences_disable_continuous_focus_summary"/>
+    <!--
+    <CheckBoxPreference
+        android:key="preferences_disable_exposure"
+        android:defaultValue="false"
+        android:title="@string/preferences_disable_exposure_title"/>
+     -->
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_try_bsplus">
+    <Preference android:title="@string/preferences_try_bsplus"
+                android:summary="@string/preferences_try_bsplus_summary">
+      <intent android:action="android.intent.action.VIEW" android:data="market://details?id=com.srowen.bs.android" />
+    </Preference>
+  </PreferenceCategory>
+</PreferenceScreen>

+ 112 - 0
RedAnt Photo/src/com/usai/redant/camera/AutoFocusManager.java

@@ -0,0 +1,112 @@
+/*
+ * 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.usai.redant.camera;
+
+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 java.util.ArrayList;
+import java.util.Collection;
+
+import com.usai.redant.photo.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<String>(2);
+    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO);
+    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO);
+  }
+
+  private boolean active;
+  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) {
+    if (active) {
+      outstandingTask = new AutoFocusTask();
+      outstandingTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+  }
+
+  synchronized void start() {
+    if (useAutoFocus) {
+      active = true;
+      try {
+        camera.autoFocus(this);
+      } catch (RuntimeException re) {
+        // Have heard RuntimeException reported in Android 4.0.x+; continue?
+        Log.w(TAG, "Unexpected exception while focusing", re);
+      }
+    }
+  }
+
+  synchronized void stop() {
+    if (useAutoFocus) {
+      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);
+      }
+    }
+    if (outstandingTask != null) {
+      outstandingTask.cancel(true);
+      outstandingTask = null;
+    }
+    active = false;
+  }
+
+  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
+      }
+      synchronized (AutoFocusManager.this) {
+        if (active) {
+          start();
+        }
+      }
+      return null;
+    }
+  }
+
+}

+ 307 - 0
RedAnt Photo/src/com/usai/redant/camera/CameraConfigurationManager.java

@@ -0,0 +1,307 @@
+/*
+ * 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.usai.redant.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.WindowManager;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import com.usai.redant.photo.PreferencesActivity;
+
+/**
+ * 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";
+
+  // This is bigger than the size of a small screen, which is still supported. The routine
+  // below will still select the default (presumably 320x240) size for these. This prevents
+  // accidental selection of very low resolution on some devices.
+  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 final Context context;
+  private Point screenResolution;
+  private Point cameraResolution;
+
+  CameraConfigurationManager(Context context) {
+    this.context = context;
+  }
+
+  /**
+   * Reads, one time, values from the camera that are needed by the app.
+   */
+  void initFromCameraParameters(Camera camera) {
+    Camera.Parameters parameters = camera.getParameters();
+    WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+    Display display = manager.getDefaultDisplay();
+    Point theScreenResolution = new Point();
+    display.getSize(theScreenResolution);
+    screenResolution = theScreenResolution;
+    Log.i(TAG, "Screen resolution: " + screenResolution);
+    cameraResolution = findBestPreviewSizeValue(parameters, screenResolution);
+    Log.i(TAG, "Camera resolution: " + cameraResolution);
+  }
+
+  void setDesiredCameraParameters(Camera camera, boolean safeMode) {
+    Camera.Parameters parameters = camera.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);
+
+    String focusMode = null;
+    if (prefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true)) {
+      if (safeMode || prefs.getBoolean(PreferencesActivity.KEY_DISABLE_CONTINUOUS_FOCUS, false)) {
+        focusMode = findSettableValue(parameters.getSupportedFocusModes(),
+                                      Camera.Parameters.FOCUS_MODE_AUTO);
+      } else {
+        focusMode = findSettableValue(parameters.getSupportedFocusModes(),
+                                      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(parameters.getSupportedFocusModes(),
+                                    Camera.Parameters.FOCUS_MODE_MACRO,
+                                    Camera.Parameters.FOCUS_MODE_EDOF);
+    }
+    if (focusMode != null) {
+      parameters.setFocusMode(focusMode);
+    }
+
+    if (prefs.getBoolean(PreferencesActivity.KEY_INVERT_SCAN, false)) {
+      String colorMode = findSettableValue(parameters.getSupportedColorEffects(),
+                                           Camera.Parameters.EFFECT_NEGATIVE);
+      if (colorMode != null) {
+        parameters.setColorEffect(colorMode);
+      }
+    }
+
+    parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
+    camera.setParameters(parameters);
+
+    Camera.Parameters afterParameters = camera.getParameters();
+    Camera.Size afterSize = afterParameters.getPreviewSize();
+    if (afterSize!= null && (cameraResolution.x != afterSize.width || cameraResolution.y != afterSize.height)) {
+      Log.w(TAG, "Camera said it supported preview size " + cameraResolution.x + 'x' + cameraResolution.y +
+                 ", but after setting it, preview size is " + afterSize.width + 'x' + afterSize.height);
+      cameraResolution.x = afterSize.width;
+      cameraResolution.y = afterSize.height;
+    }
+  }
+
+  Point getCameraResolution() {
+    return cameraResolution;
+  }
+
+  Point getScreenResolution() {
+    return screenResolution;
+  }
+
+  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) {
+    String flashMode;
+    if (newSetting) {
+      flashMode = findSettableValue(parameters.getSupportedFlashModes(),
+                                    Camera.Parameters.FLASH_MODE_TORCH,
+                                    Camera.Parameters.FLASH_MODE_ON);
+    } else {
+      flashMode = findSettableValue(parameters.getSupportedFlashModes(),
+                                    Camera.Parameters.FLASH_MODE_OFF);
+    }
+    if (flashMode != null) {
+      parameters.setFlashMode(flashMode);
+    }
+
+    /*
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+    if (!prefs.getBoolean(PreferencesActivity.KEY_DISABLE_EXPOSURE, false)) {
+      if (!safeMode) {
+        int minExposure = parameters.getMinExposureCompensation();
+        int maxExposure = parameters.getMaxExposureCompensation();
+        if (minExposure != 0 || maxExposure != 0) {
+          float step = parameters.getExposureCompensationStep();
+          int desiredCompensation;
+          if (newSetting) {
+            // Light on; set low exposue compensation
+            desiredCompensation = Math.max((int) (MIN_EXPOSURE_COMPENSATION / step), minExposure);
+          } else {
+            // Light off; set high compensation
+            desiredCompensation = Math.min((int) (MAX_EXPOSURE_COMPENSATION / step), maxExposure);
+          }
+          Log.i(TAG, "Setting exposure compensation to " + desiredCompensation + " / " + (step * desiredCompensation));
+          parameters.setExposureCompensation(desiredCompensation);
+        } else {
+          Log.i(TAG, "Camera does not support exposure compensation");
+        }
+      }
+    }
+     */
+  }
+
+  private 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();
+      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();
+    Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
+    Log.i(TAG, "No suitable preview sizes, using default: " + defaultSize);
+    return defaultSize;
+  }
+
+  private static String findSettableValue(Collection<String> supportedValues,
+                                          String... desiredValues) {
+    Log.i(TAG, "Supported values: " + supportedValues);
+    String result = null;
+    if (supportedValues != null) {
+      for (String desiredValue : desiredValues) {
+        if (supportedValues.contains(desiredValue)) {
+          result = desiredValue;
+          break;
+        }
+      }
+    }
+    Log.i(TAG, "Settable value: " + result);
+    return result;
+  }
+
+}

+ 311 - 0
RedAnt Photo/src/com/usai/redant/camera/CameraManager.java

@@ -0,0 +1,311 @@
+/*
+ * 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.usai.redant.camera;
+
+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.usai.redant.camera.open.OpenCameraInterface;
+
+import java.io.IOException;
+
+/**
+ * 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 Camera camera;
+  private AutoFocusManager autoFocusManager;
+  private Rect framingRect;
+  private Rect framingRectInPreview;
+  private boolean initialized;
+  private boolean previewing;
+  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 {
+    Camera theCamera = camera;
+    if (theCamera == null) {
+      theCamera = OpenCameraInterface.open();
+      if (theCamera == null) {
+        throw new IOException();
+      }
+      camera = theCamera;
+    }
+    theCamera.setPreviewDisplay(holder);
+
+    if (!initialized) {
+      initialized = true;
+      configManager.initFromCameraParameters(theCamera);
+      if (requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) {
+        setManualFramingRect(requestedFramingRectWidth, requestedFramingRectHeight);
+        requestedFramingRectWidth = 0;
+        requestedFramingRectHeight = 0;
+      }
+    }
+
+    Camera.Parameters parameters = theCamera.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 = theCamera.getParameters();
+        parameters.unflatten(parametersFlattened);
+        try {
+          theCamera.setParameters(parameters);
+          configManager.setDesiredCameraParameters(theCamera, true);
+        } catch (RuntimeException re2) {
+          // Well, darn. Give up
+          Log.w(TAG, "Camera rejected even safe-mode parameters! No configuration");
+        }
+      }
+    }
+
+  }
+
+  public synchronized boolean isOpen() {
+    return camera != null;
+  }
+
+  /**
+   * Closes the camera driver if still in use.
+   */
+  public synchronized void closeDriver() {
+    if (camera != null) {
+      camera.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() {
+    Camera theCamera = camera;
+    if (theCamera != null && !previewing) {
+      theCamera.startPreview();
+      previewing = true;
+      autoFocusManager = new AutoFocusManager(context, camera);
+    }
+  }
+
+  /**
+   * Tells the camera to stop drawing preview frames.
+   */
+  public synchronized void stopPreview() {
+    if (autoFocusManager != null) {
+      autoFocusManager.stop();
+      autoFocusManager = null;
+    }
+    if (camera != null && previewing) {
+      camera.stopPreview();
+      previewCallback.setHandler(null, 0);
+      previewing = false;
+    }
+  }
+
+  /**
+   * Convenience method for {@link com.usai.test1.android.CaptureActivity}
+   */
+  public synchronized void setTorch(boolean newSetting) {
+    if (newSetting != configManager.getTorchState(camera)) {
+      if (camera != null) {
+        if (autoFocusManager != null) {
+          autoFocusManager.stop();
+        }
+        configManager.setTorch(camera, newSetting);
+        if (autoFocusManager != null) {
+          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) {
+    Camera theCamera = camera;
+    if (theCamera != null && previewing) {
+      previewCallback.setHandler(handler, message);
+      theCamera.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.
+   */
+  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;
+      framingRectInPreview = rect;
+    }
+    return framingRectInPreview;
+  }
+
+  /**
+   * 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);
+  }
+
+}

+ 43 - 0
RedAnt Photo/src/com/usai/redant/camera/FrontLightMode.java

@@ -0,0 +1,43 @@
+/*
+ * 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.usai.redant.camera;
+
+import com.usai.redant.photo.PreferencesActivity;
+
+import android.content.SharedPreferences;
+
+/**
+ * Enumerates settings of the prefernce 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, null));
+  }
+
+}

+ 56 - 0
RedAnt Photo/src/com/usai/redant/camera/PreviewCallback.java

@@ -0,0 +1,56 @@
+/*
+ * 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.usai.redant.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");
+    }
+  }
+
+}

+ 62 - 0
RedAnt Photo/src/com/usai/redant/camera/open/OpenCameraInterface.java

@@ -0,0 +1,62 @@
+/*
+ * 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.usai.redant.camera.open;
+
+import android.hardware.Camera;
+import android.util.Log;
+
+public final class OpenCameraInterface {
+
+  private static final String TAG = OpenCameraInterface.class.getName();
+
+  private OpenCameraInterface() {
+  }
+
+  /**
+   * Opens a rear-facing camera with {@link Camera#open(int)}, if one exists, or opens camera 0.
+   */
+  public static Camera open() {
+    
+    int numCameras = Camera.getNumberOfCameras();
+    if (numCameras == 0) {
+      Log.w(TAG, "No cameras!");
+      return null;
+    }
+
+    int index = 0;
+    while (index < numCameras) {
+      Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+      Camera.getCameraInfo(index, cameraInfo);
+      if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
+        break;
+      }
+      index++;
+    }
+    
+    Camera camera;
+    if (index < numCameras) {
+      Log.i(TAG, "Opening camera #" + index);
+      camera = Camera.open(index);
+    } else {
+      Log.i(TAG, "No camera facing back; returning camera #0");
+      camera = Camera.open(0);
+    }
+
+    return camera;
+  }
+
+}

+ 87 - 0
RedAnt Photo/src/com/usai/redant/photo/AmbientLightManager.java

@@ -0,0 +1,87 @@
+/*
+ * 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.usai.redant.photo;
+
+import com.usai.redant.camera.CameraManager;
+import com.usai.redant.camera.FrontLightMode;
+
+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;
+
+/**
+ * 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
+  }
+
+}

+ 128 - 0
RedAnt Photo/src/com/usai/redant/photo/BeepManager.java

@@ -0,0 +1,128 @@
+/*
+ * 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.usai.redant.photo;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.AssetFileDescriptor;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.Vibrator;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Manages beeps and vibrations for {@link CaptureActivity}.
+ */
+final class BeepManager implements MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
+
+  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() {
+	  Log.i(TAG,"playBeep=========>"+playBeep);
+	  Log.i(TAG,"mediaPlayer=========>"+mediaPlayer==null?"null":"ok");
+	  Log.i(TAG,"vibrate=========>"+vibrate);
+    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();
+    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+    mediaPlayer.setOnCompletionListener(this);
+    mediaPlayer.setOnErrorListener(this);
+
+    AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.beep);
+    try {
+      mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
+      file.close();
+      mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
+      mediaPlayer.prepare();
+    } catch (IOException ioe) {
+      Log.w(TAG, ioe);
+      mediaPlayer = null;
+    }
+    return mediaPlayer;
+  }
+
+  @Override
+  public void onCompletion(MediaPlayer mp) {
+    // When the beep has finished playing, rewind to queue up another one.      
+    mp.seekTo(0);
+  }
+
+  @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
+      mp.release();
+      mediaPlayer = null;
+      updatePrefs();
+    }
+    return true;
+  }
+
+}

+ 27 - 0
RedAnt Photo/src/com/usai/redant/photo/BootReceiver.java

@@ -0,0 +1,27 @@
+package com.usai.redant.photo;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.util.Log;
+
+public class BootReceiver extends BroadcastReceiver {
+
+	// Context
+	public void UnlockReceiver(Context context) {
+
+	}
+
+	@Override
+	public void onReceive(Context context, Intent intent) {
+		// TODO Auto-generated method stub
+		if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
+			// Log.e("hg","ÊÕµ½¹ã²¥");
+		} else if (intent.getAction().equals(
+				ConnectivityManager.CONNECTIVITY_ACTION)) {
+
+		}
+	}
+
+}

+ 715 - 0
RedAnt Photo/src/com/usai/redant/photo/CaptureActivity.java

@@ -0,0 +1,715 @@
+/*
+ * 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.usai.redant.photo;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.Result;
+import com.google.zxing.ResultPoint;
+import com.google.zxing.client.result.ResultParser;
+import com.usai.redant.camera.CameraManager;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+//import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+import java.io.IOException;
+import java.util.Collection;
+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) {
+	  Log.i(TAG,"==============>CaptureActivity created!");
+    super.onCreate(icicle);
+
+    Window window = getWindow();
+    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    
+    setContentView(R.layout.capture);
+
+    
+    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+    hasSurface = false;
+//    historyManager = new HistoryManager(this);
+//    historyManager.trimHistory();
+    inactivityTimer = new InactivityTimer(this);
+    beepManager = new BeepManager(this);
+    ambientLightManager = new AmbientLightManager(this);
+
+    PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+  }
+
+  @Override
+  protected void onResume() {
+    super.onResume();
+
+    // CameraManager must be initialized here, not in onCreate(). This is necessary because we don't
+    // want to open the camera driver and measure the screen size if we're going to show the help on
+    // first launch. That led to bugs where the scanning rectangle was the wrong size and partially
+    // off screen.
+    cameraManager = new CameraManager(getApplication());
+
+    viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
+    viewfinderView.setCameraManager(cameraManager);
+
+//    resultView = findViewById(R.id.result_view);
+    statusView = (TextView) findViewById(R.id.status_view);
+
+    handler = null;
+    lastResult = null;
+
+    resetStatusView();
+
+    SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
+    SurfaceHolder surfaceHolder = surfaceView.getHolder();
+    if (hasSurface) {
+      // The activity was paused but not stopped, so the surface still exists. Therefore
+      // surfaceCreated() won't be called, so init the camera here.
+      initCamera(surfaceHolder);
+    } else {
+      // Install the callback and wait for surfaceCreated() to init the camera.
+      surfaceHolder.addCallback(this);
+    }
+
+    beepManager.updatePrefs();
+    ambientLightManager.start(cameraManager);
+
+    inactivityTimer.onResume();
+
+    Intent intent = getIntent();
+
+//    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+//    copyToClipboard = prefs.getBoolean(PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true)
+//        && (intent == null || intent.getBooleanExtra(Intents.Scan.SAVE_HISTORY, true));
+
+//    source = IntentSource.NONE;
+    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);
+          }
+        }
+        
+        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);
+
+    }
+  }
+  
+//  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();
+    cameraManager.closeDriver();
+    if (!hasSurface) {
+      SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
+      SurfaceHolder surfaceHolder = surfaceView.getHolder();
+      surfaceHolder.removeCallback(this);
+    }
+    super.onPause();
+  }
+
+  @Override
+  protected void onDestroy() {
+    inactivityTimer.shutdown();
+    super.onDestroy();
+  }
+
+  @Override
+  public boolean onKeyDown(int keyCode, KeyEvent event) {
+    switch (keyCode) {
+//      case KeyEvent.KEYCODE_BACK:
+//        if (source == IntentSource.NATIVE_APP_INTENT) {
+//          setResult(RESULT_CANCELED);
+//          finish();
+//          return true;
+//        }
+//        if ((source == IntentSource.NONE || source == IntentSource.ZXING_LINK) && lastResult != null) {
+//          restartPreviewAfterDelay(0L);
+//          return true;
+//        }
+//        break;
+      case KeyEvent.KEYCODE_FOCUS:
+      case KeyEvent.KEYCODE_CAMERA:
+        // Handle these events so they don't launch the Camera app
+        return true;
+      // Use volume up/down to turn on light
+      case KeyEvent.KEYCODE_VOLUME_DOWN:
+        cameraManager.setTorch(false);
+        return true;
+      case KeyEvent.KEYCODE_VOLUME_UP:
+        cameraManager.setTorch(true);
+        return true;
+    }
+    return super.onKeyDown(keyCode, event);
+  }
+
+  @Override
+  public boolean onCreateOptionsMenu(Menu menu) {
+    MenuInflater menuInflater = getMenuInflater();
+    menuInflater.inflate(R.menu.capture, menu);
+    return super.onCreateOptionsMenu(menu);
+  }
+
+  @Override
+  public boolean onOptionsItemSelected(MenuItem item) {
+    Intent intent = new Intent(Intent.ACTION_VIEW);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    switch (item.getItemId()) {
+//      case R.id.menu_share:
+//        intent.setClassName(this, ShareActivity.class.getName());
+//        startActivity(intent);
+//        break;
+//      case R.id.menu_history:
+//        intent.setClassName(this, HistoryActivity.class.getName());
+//        startActivityForResult(intent, HISTORY_REQUEST_CODE);
+//        break;
+      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;
+      default:
+        return super.onOptionsItemSelected(item);
+    }
+    return true;
+  }
+
+//  @Override
+//  public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+//    if (resultCode == RESULT_OK) {
+////      if (requestCode == HISTORY_REQUEST_CODE) 
+////      {
+////        int itemNumber = intent.getIntExtra(Intents.History.ITEM_NUMBER, -1);
+////        if (itemNumber >= 0) {
+////          HistoryItem historyItem = historyManager.buildHistoryItem(itemNumber);
+////          decodeOrStoreSavedBitmap(null, historyItem.getResult());
+////        }
+////      }
+//    }
+//  }
+
+  private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
+    // Bitmap isn't used yet -- will be used soon
+    if (handler == null) {
+      savedResultToShow = result;
+    } else {
+      if (result != null) {
+        savedResultToShow = result;
+      }
+      if (savedResultToShow != null) {
+        Message message = Message.obtain(handler, R.id.decode_succeeded, savedResultToShow);
+        handler.sendMessage(message);
+      }
+      savedResultToShow = null;
+    }
+  }
+
+  @Override
+  public void surfaceCreated(SurfaceHolder holder) {
+    if (holder == null) {
+      Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
+    }
+    if (!hasSurface) {
+      hasSurface = true;
+      initCamera(holder);
+    }
+  }
+
+  @Override
+  public void surfaceDestroyed(SurfaceHolder holder) {
+    hasSurface = false;
+  }
+
+  @Override
+  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+
+  }
+
+  /**
+   * A valid barcode has been found, so give an indication of success and show the results.
+   *
+   * @param rawResult The contents of the barcode.
+   * @param 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;
+    TextView debugTextView = (TextView)findViewById(R.id.textView1);
+    debugTextView.setText(rawResult.getText());
+//    ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
+    Log.i(TAG, "RESULT=========>"+rawResult.getText().toString());
+  //  ParsedResult result = parseResult(rawResult);
+    Log.i(TAG, "HANDLER========>"+ResultParser.parseResult(rawResult).getType().toString());
+    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);
+    }
+
+    Intent result = new Intent();
+    result.putExtra("pid", rawResult.getText());
+    setResult(Activity.RESULT_OK, result);
+    finish();    
+//    restartPreviewAfterDelay(1000l);
+ //   finish();
+//
+//    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) {
+//    statusView.setVisibility(View.GONE);
+//    viewfinderView.setVisibility(View.GONE);
+////    resultView.setVisibility(View.VISIBLE);
+//    Log.i(TAG, "RESULT=========>"+rawResult.getText().toString());
+//    Log.i(TAG, "HANDLER========>"+resultHandler.getType().toString());
+
+//    ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view);
+//    if (barcode == null) {
+//      barcodeImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),
+//          R.drawable.ic_launcher));
+//    } else {
+//      barcodeImageView.setImageBitmap(barcode);
+//    }
+//
+//    TextView formatTextView = (TextView) findViewById(R.id.format_text_view);
+//    formatTextView.setText(rawResult.getBarcodeFormat().toString());
+//
+//    TextView typeTextView = (TextView) findViewById(R.id.type_text_view);
+//    typeTextView.setText(resultHandler.getType().toString());
+//
+//    DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+//    TextView timeTextView = (TextView) findViewById(R.id.time_text_view);
+//    timeTextView.setText(formatter.format(new Date(rawResult.getTimestamp())));
+//
+//
+//    TextView metaTextView = (TextView) findViewById(R.id.meta_text_view);
+//    View metaTextViewLabel = findViewById(R.id.meta_text_view_label);
+//    metaTextView.setVisibility(View.GONE);
+//    metaTextViewLabel.setVisibility(View.GONE);
+//    Map<ResultMetadataType,Object> metadata = rawResult.getResultMetadata();
+//    if (metadata != null) {
+//      StringBuilder metadataText = new StringBuilder(20);
+//      for (Map.Entry<ResultMetadataType,Object> entry : metadata.entrySet()) {
+//        if (DISPLAYABLE_METADATA_TYPES.contains(entry.getKey())) {
+//          metadataText.append(entry.getValue()).append('\n');
+//        }
+//      }
+//      if (metadataText.length() > 0) {
+//        metadataText.setLength(metadataText.length() - 1);
+//        metaTextView.setText(metadataText);
+//        metaTextView.setVisibility(View.VISIBLE);
+//        metaTextViewLabel.setVisibility(View.VISIBLE);
+//      }
+//    }
+//
+//    TextView contentsTextView = (TextView) findViewById(R.id.contents_text_view);
+//    CharSequence displayContents = resultHandler.getDisplayContents();
+//    contentsTextView.setText(displayContents);
+//    // Crudely scale betweeen 22 and 32 -- bigger font for shorter text
+//    int scaledSize = Math.max(22, 32 - displayContents.length() / 4);
+//    contentsTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize);
+//
+//    TextView supplementTextView = (TextView) findViewById(R.id.contents_supplement_text_view);
+//    supplementTextView.setText("");
+//    supplementTextView.setOnClickListener(null);
+////    if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
+////        PreferencesActivity.KEY_SUPPLEMENTAL, true)) {
+////      SupplementalInfoRetriever.maybeInvokeRetrieval(supplementTextView,
+////                                                     resultHandler.getResult(),
+////                                                     historyManager,
+////                                                     this);
+////    }
+//
+//    int buttonCount = resultHandler.getButtonCount();
+//    ViewGroup buttonView = (ViewGroup) findViewById(R.id.result_button_view);
+//    buttonView.requestFocus();
+//    for (int x = 0; x < ResultHandler.MAX_BUTTON_COUNT; x++) {
+//      TextView button = (TextView) buttonView.getChildAt(x);
+//      if (x < buttonCount) {
+//        button.setVisibility(View.VISIBLE);
+//        button.setText(resultHandler.getButtonText(x));
+//        button.setOnClickListener(new ResultButtonListener(resultHandler, x));
+//      } else {
+//        button.setVisibility(View.GONE);
+//      }
+//    }
+//
+//    if (copyToClipboard && !resultHandler.areContentsSecure()) {
+//      ClipboardInterface.setText(displayContents, this);
+//    }
+//  }
+
+//  // 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);
+//        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();
+  }
+}

+ 169 - 0
RedAnt Photo/src/com/usai/redant/photo/CaptureActivityHandler.java

@@ -0,0 +1,169 @@
+/*
+ * 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.usai.redant.photo;
+
+import android.content.ActivityNotFoundException;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.BitmapFactory;
+import android.provider.Browser;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.Result;
+import com.usai.redant.camera.CameraManager;
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import java.util.Collection;
+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) {
+    switch (message.what) {
+      case R.id.restart_preview:
+        Log.d(TAG, "Got restart preview message");
+        restartPreviewAndDecode();
+        break;
+      case R.id.decode_succeeded:
+        Log.d(TAG, "Got decode succeeded message");
+        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);
+        break;
+      case 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);
+        break;
+      case R.id.return_scan_result:
+        Log.d(TAG, "Got return scan result message");
+        activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
+        activity.finish();
+        break;
+      case R.id.launch_product_query:
+        Log.d(TAG, "Got product query message");
+        String url = (String) message.obj;
+
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+        intent.setData(Uri.parse(url));
+
+        ResolveInfo resolveInfo =
+            activity.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        String browserPackageName = null;
+        if (resolveInfo != 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);
+        }
+        break;
+    }
+  }
+
+  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();
+    }
+  }
+
+}

+ 101 - 0
RedAnt Photo/src/com/usai/redant/photo/DecodeFormatManager.java

@@ -0,0 +1,101 @@
+/*
+ * 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.usai.redant.photo;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import android.content.Intent;
+import android.net.Uri;
+import com.google.zxing.BarcodeFormat;
+
+final class DecodeFormatManager {
+
+  private static final Pattern COMMA_PATTERN = Pattern.compile(",");
+
+  static final Collection<BarcodeFormat> PRODUCT_FORMATS;
+  static final Collection<BarcodeFormat> ONE_D_FORMATS;
+  static final Collection<BarcodeFormat> QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
+  static final Collection<BarcodeFormat> DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);
+  static {
+    PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A,
+                                 BarcodeFormat.UPC_E,
+                                 BarcodeFormat.EAN_13,
+                                 BarcodeFormat.EAN_8,
+                                 BarcodeFormat.RSS_14,
+                                 BarcodeFormat.RSS_EXPANDED);
+    ONE_D_FORMATS = EnumSet.of(BarcodeFormat.CODE_39,
+                               BarcodeFormat.CODE_93,
+                               BarcodeFormat.CODE_128,
+                               BarcodeFormat.ITF,
+                               BarcodeFormat.CODABAR);
+    ONE_D_FORMATS.addAll(PRODUCT_FORMATS);
+  }
+
+  private DecodeFormatManager() {}
+
+  static Collection<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 Collection<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 Collection<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats,
+                                                              String decodeMode) {
+    if (scanFormats != null) {
+      Collection<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) {
+      if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) {
+        return PRODUCT_FORMATS;
+      }
+      if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) {
+        return QR_CODE_FORMATS;
+      }
+      if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) {
+        return DATA_MATRIX_FORMATS;
+      }
+      if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) {
+        return ONE_D_FORMATS;
+      }
+    }
+    return null;
+  }
+
+}

+ 121 - 0
RedAnt Photo/src/com/usai/redant/photo/DecodeHandler.java

@@ -0,0 +1,121 @@
+/*
+ * 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.usai.redant.photo;
+
+import android.graphics.Bitmap;
+
+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 android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+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;
+    }
+    switch (message.what) {
+      case R.id.decode:
+        decode((byte[]) message.obj, message.arg1, message.arg2);
+        break;
+      case R.id.quit:
+        running = false;
+        Looper.myLooper().quit();
+        break;
+    }
+  }
+
+  /**
+   * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
+   * reuse the same reader objects from one decode to the next.
+   *
+   * @param data   The YUV preview frame.
+   * @param width  The width of the preview frame.
+   * @param height The height of the preview frame.
+   */
+  private void decode(byte[] data, int width, int height) {
+    long start = System.currentTimeMillis();
+    Result rawResult = null;
+    PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
+    if (source != null) {
+      BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+      try {
+        rawResult = multiFormatReader.decodeWithState(bitmap);
+      } catch (ReaderException re) {
+        // continue
+      } finally {
+        multiFormatReader.reset();
+      }
+    }
+
+    Handler handler = activity.getHandler();
+    if (rawResult != null) {
+      // Don't log the barcode contents for security.
+      long end = System.currentTimeMillis();
+      Log.d(TAG, "Found barcode in " + (end - start) + " ms");
+      if (handler != null) {
+        Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
+        Bundle bundle = new Bundle();
+        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());
+  }
+
+}

+ 236 - 0
RedAnt Photo/src/com/usai/redant/photo/DecodeHintManager.java

@@ -0,0 +1,236 @@
+/*
+ * 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.usai.redant.photo;
+
+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<String,String>();
+    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, Object>(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,Object>(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;
+  }
+
+}

+ 104 - 0
RedAnt Photo/src/com/usai/redant/photo/DecodeThread.java

@@ -0,0 +1,104 @@
+/*
+ * 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.usai.redant.photo;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.ResultPointCallback;
+
+import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.Looper;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This thread does all the heavy lifting of decoding the images.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+final class DecodeThread extends Thread {
+
+  public static final String BARCODE_BITMAP = "barcode_bitmap";
+  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,Object>(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, false)) {
+        decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
+      }
+      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, false)) {
+        decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
+      }
+      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_DATA_MATRIX, false)) {
+        decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
+      }
+    }
+    hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
+
+    if (characterSet != null) {
+      hints.put(DecodeHintType.CHARACTER_SET, characterSet);
+    }
+    hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);
+    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();
+  }
+
+}

+ 49 - 0
RedAnt Photo/src/com/usai/redant/photo/FinishListener.java

@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.usai.redant.photo;
+
+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();
+  }
+
+}

+ 243 - 0
RedAnt Photo/src/com/usai/redant/photo/HttpHelper.java

@@ -0,0 +1,243 @@
+/*
+ * 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.usai.redant.photo;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+
+/**
+ * Utility methods for retrieving content over HTTP using the more-supported {@code java.net} classes
+ * in Android.
+ */
+public final class HttpHelper {
+
+  private static final String TAG = HttpHelper.class.getSimpleName();
+
+  private static final Collection<String> REDIRECTOR_DOMAINS = new HashSet<String>(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.
+   *
+   * @see #downloadViaHttp(String, HttpHelper.ContentType, int)
+   */
+  public static CharSequence downloadViaHttp(String uri, ContentType type) throws IOException {
+    return downloadViaHttp(uri, type, Integer.MAX_VALUE);
+  }
+
+  /**
+   * @param uri URI to retrieve
+   * @param type expected text-like MIME type of that content
+   * @param maxChars approximate maximum characters to read from the source
+   * @return content as a {@code String}
+   * @throws IOException if the content can't be retrieved because of a bad URI, network problem, etc.
+   */
+  public static CharSequence downloadViaHttp(String uri, ContentType type, int maxChars) throws IOException {
+    String contentTypes;
+    switch (type) {
+      case HTML:
+        contentTypes = "application/xhtml+xml,text/html,text/*,*/*";
+        break;
+      case JSON:
+        contentTypes = "application/json,text/*,*/*";
+        break;
+      case 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(uri, 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 ioe) {
+          // continue
+        } catch (NullPointerException npe) {
+          // another apparent Android / Harmony bug; continue
+        }
+      }
+    }
+    return out;
+  }
+
+  public static URI unredirect(URI uri) throws IOException {
+    if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
+      return uri;
+    }
+    URL url = uri.toURL();
+    HttpURLConnection connection = safelyOpenConnection(url);
+    connection.setInstanceFollowRedirects(false);
+    connection.setDoInput(false);
+    connection.setRequestMethod("HEAD");
+    connection.setRequestProperty("User-Agent", "ZXing (Android)");
+    try {
+      int responseCode = safelyConnect(uri.toString(), 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(String uri, HttpURLConnection connection) throws IOException {
+    try {
+      connection.connect();
+    } catch (NullPointerException npe) {
+      // this is an Android bug: http://code.google.com/p/android/issues/detail?id=16895
+      throw new IOException(npe);
+    } catch (IllegalArgumentException iae) {
+      // Also seen this in the wild, not sure what to make of it. Probably a bad URL
+      throw new IOException(iae);
+    } catch (SecurityException se) {
+      // due to bad VPN settings?
+      Log.w(TAG, "Restricted URI? " + uri);
+      throw new IOException(se);
+    } catch (IndexOutOfBoundsException ioobe) {
+      // Another Android problem? https://groups.google.com/forum/?fromgroups#!topic/google-admob-ads-sdk/U-WfmYa9or0
+      throw new IOException(ioobe);
+    }
+    try {
+      return connection.getResponseCode();
+    } catch (NullPointerException npe) {
+      // this is maybe this Android bug: http://code.google.com/p/android/issues/detail?id=15554
+      throw new IOException(npe);
+    } catch (IllegalArgumentException iae) {
+      // Again seen this in the wild for bad header fields in the server response! or bad reads
+      Log.w(TAG, "Bad server status? " + uri);
+      throw new IOException(iae);
+    } catch (StringIndexOutOfBoundsException sioobe) {
+      // Another Android bug: https://code.google.com/p/android/issues/detail?id=18856
+      throw new IOException(sioobe);
+    }
+  }
+
+}

+ 116 - 0
RedAnt Photo/src/com/usai/redant/photo/InactivityTimer.java

@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.usai.redant.photo;
+
+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<?,?,?> 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;
+    }
+  }
+
+}

+ 261 - 0
RedAnt Photo/src/com/usai/redant/photo/Intents.java

@@ -0,0 +1,261 @@
+/*
+ * 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.usai.redant.photo;
+
+/**
+ * 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";
+
+    /**
+     * 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";
+
+    /**
+     * @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() {
+    }
+  }
+}

+ 297 - 0
RedAnt Photo/src/com/usai/redant/photo/LockerActivity.java

@@ -0,0 +1,297 @@
+package com.usai.redant.photo;
+
+import com.usai.util.dbUtil;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.TextView;
+
+/**
+ * Activity which displays a login screen to the user, offering registration as
+ * well.
+ */
+public class LockerActivity extends Activity {
+	/**
+	 * A dummy authentication store containing known user names and passwords.
+	 * TODO: remove after connecting to a real authentication system.
+	 */
+//	private static final String[] DUMMY_CREDENTIALS = new String[] {
+//			"foo@example.com:hello", "bar@example.com:world" };
+
+	/**
+	 * The default email to populate the email field with.
+	 */
+	public static final String EXTRA_EMAIL = "com.example.android.authenticatordemo.extra.EMAIL";
+
+	/**
+	 * Keep track of the login task to ensure we can cancel it if requested.
+	 */
+	private UserLoginTask mAuthTask = null;
+
+	SQLiteDatabase m_db;
+	// Values for email and password at the time of the login attempt.
+	private String m_sName;
+	private String m_sPassword;
+
+	// UI references.
+	private EditText m_etName;
+	private EditText m_etPassword;
+	private View mLoginFormView;
+	private View mLoginStatusView;
+	private TextView mLoginStatusMessageView;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_locker);
+
+		// Set up the login form.
+//		m_sName = getIntent().getStringExtra(EXTRA_USER);
+		m_etName = (EditText) findViewById(R.id.name);
+		
+//		m_etName.setText(m_sName);
+
+		m_etPassword = (EditText) findViewById(R.id.password);
+		m_etPassword
+				.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+					@Override
+					public boolean onEditorAction(TextView textView, int id,
+							KeyEvent keyEvent) {
+Log.d("onEditorAction", "id="+id+" keyevent="+keyEvent);
+						if (id == R.id.locker || id == EditorInfo.IME_ACTION_DONE ) {
+							attemptLogin();
+							return true;
+						}
+						return false;
+					}
+				});
+
+		mLoginFormView = findViewById(R.id.login_form);
+		mLoginStatusView = findViewById(R.id.login_status);
+		mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);
+
+		findViewById(R.id.sign_in_button).setOnClickListener(
+				new View.OnClickListener() {
+					@Override
+					public void onClick(View view) {
+						attemptLogin();
+					}
+				});
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		super.onCreateOptionsMenu(menu);
+		getMenuInflater().inflate(R.menu.locker, menu);
+		return true;
+	}
+
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if(keyCode == KeyEvent.KEYCODE_BACK){
+//            Intent myIntent = new Intent();
+//            myIntent = new Intent(EditActivity.this, tabActivity.class);
+//            startActivity(myIntent);
+//            this.finish();
+        	return true;
+        }
+        return super.onKeyDown(keyCode, event);
+
+	}
+
+	/**
+	 * Attempts to sign in or register the account specified by the login form.
+	 * If there are form errors (invalid email, missing fields, etc.), the
+	 * errors are presented and no actual login attempt is made.
+	 */
+	public void attemptLogin() {
+		if (mAuthTask != null) {
+			return;
+		}
+
+		// Reset errors.
+		m_etName.setError(null);
+		m_etPassword.setError(null);
+
+		// Store values at the time of the login attempt.
+		m_sName = m_etName.getText().toString();
+		m_sPassword = m_etPassword.getText().toString();
+
+		boolean cancel = false;
+		View focusView = null;
+
+		// Check for a valid password.
+		if (TextUtils.isEmpty(m_sPassword)) {
+			m_etPassword.setError(getString(R.string.error_field_required));
+			focusView = m_etPassword;
+			cancel = true;
+		} else if (m_sPassword.length() < 4) {
+			m_etPassword.setError(getString(R.string.error_invalid_password));
+			focusView = m_etPassword;
+			cancel = true;
+		}
+
+		// Check for a valid user name.
+		if (TextUtils.isEmpty(m_sName)) {
+			m_etName.setError(getString(R.string.error_field_required));
+			focusView = m_etName;
+			cancel = true;
+		}
+		// else if (!m_sName.contains("@")) {
+		// m_etName.setError(getString(R.string.error_invalid_email));
+		// focusView = m_etName;
+		// cancel = true;
+		// }
+
+		if (cancel) {
+			// There was an error; don't attempt login and focus the first
+			// form field with an error.
+			focusView.requestFocus();
+		} else {
+			// Show a progress spinner, and kick off a background task to
+			// perform the user login attempt.
+			mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
+			showProgress(true);
+			mAuthTask = new UserLoginTask();
+			mAuthTask.execute((Void) null);
+		}
+	}
+
+	/**
+	 * Shows the progress UI and hides the login form.
+	 */
+	@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+	private void showProgress(final boolean show) {
+		// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+		// for very easy animations. If available, use these APIs to fade-in
+		// the progress spinner.
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
+			int shortAnimTime = getResources().getInteger(
+					android.R.integer.config_shortAnimTime);
+
+			mLoginStatusView.setVisibility(View.VISIBLE);
+			mLoginStatusView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 1 : 0)
+					.setListener(new AnimatorListenerAdapter() {
+						@Override
+						public void onAnimationEnd(Animator animation) {
+							mLoginStatusView.setVisibility(show ? View.VISIBLE
+									: View.GONE);
+						}
+					});
+
+			mLoginFormView.setVisibility(View.VISIBLE);
+			mLoginFormView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 0 : 1)
+					.setListener(new AnimatorListenerAdapter() {
+						@Override
+						public void onAnimationEnd(Animator animation) {
+							mLoginFormView.setVisibility(show ? View.GONE
+									: View.VISIBLE);
+						}
+					});
+		} else {
+			// The ViewPropertyAnimator APIs are not available, so simply show
+			// and hide the relevant UI components.
+			mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
+			mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+		}
+	}
+
+	/**
+	 * Represents an asynchronous login/registration task used to authenticate
+	 * the user.
+	 */
+	public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
+		@Override
+		protected Boolean doInBackground(Void... params) {
+
+			m_db = dbUtil.OpenDB(LockerActivity.this, null, true);
+
+			Cursor cursor = m_db.query("users", new String[] {  "pass",
+					"_id" }, "name= '"+m_sName+"'", null, null, null, "_id desc", null);
+			if (cursor.moveToNext()) {
+				// user exist in local db;
+//				Log.d(TAG, "USER "+m_sName+" exist!");
+				String pass = cursor.getString(0);
+				if (pass.equals(m_sPassword))
+					return true;
+				else {
+					return false;// wrong password
+				}
+			} else {
+				// user not exist in local db;
+				try {
+					// Simulate network access.
+					Thread.sleep(2000);
+				} catch (InterruptedException e) {
+					return false;
+				}
+				// TODO: register the new account here.
+				// online check user here;
+				if (true)// check pass create user in local db;
+				{
+					ContentValues cv = new ContentValues();
+					cv.put("name", m_sName);
+					cv.put("pass", m_sPassword);
+
+
+					m_db.insert("users", null, cv);
+
+					return true;
+
+				} else {
+					// no user exist on the server;
+					return false;
+				}
+			}
+		}
+		
+		@Override
+		protected void onPostExecute(final Boolean success) {
+			mAuthTask = null;
+			showProgress(false);
+
+			if (success) {
+				
+//				SharedPreferences.Editor editor = RunOnce.edit();
+//				editor.putBoolean("FirstRun"+globalUtil.getVerName(this), false);
+//				// Don't forget to commit your edits!!!
+//				editor.commit();
+                
+                Intent intent = new Intent();
+                intent.putExtra("user", m_sName);
+                /*
+                 * 调用setResult方法表示我将Intent对象返回给之前的那个Activity,这样就可以在onActivityResult方法中得到Intent对象,
+                 */
+                setResult(Activity.RESULT_OK, intent);			
+				finish();
+			} else {
+				m_etPassword
+						.setError(getString(R.string.error_incorrect_password));
+				m_etPassword.requestFocus();
+			}
+		}
+		@Override
+		protected void onCancelled() {
+			mAuthTask = null;
+			showProgress(false);
+		}
+	}
+}

+ 400 - 0
RedAnt Photo/src/com/usai/redant/photo/LoginActivity.java

@@ -0,0 +1,400 @@
+package com.usai.redant.photo;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+//import com.example.com.apex.usa.test1.R.id;
+//import com.example.com.apex.usa.test1.R.layout;
+//import com.example.com.apex.usa.test1.R.menu;
+//import com.example.com.apex.usa.test1.R.string;
+
+import android.R.bool;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.nfc.Tag;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Looper;
+import android.telephony.PhoneNumberUtils;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * Activity which displays a login screen to the user, offering registration as
+ * well.
+ */
+public class LoginActivity extends Activity
+{
+
+//	public static final int ERR_CODE_NONE = 0;
+//	public static final int ERR_CODE_NULLRETURN = 1;
+//	public static final int ERR_CODE_NONETWORK = 2;
+
+	/**
+	 * A dummy authentication store containing known user names and passwords.
+	 * TODO: remove after connecting to a real authentication system.
+	 */
+	// private static final String[] DUMMY_CREDENTIALS = new String[] {
+	// "foo@example.com:hello", "bar@example.com:world" };
+
+	/**
+	 * The default email to populate the email field with.
+	 */
+	// public static final String EXTRA_EMAIL =
+	// "com.example.android.authenticatordemo.extra.EMAIL";
+	// public static final String EXTRA_USER = "Login_User";
+
+	/**
+	 * Keep track of the login task to ensure we can cancel it if requested.
+	 */
+	private UserLoginTask mAuthTask = null;
+
+	SQLiteDatabase m_db;
+	// Values for email and password at the time of the login attempt.
+	private String m_sName;
+	private String m_sPassword;
+
+	// UI references.
+	private EditText m_etName;
+	private EditText m_etPassword;
+	private View mLoginFormView;
+	private View mLoginStatusView;
+	private TextView mLoginStatusMessageView;
+
+	@Override
+	protected void onDestroy()
+	{
+		// TODO Auto-generated method stub
+		dbUtil.CloseDB(m_db);
+		super.onDestroy();
+
+	}
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+
+		setContentView(R.layout.activity_login);
+
+		// Set up the login form.
+		// m_sName = getIntent().getStringExtra(EXTRA_USER);
+		m_etName = (EditText) findViewById(R.id.name);
+
+		// m_etName.setText(m_sName);
+
+		m_etPassword = (EditText) findViewById(R.id.password);
+		m_etPassword
+				.setOnEditorActionListener(new TextView.OnEditorActionListener()
+				{
+					@Override
+					public boolean onEditorAction(TextView textView, int id,
+							KeyEvent keyEvent)
+					{
+						if (id == R.id.login
+								|| id == EditorInfo.IME_ACTION_DONE)
+						{
+							InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext()
+									.getSystemService(INPUT_METHOD_SERVICE);
+
+							// EditText editText =
+							// (EditText)findViewById(R.id.xxxx);
+							inputMethodManager.hideSoftInputFromWindow(
+									m_etPassword.getWindowToken(), 0); // Òþ²Ø
+							attemptLogin();
+							return true;
+						}
+						return false;
+					}
+				});
+
+		mLoginFormView = findViewById(R.id.login_form);
+		mLoginStatusView = findViewById(R.id.login_status);
+		mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);
+
+		findViewById(R.id.sign_in_button).setOnClickListener(
+				new View.OnClickListener()
+				{
+					@Override
+					public void onClick(View view)
+					{
+						attemptLogin();
+					}
+				});
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		super.onCreateOptionsMenu(menu);
+		getMenuInflater().inflate(R.menu.login, menu);
+		return true;
+	}
+
+	/**
+	 * Attempts to sign in or register the account specified by the login form.
+	 * If there are form errors (invalid email, missing fields, etc.), the
+	 * errors are presented and no actual login attempt is made.
+	 */
+	public void attemptLogin()
+	{
+		if (mAuthTask != null)
+		{
+			return;
+		}
+
+		// Reset errors.
+		m_etName.setError(null);
+		m_etPassword.setError(null);
+
+		// Store values at the time of the login attempt.
+		m_sName = m_etName.getText().toString();
+		m_sPassword = m_etPassword.getText().toString();
+
+		boolean cancel = false;
+		View focusView = null;
+
+		// Check for a valid password.
+		if (TextUtils.isEmpty(m_sPassword))
+		{
+			m_etPassword.setError(getString(R.string.error_field_required));
+			focusView = m_etPassword;
+			cancel = true;
+		}
+		else
+			if (m_sPassword.length() < 4)
+			{
+				m_etPassword
+						.setError(getString(R.string.error_invalid_password));
+				focusView = m_etPassword;
+				cancel = true;
+			}
+
+		// Check for a valid user name.
+		if (TextUtils.isEmpty(m_sName))
+		{
+			m_etName.setError(getString(R.string.error_field_required));
+			focusView = m_etName;
+			cancel = true;
+		}
+		// else if (!m_sName.contains("@")) {
+		// m_etName.setError(getString(R.string.error_invalid_email));
+		// focusView = m_etName;
+		// cancel = true;
+		// }
+
+		if (cancel)
+		{
+			// There was an error; don't attempt login and focus the first
+			// form field with an error.
+			focusView.requestFocus();
+		}
+		else
+		{
+			// Show a progress spinner, and kick off a background task to
+			// perform the user login attempt.
+			mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
+			showProgress(true);
+			mAuthTask = new UserLoginTask();
+			mAuthTask.execute((Void) null);
+		}
+	}
+
+	/**
+	 * Shows the progress UI and hides the login form.
+	 */
+	@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+	private void showProgress(final boolean show)
+	{
+		// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+		// for very easy animations. If available, use these APIs to fade-in
+		// the progress spinner.
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
+		{
+			int shortAnimTime = getResources().getInteger(
+					android.R.integer.config_shortAnimTime);
+
+			mLoginStatusView.setVisibility(View.VISIBLE);
+			mLoginStatusView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 1 : 0)
+					.setListener(new AnimatorListenerAdapter()
+					{
+						@Override
+						public void onAnimationEnd(Animator animation)
+						{
+							mLoginStatusView.setVisibility(show ? View.VISIBLE
+									: View.GONE);
+						}
+					});
+
+			mLoginFormView.setVisibility(View.VISIBLE);
+			mLoginFormView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 0 : 1)
+					.setListener(new AnimatorListenerAdapter()
+					{
+						@Override
+						public void onAnimationEnd(Animator animation)
+						{
+							mLoginFormView.setVisibility(show ? View.GONE
+									: View.VISIBLE);
+						}
+					});
+		}
+		else
+		{
+			// The ViewPropertyAnimator APIs are not available, so simply show
+			// and hide the relevant UI components.
+			mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
+			mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+		}
+	}
+
+	/**
+	 * Represents an asynchronous login/registration task used to authenticate
+	 * the user.
+	 */
+	public class UserLoginTask extends AsyncTask<Void, Void, Boolean>
+	{
+//		int err_code = ERR_CODE_NONE;
+		int verifyuser = Network.RESULT_TRUE;
+		int netconnect;
+
+		@Override
+		protected Boolean doInBackground(Void... params)
+		{
+
+			// if (Network.NetworkIsAvailable(LoginActivity.this))
+			// {
+			// Network.VerifyUser(m_sName, m_sPassword,LoginActivity.this);
+			// return false;
+			// }
+			m_db = dbUtil.OpenDB(LoginActivity.this, null, true);
+
+			Cursor cursor = m_db.query("users", new String[] { "pass", "_id" },
+					"name= '" + m_sName + "'", null, null, null, "_id desc",
+					null);
+			if (cursor.moveToNext())
+			{
+				// user exist in local db;
+				// Log.d(TAG, "USER "+m_sName+" exist!");
+				String pass = cursor.getString(0);
+				if (pass.equals(m_sPassword))
+					return true;
+				else
+				{
+					return false;// wrong password
+				}
+			}
+			else
+			{
+				/*
+				 * user not exist in local db; check online if user is
+				 * authorized create user in local db;
+				 */
+
+				if (!Network.NetworkIsAvailable(LoginActivity.this))
+				{
+					netconnect = Network.RESULT_NET_ERROR;
+
+					return false;
+				}
+				verifyuser = Network.VerifyUser(m_sName, m_sPassword);
+				if(verifyuser==Network.RESULT_TRUE)
+					return true;
+
+			}
+			return false;
+		}
+
+		@Override
+		protected void onPostExecute(final Boolean success)
+		{
+			Log.i("onPostExecute", "entry");
+			mAuthTask = null;
+			showProgress(false);
+			if(netconnect==Network.RESULT_NET_ERROR)
+			{
+				Toast toast = Toast.makeText(getApplicationContext(),
+						getText(R.string.msg_connection_none),
+						Toast.LENGTH_LONG);
+				toast.setGravity(Gravity.CENTER, 0, 0);
+				toast.show();				
+			}
+			switch (verifyuser)
+			{
+			case Network.RESULT_NET_ERROR:
+			{
+				Toast toast = Toast.makeText(getApplicationContext(),
+						getText(R.string.msg_net_error),
+						Toast.LENGTH_LONG);
+				toast.setGravity(Gravity.CENTER, 0, 0);
+				toast.show();
+				return;
+			}
+			case Network.RESULT_ERROR:
+//			case Network.RESULT_RESPONSE_NULL:
+			{
+				Toast toast = Toast.makeText(getApplicationContext(),
+						getText(R.string.msg_net_resulterror),
+						Toast.LENGTH_LONG);
+				toast.setGravity(Gravity.CENTER, 0, 0);
+				toast.show();
+				return;
+			}
+				
+			default:
+				break;
+			}
+
+			if (success)
+			{
+
+				// SharedPreferences.Editor editor = RunOnce.edit();
+				// editor.putBoolean("FirstRun"+globalUtil.getVerName(this),
+				// false);
+				// // Don't forget to commit your edits!!!
+				// editor.commit();
+				Intent intent = new Intent();
+				intent.setClass(LoginActivity.this, MainActivity.class);
+				intent.putExtra("user", m_sName);
+				intent.putExtra("password", m_sPassword);
+				startActivity(intent);
+				finish();
+			}
+			else
+			{
+				m_etPassword
+						.setError(getString(R.string.error_incorrect_password));
+				m_etPassword.requestFocus();
+			}
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			mAuthTask = null;
+			showProgress(false);
+		}
+	}
+}

+ 751 - 0
RedAnt Photo/src/com/usai/redant/photo/MainActivity.java

@@ -0,0 +1,751 @@
+package com.usai.redant.photo;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.ThumbnailUtils;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.database.sqlite.SQLiteDatabase;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class MainActivity extends Activity
+{
+	// static final int ACTIVITY_CAMERA = 0;
+	// static final int ACTIVITY_VIEW = 1;
+//	static final String serverurl = "http://192.168.23.1/xampp/";
+	static final String TAG = "MainActivity";
+	static final int REQUEST_TAKE_PHOTO = 1;
+	static final int REQUEST_SCAN_BARCODE = 2;
+	static final int REQUEST_LOCKER = 3;
+
+//	private String thumbpath = null;
+	private int iwidth = 640;
+	private int iheight = 480;
+	private File photoFile = null;
+	Bitmap thumbBitmap = null;
+	// private int iPhotoCount = 0;
+	public String LastFileName = "";
+	private boolean m_blocked = false;
+	TextView m_tvalert;
+	// private String user;
+	// private String password;
+	String m_sName;
+	String m_sPassword;
+	ArrayList<String> photoList = new ArrayList<String>();
+	// private SurfaceView picSV;
+	// private Camera camera;
+	//
+	private final BroadcastReceiver m_lockedReceiver = new BroadcastReceiver()
+	{
+		@Override
+		public void onReceive(Context context, Intent intent)
+		{
+			String action = intent.getAction();
+			if (action.equals(Intent.ACTION_SCREEN_OFF))
+			{
+				Log.e("hg", "收到广播!!!=======>m_blocked=" + m_blocked);
+				if (m_blocked == true)
+					return;
+				Intent activityintent = new Intent();
+				activityintent
+						.setClass(MainActivity.this, LockerActivity.class);
+				startActivityForResult(activityintent, REQUEST_LOCKER);
+				Log.e(TAG, "===================>start locker");
+				m_blocked = true;
+			}
+			// if (action.equals(Intent.ACTION_USER_PRESENT)) {
+			//
+			// Log.e("hg", "收到广播!!!=======>m_blocked=" + m_blocked);
+			// if (m_blocked == true)
+			// return;
+			// Intent activityintent = new Intent();
+			// activityintent
+			// .setClass(MainActivity.this, LockerActivity.class);
+			// startActivityForResult(activityintent, REQUEST_LOCKER);
+			// Log.e(TAG, "===================>start locker");
+			// m_blocked = true;
+			// }
+		}
+	};
+
+	// @Override
+	// protected void onStart() {
+	// Log.i(TAG, "onStart========>m_blocked="+m_blocked);
+	// // TODO Auto-generated method stub
+	//
+	// if (m_blocked) {
+	//
+	// }
+	// super.onStart();
+	// }
+	//
+	// @Override
+	// protected void onStop() {
+	// Log.i(TAG, "onStop========>");
+	// // TODO Auto-generated method stub
+	//
+	// super.onStop();
+	// }
+
+	private void StartCamera()
+	{
+		Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+		// Ensure that there's a camera activity to handle the intent
+
+		if (takePictureIntent.resolveActivity(getPackageManager()) != null)
+		{
+			// Create the File where the photo should go
+			// File photoFile = null;
+			if (photoFile != null)
+				photoFile = null;
+			try
+			{
+				photoFile = createImageFile();
+			}
+			catch (IOException ex)
+			{
+				// Error occurred while creating the File
+				// ...
+			}
+			// Continue only if the File was successfully created
+			Log.i(TAG, photoFile.toString());
+			if (photoFile != null)
+			{
+				Log.i(TAG, "start system camera====================>");
+				takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
+						Uri.fromFile(photoFile));
+				startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
+			}
+		}
+	}
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		Log.e(TAG, "=======================>MainActivity Created!");
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_main1);
+		IntentFilter msgFilter = new IntentFilter();
+		Intent intent = getIntent();
+
+		m_sName = intent.getStringExtra("user");
+		m_sPassword = intent.getStringExtra("password");
+
+		Log.e(TAG, "user=" + m_sName + ",password=" + m_sPassword);
+
+		msgFilter.addAction("android.intent.action.SCREEN_OFF");
+		msgFilter.setPriority(2147483647);
+		registerReceiver(m_lockedReceiver, msgFilter);
+		Log.e(TAG, "=======================>msgFilter registed!");
+		if (savedInstanceState != null)
+		{
+			thumbBitmap = getBitmap(savedInstanceState
+					.getByteArray("thumbBitmap"));
+			photoList.clear();
+			// ArrayList list = (ArrayList)
+			// Arrays.asList(savedInstanceState.getStringArray("arrayLabel"));
+			photoList = savedInstanceState.getStringArrayList("photoList");
+			// photoList = A
+			// savedInstanceState.getStringArrayList("photoList");
+			photoFile = (File) savedInstanceState.getSerializable("photoFile");
+			// iPhotoCount = savedInstanceState.getInt("iPhotoCount");
+//			thumbpath = savedInstanceState.getString("thumbpath");
+			if (savedInstanceState.getString("m_sName") != null)
+				m_sName = savedInstanceState.getString("m_sName");
+			if (savedInstanceState.getString("m_sPassword") != null)
+				m_sPassword = savedInstanceState.getString("m_sPassword");
+			ImageView thumbsImageView = (ImageView) findViewById(R.id.ivThumbs);
+			if (thumbBitmap != null)
+			{
+				thumbsImageView.setImageBitmap(thumbBitmap);
+//				Log.e(TAG, "load thumbpath==" + thumbpath);
+			}
+			// photoFile.delete();
+			TextView countTextView = (TextView) findViewById(R.id.tvPhotoCount);
+			countTextView.setText(photoList.size() + " Photos");
+
+		}
+		EditText edit = (EditText) findViewById(R.id.edit);
+
+		edit.addTextChangedListener(new TextWatcher()
+		{
+			@Override
+			public void onTextChanged(CharSequence s, int start, int before,
+					int count)
+			{
+
+			}
+
+			@Override
+			public void beforeTextChanged(CharSequence s, int start, int count,
+					int after)
+			{
+			}
+
+			@Override
+			public void afterTextChanged(Editable s)
+			{
+				// EditText edit = (EditText) findViewById(R.id.edit);
+				ImageButton ibtnUpload = (ImageButton) findViewById(R.id.ibtnOk);
+				if (photoList.size() > 0 && s.length() > 0)
+				{
+					ibtnUpload.setVisibility(View.VISIBLE);
+
+				}
+				else
+				{
+					ibtnUpload.setVisibility(View.INVISIBLE);
+
+				}
+			}
+		});
+		// if (getRequestedOrientation() ==
+		// ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
+		// LinearLayout landLayout = (LinearLayout) findViewById(R.id.land);
+		// landLayout.setVisibility(View.VISIBLE);
+		// } else {
+		// LinearLayout portLayout = (LinearLayout) findViewById(R.id.port);
+		// portLayout.setVisibility(View.VISIBLE);
+		// }
+		ImageButton ibtnscan = (ImageButton) findViewById(R.id.ibtnScan);
+		ibtnscan.setOnClickListener(new View.OnClickListener()
+		{
+
+			@Override
+			public void onClick(View v)
+			{
+				Intent intent = new Intent();
+				// Intent.ACTION_PICK,
+				// android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+				// startActivityForResult(intent, REQUEST_SCAN_BARCODE);
+
+				intent.setClass(MainActivity.this, CaptureActivity.class);
+				startActivityForResult(intent, REQUEST_SCAN_BARCODE);
+			}
+		});
+
+		ImageButton captureButton = (ImageButton) findViewById(R.id.ibtnCapture);
+		captureButton.setOnClickListener(new View.OnClickListener()
+		{
+
+			@Override
+			public void onClick(View v)
+			{
+
+				StartCamera();
+			}
+		});
+		ImageButton uploadButton = (ImageButton) findViewById(R.id.ibtnOk);
+		uploadButton.setOnClickListener(new View.OnClickListener()
+		{
+
+			@Override
+			public void onClick(View v)
+			{
+
+				new UploadTask().execute((Void) null);
+			}
+		});
+
+		m_tvalert = (TextView) findViewById(R.id.tvalert);
+		m_tvalert.setSelected(true);
+
+	}
+
+	@Override
+	protected void onDestroy()
+	{
+		// TODO Auto-generated method stub
+		Log.e(TAG, "=======================>MainActivity Destroyed!");
+		unregisterReceiver(m_lockedReceiver);
+		Log.e(TAG, "=======================>msgFilter unregisted!");
+		super.onDestroy();
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.main, menu);
+		return true;
+	}
+
+	private File createImageFile() throws IOException
+	{
+		// Create an image file name
+		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
+				.format(new Date());
+		String imageFileName = "JPEG_" + timeStamp + "_";
+		File storageDir = Environment
+				.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+		// Log.d(TAG, "DIR:" + storageDir);
+		LastFileName = storageDir + imageFileName + ".jpg";
+		Log.d(TAG, "File:" + LastFileName);
+		File image = File.createTempFile(imageFileName, /* prefix */
+				".jpg", /* suffix */
+				storageDir /* directory */
+		);
+
+		// Save a file: path for use with ACTION_VIEW intents
+		// mCurrentPhotoPath = "file:" + image.getAbsolutePath();
+		return image;
+	}
+
+//	public static void savePic(Bitmap b, String strFileName)
+//	{
+//		FileOutputStream fos = null;
+//		try
+//		{
+//			fos = new FileOutputStream(strFileName);
+//			if (null != fos)
+//			{
+//
+//				b.compress(Bitmap.CompressFormat.PNG, 90, fos);
+//				fos.flush();
+//				fos.close();
+//			}
+//		}
+//		catch (FileNotFoundException e)
+//		{
+//			e.printStackTrace();
+//		}
+//		catch (IOException e)
+//		{
+//			e.printStackTrace();
+//		}
+//	}
+
+	boolean createDir(String path)
+	{
+		Log.i(TAG, "readFile:createDir=" + path);
+		boolean ret = false;
+		try
+		{
+			File file = new File(path);
+			if (!file.exists())
+				file.mkdirs();
+			if (!file.isDirectory())
+			{
+				ret = file.mkdirs();
+			}
+		}
+		catch (Exception e)
+		{
+			Log.e(TAG, e.toString());
+		}
+		return ret;
+	}
+
+	void updateUploadButton()
+	{
+		EditText edit = (EditText) findViewById(R.id.edit);
+		ImageButton ibtnUpload = (ImageButton) findViewById(R.id.ibtnOk);
+		if (photoList.size() > 0 && edit.getText().length() > 0)
+		{
+			ibtnUpload.setVisibility(View.VISIBLE);
+
+		}
+		else
+		{
+			ibtnUpload.setVisibility(View.INVISIBLE);
+
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see android.app.Activity#onActivityResult(int, int,
+	 * android.content.Intent)
+	 */
+	@Override
+	public void onActivityResult(int requestCode, int resultCode, Intent data)
+	{
+
+		if (requestCode == REQUEST_TAKE_PHOTO)
+			// 处理照相机拍照的图片
+			if (resultCode == Activity.RESULT_OK) // 继续拍照
+
+			{
+				// Log.e(TAG, msg)
+				// Bundle bundle = data.getExtras();
+				// if(thumbBitmap!=null)
+				// thumbBitmap=null;
+				// thumbBitmap = (Bitmap) bundle.get("data");
+				// // 获取相机返回的数据,并转换为Bitmap图片格式
+				// Bitmap thumbBitmap = BitmapFactory.decodeFile(photoFile
+				// .toString());
+
+				// CreateThumb(photoFile);
+				Log.e(TAG, photoFile.toString());
+				photoList.add(photoFile.toString());
+
+				// Bitmap.createScaledBitmap(
+				// thumbBitmap, thumbsImageView.getWidth(),
+				// thumbsImageView.getHeight(), false));
+				// Log.i(TAG, "thumb size" + thumbBitmap.getHeight() + "x"
+				// + thumbBitmap.getWidth());
+//				thumbpath = photoFile.toString();
+//				Log.e(TAG, "get thumbpath==" + thumbpath);
+				StartCamera();
+				// iPhotoCount++;
+				super.onActivityResult(requestCode, resultCode, data);
+
+			}
+			else
+			{
+				// 退出拍照
+				// File emptyFile = new File(LastFileName);
+				// boolean b=emptyFile.delete();
+//				Log.i(TAG, "lastpicPath: " + thumbpath);
+				ImageView thumbsImageView = (ImageView) findViewById(R.id.ivThumbs);
+				// thumbBitmap=getImageThumbnail(thumbpath, iwidth,iheight);
+				if(photoList.size()>0)
+				{
+					thumbBitmap = ThumbnailUtils.extractThumbnail(
+							BitmapFactory.decodeFile(photoList.get(photoList.size()-1)), iwidth, iheight);
+					if (thumbBitmap != null)
+						thumbsImageView.setImageBitmap(thumbBitmap);
+				}
+//				thumbBitmap = ThumbnailUtils.extractThumbnail(
+//						BitmapFactory.decodeFile(thumbpath), iwidth, iheight);
+				// saveMyBitmap("thumbtest",thumbBitmap);
+//				if (thumbBitmap != null)
+//					thumbsImageView.setImageBitmap(thumbBitmap);
+				photoFile.delete();
+				TextView countTextView = (TextView) findViewById(R.id.tvPhotoCount);
+				countTextView.setText(photoList.size() + " Photos");
+				// ImageButton ibtnUpload = (ImageButton)
+				// findViewById(R.id.ibtnOk);
+				updateUploadButton();
+
+			}
+
+		else
+			if (requestCode == REQUEST_LOCKER)
+			{
+				if (resultCode == Activity.RESULT_OK)
+					m_blocked = false;
+			}
+			else
+				if (requestCode == REQUEST_SCAN_BARCODE)
+				{
+					if (resultCode == Activity.RESULT_OK)
+					{
+						Bundle bundle = data.getExtras();
+						String pid = bundle.getString("pid");
+						Log.e(TAG, "REQUEST_SCAN_BARCODE==========>pid="
+								+ bundle.getString("pid"));
+						EditText edit = (EditText) findViewById(R.id.edit);
+						edit.setText(pid);
+						// updateUploadButton();
+					}
+				}
+		super.onActivityResult(requestCode, resultCode, data);
+	}
+
+	public void saveMyBitmap(String bitName, Bitmap mBitmap)
+	{
+		File f = new File("/sdcard/" + bitName + ".png");
+		try
+		{
+			f.createNewFile();
+		}
+		catch (IOException e)
+		{
+			// TODO Auto-generated catch block
+			// DebugMessage.put("在保存图片时出错:" + e.toString());
+		}
+		FileOutputStream fOut = null;
+		try
+		{
+			fOut = new FileOutputStream(f);
+		}
+		catch (FileNotFoundException e)
+		{
+			e.printStackTrace();
+		}
+		mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
+		try
+		{
+			fOut.flush();
+		}
+		catch (IOException e)
+		{
+			e.printStackTrace();
+		}
+		try
+		{
+			fOut.close();
+		}
+		catch (IOException e)
+		{
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		// TODO Auto-generated method stub
+		switch (item.getItemId())
+		{
+		case R.id.action_orientation:
+			if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
+				setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+			else
+			{
+				setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+			}
+			break;
+
+		default:
+			break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	@Override
+	protected void onSaveInstanceState(Bundle outState)
+	{
+		// TODO Auto-generated method stub
+		super.onSaveInstanceState(outState);
+		if (photoFile != null)
+			outState.putSerializable("photoFile", photoFile);
+
+		if (thumbBitmap != null)
+			outState.putByteArray("thumbBitmap", getBytes(thumbBitmap));// ("thumbBitmap",
+																		// (Object)thumbBitmap);
+//		outState.putString("thumbpath", thumbpath);
+		outState.putString("m_sName", m_sName);
+		outState.putString("m_sPassword", m_sPassword);
+
+		outState.putStringArrayList("photoList", photoList);
+//		Log.e(TAG, "save thumbpath==" + thumbpath);
+		outState.putInt("iPhotoCount", photoList.size());
+	}
+
+	public static byte[] getBytes(Bitmap bitmap)
+	{
+		// 实例化字节数组输出流
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		bitmap.compress(Bitmap.CompressFormat.PNG, 0, baos);// 压缩位图
+		return baos.toByteArray();// 创建分配字节数组
+	}
+
+	public static Bitmap getBitmap(byte[] data)
+	{
+		if (data == null)
+			return null;
+		return BitmapFactory.decodeByteArray(data, 0, data.length);// 从字节数组解码位图
+	}
+
+	private void clearfornew()
+	{
+		photoList.clear();
+		EditText edit = (EditText) findViewById(R.id.edit);
+		edit.setText("");
+		updateUploadButton();
+		ImageView thumbsImageView = (ImageView) findViewById(R.id.ivThumbs);
+		thumbsImageView.setImageResource(R.drawable.no_pic);	
+		thumbBitmap=null;
+		TextView countTextView = (TextView) findViewById(R.id.tvPhotoCount);
+		countTextView.setText("no photo");
+
+	}
+	public class UploadTask extends AsyncTask<Void, Void, Boolean>
+	{
+		String err_msg="";
+		@Override
+		protected Boolean doInBackground(Void... params)
+		{
+			boolean bret=true;
+
+
+			SQLiteDatabase db = dbUtil.OpenDB(MainActivity.this, null, true);
+			EditText edit = (EditText) findViewById(R.id.edit);
+			String pid = edit.getText().toString();
+
+			if (Network.NetworkIsAvailable(MainActivity.this))
+			{
+				int verifyresult = Network.VerifyUser(m_sName, m_sPassword);
+				if (verifyresult == Network.RESULT_TRUE)
+				{
+					/* user is authorized */
+					for (int i = 0; i < photoList.size(); i++)
+					{
+						int uploadresult = Network.UploadFile(photoList.get(i),
+								m_sName, m_sPassword, pid);
+						if (uploadresult != Network.RESULT_TRUE)
+						{
+							/*
+							 * upload failed write to local db upload when
+							 * connect to network next time;
+							 */
+
+							/*
+							 * serious error occur must notify user
+							 * immediately
+							 */
+							if (uploadresult == Network.RESULT_LOCALFILE_ERROR)
+								err_msg+="Warring! Local picture file not found!      ";
+							if( uploadresult == Network.RESULT_USERAUTH_ERROR)
+								err_msg+="Warring! Authorize check failed when uploading photos!      ";
+
+							ContentValues cv = new ContentValues();
+							cv.put("picker", m_sName);
+							cv.put("err_code", uploadresult);
+							cv.put("pid", pid);
+							cv.put("local_path", photoList.get(i));
+							db.insert("pics", null, cv);
+							bret=false;
+						}
+						else
+						{
+							/* upload success delete file */
+							File file = new File(photoList.get(i));
+							file.delete();
+						}
+
+					}
+
+				}
+				else
+					if (verifyresult == Network.RESULT_FALSE)
+					{
+						/*
+						 * user is not authorized serious error occur must
+						 * notify user
+						 */
+						Log.e(TAG, "notification====================>");
+						// String text=m_tvalert.getText().toString();
+						err_msg+="Warring! Authorize check failed when uploading photos!";
+						bret=false;
+						for (int i = 0; i < photoList.size(); i++)
+						{
+							ContentValues cv = new ContentValues();
+							cv.put("picker", m_sName);
+							cv.put("err_code", Network.RESULT_USERAUTH_ERROR);
+							cv.put("pid", pid);
+							cv.put("local_path", photoList.get(i));
+							db.insert("pics", null, cv);
+						}
+
+					}
+					else
+					{
+						/* an error occur */
+						for (int i = 0; i < photoList.size(); i++)
+						{
+							ContentValues cv = new ContentValues();
+							cv.put("picker", m_sName);
+							cv.put("err_code", Network.RESULT_NET_ERROR);
+							cv.put("pid", pid);
+							cv.put("local_path", photoList.get(i));
+							db.insert("pics", null, cv);
+						}
+						bret = false;
+					}
+			}
+			else
+			{
+				/*
+				 * net work is not available store into local DB it will auto
+				 * upload when connect to network next time;
+				 */
+
+				for (int i = 0; i < photoList.size(); i++)
+				{
+					ContentValues cv = new ContentValues();
+					cv.put("picker", m_sName);
+					cv.put("err_code", Network.RESULT_NET_ERROR);
+					cv.put("pid", pid);
+					cv.put("local_path", photoList.get(i));
+					db.insert("pics", null, cv);
+				}
+				bret=false;
+				// m_tvalert.setText("Upload failed when uploading photos!");
+
+			}
+
+			dbUtil.CloseDB(db);
+			return bret;
+		}
+
+		@Override
+		protected void onPostExecute(final Boolean success)
+		{
+			if(success)
+			{
+				m_tvalert.setTextColor(getResources().getColor(R.color.message_success));
+				m_tvalert.setText("Upload successed!");
+			}
+			else
+			{
+				m_tvalert.setTextColor(getResources().getColor(R.color.message_fail));
+				m_tvalert.setText(err_msg);
+			}
+			
+			clearfornew();
+			// mAuthTask = null;
+			// showProgress(false);
+			//
+			// if (success) {
+			//
+			// // SharedPreferences.Editor editor = RunOnce.edit();
+			// // editor.putBoolean("FirstRun"+globalUtil.getVerName(this),
+			// false);
+			// // // Don't forget to commit your edits!!!
+			// // editor.commit();
+			// Intent intent = new Intent();
+			// intent.setClass(LoginActivity.this, MainActivity.class);
+			// startActivity(intent);
+			// finish();
+			// } else {
+			// m_etPassword
+			// .setError(getString(R.string.error_incorrect_password));
+			// m_etPassword.requestFocus();
+			// }
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			// mAuthTask = null;
+			// showProgress(false);
+		}
+	}
+
+}

+ 56 - 0
RedAnt Photo/src/com/usai/redant/photo/PreferencesActivity.java

@@ -0,0 +1,56 @@
+/*
+ * 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.usai.redant.photo;
+
+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 = "preferences_decode_1D";
+  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_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_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_CONTINUOUS_FOCUS = "preferences_disable_continuous_focus";
+  //public static final String KEY_DISABLE_EXPOSURE = "preferences_disable_exposure";
+
+  @Override
+  protected void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    getFragmentManager().beginTransaction().replace(android.R.id.content, new PreferencesFragment()).commit();
+
+  }
+
+}

+ 71 - 0
RedAnt Photo/src/com/usai/redant/photo/PreferencesFragment.java

@@ -0,0 +1,71 @@
+/*
+ * 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.usai.redant.photo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+
+public final class PreferencesFragment 
+    extends PreferenceFragment 
+    implements SharedPreferences.OnSharedPreferenceChangeListener {
+  
+  private CheckBoxPreference decode1D;
+  private CheckBoxPreference decodeQR;
+  private CheckBoxPreference decodeDataMatrix;
+  
+  @Override
+  public void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    addPreferencesFromResource(R.xml.preferences);
+    
+    PreferenceScreen preferences = getPreferenceScreen();
+    preferences.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+    decode1D = (CheckBoxPreference) preferences.findPreference(PreferencesActivity.KEY_DECODE_1D);
+    decodeQR = (CheckBoxPreference) preferences.findPreference(PreferencesActivity.KEY_DECODE_QR);
+    decodeDataMatrix = (CheckBoxPreference) preferences.findPreference(PreferencesActivity.KEY_DECODE_DATA_MATRIX);
+    disableLastCheckedPref();
+  }
+  
+  @Override
+  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+    disableLastCheckedPref();
+  }
+
+  private void disableLastCheckedPref() {
+    Collection<CheckBoxPreference> checked = new ArrayList<CheckBoxPreference>(3);
+    if (decode1D.isChecked()) {
+      checked.add(decode1D);
+    }
+    if (decodeQR.isChecked()) {
+      checked.add(decodeQR);
+    }
+    if (decodeDataMatrix.isChecked()) {
+      checked.add(decodeDataMatrix);
+    }
+    boolean disable = checked.size() < 2;
+    CheckBoxPreference[] checkBoxPreferences = {decode1D, decodeQR, decodeDataMatrix};
+    for (CheckBoxPreference pref : checkBoxPreferences) {
+      pref.setEnabled(!(disable && checked.contains(pref)));
+    }
+  }
+}

+ 15 - 0
RedAnt Photo/src/com/usai/redant/photo/UploadService.java

@@ -0,0 +1,15 @@
+package com.usai.redant.photo;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class UploadService extends Service {
+
+	@Override
+	public IBinder onBind(Intent intent) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}

+ 35 - 0
RedAnt Photo/src/com/usai/redant/photo/ViewfinderResultPointCallback.java

@@ -0,0 +1,35 @@
+/*
+ * 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.usai.redant.photo;
+
+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);
+  }
+
+}

+ 187 - 0
RedAnt Photo/src/com/usai/redant/photo/ViewfinderView.java

@@ -0,0 +1,187 @@
+/*
+ * 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.usai.redant.photo;
+
+import com.google.zxing.ResultPoint;
+import com.usai.redant.camera.CameraManager;
+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 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<ResultPoint>(5);
+    lastPossibleResultPoints = null;
+  }
+
+  public void setCameraManager(CameraManager cameraManager) {
+    this.cameraManager = cameraManager;
+  }
+
+  @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<ResultPoint>(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();
+      }
+    }
+  }
+
+}

+ 43 - 0
RedAnt Photo/src/com/usai/util/MD5.java

@@ -0,0 +1,43 @@
+package com.usai.util;
+
+import java.security.MessageDigest;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+public class MD5 {
+    private static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+'A', 'B', 'C', 'D', 'E', 'F' };
+
+    public static void main(String[] args)
+    {
+        System.out.println(md5sum("/init.rc"));
+    }
+
+    public static String toHexString(byte[] b) {
+        StringBuilder sb = new StringBuilder(b.length * 2);
+        for (int i = 0; i < b.length; i++) {
+            sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);
+            sb.append(HEX_DIGITS[b[i] & 0x0f]);
+        }
+        return sb.toString();
+    }
+
+    public static String md5sum(String filename) {
+        InputStream fis;
+        byte[] buffer = new byte[1024];
+        int numRead = 0;
+        MessageDigest md5;
+        try{
+            fis = new FileInputStream(filename);
+            md5 = MessageDigest.getInstance("MD5");
+            while((numRead=fis.read(buffer)) > 0) {
+                md5.update(buffer,0,numRead);
+            }
+            fis.close();
+            return toHexString(md5.digest());  
+        } catch (Exception e) {
+            System.out.println("error");
+            return null;
+        }
+    }
+}

+ 632 - 0
RedAnt Photo/src/com/usai/util/Network.java

@@ -0,0 +1,632 @@
+package com.usai.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntity;
+import org.apache.http.entity.mime.content.FileBody;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.json.JSONObject;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.util.Log;
+
+public class Network
+{
+	private static final int REQUEST_TIMEOUT = 5 * 1000;// request time out 20
+														// secs
+	private static final int SO_TIMEOUT = 5 * 1000; // so time out 20 secs;
+	public static int AP_USER_AUTH = 1;
+	public static int AP_USER_NOT_AUTH = 2;
+	public static int AP_USER_NOT_EXIST = 3;
+	public static int AP_UPLOAD_SUCCESS = 4;
+	public static int AP_UPLOAD_FAIL = 5;
+//
+	public static final int RESULT_FALSE = 0;
+	public static final int RESULT_TRUE = 1;
+	public static final int RESULT_NET_ERROR = 3;
+	public static final int RESULT_ERROR = 5;
+	public static final int RESULT_LOCALFILE_ERROR= 7;
+	public static final int RESULT_USERAUTH_ERROR = 9;
+//	public static final int RESULT_NOCONNECT = 2;
+//	public static final int RESULT_CONNECT = 3;
+//	public static final int RESULT_TIMEOUT = 4;
+//	public static final int RESULT_RESPONSE_NULL= 6;
+//	public static final int RESULT_ERR_USERAUTH= 8;
+
+//	enum RES_VERIFYUSER{RESULT_FALSE,RESULT_TRUE,}
+//	public static int PROTOCAL_FALSE = 0;
+//	public static int PROTOCAL_TRUE = 1;
+//	public static int PROTOCAL_NOT_AUTH = 2;
+//	public static int PROTOCAL_SUCCESS = 1;
+//	public static int PROTOCAL_FAILED = 1;
+	// public static int PROTOCAL_MORE=4;
+//	public static int ERR_LOCALFILE = 0;
+
+//	static String URL_JSON_TEST = "http://192.168.23.1/xampp/json_test.php";
+//	static String URL_VERIFY_USER = "http://192.168.1.10/xampp/verify_user.php";
+//	static String URL_UPLOAD_PHOTO = "http://192.168.1.10/xampp/save_upload_file.php";
+	static String URL_VERIFY_USER = "http://192.168.23.1/xampp/verify_user.php";
+	static String URL_UPLOAD_PHOTO = "http://192.168.23.1/xampp/save_upload_file.php";
+
+//	public static String VerifyUser(String user, String password,
+//			Context context)
+//	{
+//		String TAG = "net_dbg@VerifyUser";
+//		Log.d(TAG, "entry");
+//		try
+//		{
+//			BasicHttpParams httpParams = new BasicHttpParams();
+//			HttpConnectionParams.setConnectionTimeout(httpParams,
+//					REQUEST_TIMEOUT);
+//			HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
+//			HttpClient client = new DefaultHttpClient(httpParams);
+//			HttpPost post = new HttpPost(URL_VERIFY_USER);
+//			MultipartEntity reqEntity = new MultipartEntity(
+//					HttpMultipartMode.BROWSER_COMPATIBLE);
+//			reqEntity.addPart("user", new StringBody(user));
+//			reqEntity.addPart("password", new StringBody(password));
+//
+//			post.setEntity(reqEntity);
+//			HttpResponse response = client.execute(post);
+//			int statucode = response.getStatusLine().getStatusCode();
+//			if (statucode == HttpStatus.SC_OK)
+//			{
+//				HttpEntity resEntity = response.getEntity();
+//				if (resEntity != null)
+//				{
+//					Log.d(TAG,
+//							"Response: content len==>"
+//									+ resEntity.getContentLength());
+//					InputStream is = resEntity.getContent();
+//					try
+//					{
+//
+//						BufferedReader br = new BufferedReader(
+//								new InputStreamReader(is, "utf-8"), 8);
+//						StringBuilder sb = new StringBuilder();
+//						String line = null;
+//						while ((line = br.readLine()) != null)
+//						{
+//							sb.append(line + "\n");
+//						}
+//
+//						Log.d(TAG, "Response: content begin");
+//						Log.d(TAG, sb.toString());
+//						Log.d(TAG, "Response: content end");
+//						return sb.toString();
+//					}
+//					catch (Exception e)
+//					{
+//						Log.e(TAG, e.toString());
+//						// TODO: handle exception
+//					}
+//					finally
+//					{
+//						is.close();
+//
+//					}
+//
+//				}
+//				else
+//				{
+//					/*
+//					 * resEntity is null
+//					 */
+//					Log.d(TAG, "RESPONSE ENTITY IS NULL");
+//					return null;
+//				}
+//
+//			}
+//			else
+//			{
+//				/*
+//				 * Http error; out put error code;
+//				 */
+//				Log.d(TAG, "HTTP " + statucode);
+//
+//				HttpEntity resEntity = response.getEntity();
+//				if (resEntity != null)
+//				{
+//
+//					InputStream is = resEntity.getContent();
+//					try
+//					{
+//
+//						BufferedReader br = new BufferedReader(
+//								new InputStreamReader(is, "utf-8"), 8);
+//						StringBuilder sb = new StringBuilder();
+//						String line = null;
+//						while ((line = br.readLine()) != null)
+//						{
+//							sb.append(line + "\n");
+//						}
+//
+//						Log.d(TAG, "Response: content begin");
+//						Log.d(TAG, sb.toString());
+//						Log.d(TAG, "Response: content end");
+//						return null;
+//					}
+//					catch (Exception e)
+//					{
+//						Log.e(TAG, e.toString());
+//						// TODO: handle exception
+//					}
+//					finally
+//					{
+//						is.close();
+//
+//					}
+//
+//				}
+//				else
+//				{
+//					/*
+//					 * resEntity is null
+//					 */
+//					Log.e(TAG, "RESPONSE ENTITY IS NULL");
+//					return null;
+//				}
+//				return null;
+//			}
+//
+//		}
+//		catch (ConnectTimeoutException e)
+//		{
+//			Log.d(TAG, "request time out");
+//
+//		}
+//		catch (Exception e)
+//		{
+//			Log.d(TAG, e.toString());
+//		}
+//		return null;
+//	}
+
+	public static int VerifyUser(String user, String password)
+	{
+		String TAG = "net_dbg@VerifyUser";
+		Log.d(TAG, "entry");
+		try
+		{
+			BasicHttpParams httpParams = new BasicHttpParams();
+			HttpConnectionParams.setConnectionTimeout(httpParams,
+					REQUEST_TIMEOUT);
+			HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
+			HttpClient client = new DefaultHttpClient(httpParams);
+			HttpPost post = new HttpPost(URL_VERIFY_USER);
+			MultipartEntity reqEntity = new MultipartEntity(
+					HttpMultipartMode.BROWSER_COMPATIBLE);
+			reqEntity.addPart("user", new StringBody(user));
+			reqEntity.addPart("password", new StringBody(password));
+
+			post.setEntity(reqEntity);
+			HttpResponse response = client.execute(post);
+			int statucode = response.getStatusLine().getStatusCode();
+			if (statucode == HttpStatus.SC_OK)
+			{
+				HttpEntity resEntity = response.getEntity();
+				if (resEntity != null)
+				{
+					Log.d(TAG,
+							"Response: content len==>"
+									+ resEntity.getContentLength());
+					InputStream is = resEntity.getContent();
+					try
+					{
+
+						BufferedReader br = new BufferedReader(
+								new InputStreamReader(is, "utf-8"), 8);
+						StringBuilder sb = new StringBuilder();
+						String line = null;
+						while ((line = br.readLine()) != null)
+						{
+							sb.append(line + "\n");
+						}
+
+						Log.d(TAG, "Response: content begin");
+						Log.d(TAG, sb.toString());
+						Log.d(TAG, "Response: content end");
+
+						if (sb.length()<=0)
+						{
+							
+							return RESULT_NET_ERROR;
+						}
+						JSONObject obj = new JSONObject(sb.toString());
+						if (obj.length() > 0)
+						{
+							// JSONObject obj = array.getJSONObject(0);
+							try
+							{
+								int verifyresult = Integer.parseInt(obj
+										.getString("result"));
+								if (verifyresult == Network.AP_USER_AUTH)
+								{
+									return RESULT_TRUE;
+								}
+								else
+								{
+									return RESULT_FALSE;
+								}
+							}
+							catch (Exception e)
+							{
+								Log.e(TAG, e.toString());
+								return RESULT_ERROR;
+							}
+						}
+					}
+					catch (Exception e)
+					{
+						Log.e(TAG, e.toString());
+						return RESULT_ERROR;
+						// TODO: handle exception
+					}
+					finally
+					{
+						is.close();
+
+					}
+
+				}
+				else
+				{
+					/*
+					 * resEntity is null
+					 */
+					Log.d(TAG, "RESPONSE ENTITY IS NULL");
+					return RESULT_NET_ERROR;
+				}
+
+			}
+			else
+			{
+				/*
+				 * Http error; out put error code;
+				 */
+				Log.d(TAG, "HTTP " + statucode);
+
+				HttpEntity resEntity = response.getEntity();
+				if (resEntity != null)
+				{
+
+					InputStream is = resEntity.getContent();
+					try
+					{
+
+						BufferedReader br = new BufferedReader(
+								new InputStreamReader(is, "utf-8"), 8);
+						StringBuilder sb = new StringBuilder();
+						String line = null;
+						while ((line = br.readLine()) != null)
+						{
+							sb.append(line + "\n");
+						}
+
+						Log.d(TAG, "Response: content begin");
+						Log.d(TAG, sb.toString());
+						Log.d(TAG, "Response: content end");
+						return RESULT_ERROR;
+					}
+					catch (Exception e)
+					{
+						Log.e(TAG, e.toString());
+						return RESULT_ERROR;
+						// TODO: handle exception
+					}
+					finally
+					{
+						is.close();
+
+					}
+
+				}
+				else
+				{
+					/*
+					 * resEntity is null
+					 */
+					Log.e(TAG, "RESPONSE ENTITY IS NULL");
+					return RESULT_NET_ERROR;
+				}
+			}
+
+		}
+		catch (ConnectTimeoutException e)
+		{
+			Log.d(TAG, "request time out");
+			return RESULT_NET_ERROR;
+
+		}
+		catch (Exception e)
+		{
+			Log.d(TAG, e.toString());
+			return RESULT_ERROR;
+		}
+		return RESULT_ERROR;
+	}
+
+	public static int UploadFile( String path, String user,
+			String password, String pid)
+	{
+		String TAG = "net_dbg@VerifyUser";
+		Log.d(TAG, "entry");
+
+		Log.d(TAG, "sourcefile:" + path);
+		File file = new File(path);
+
+		if (file.exists() == false)
+			return RESULT_LOCALFILE_ERROR;
+		String md5= MD5.md5sum(path);
+		if(md5==null)
+		{
+			Log.d(TAG, "md5 sum failed");
+			return RESULT_LOCALFILE_ERROR;
+			
+		}
+		try
+		{
+			BasicHttpParams httpParams = new BasicHttpParams();
+			HttpConnectionParams.setConnectionTimeout(httpParams,
+					REQUEST_TIMEOUT);
+			HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
+			HttpClient client = new DefaultHttpClient(httpParams);
+			HttpPost post = new HttpPost(URL_UPLOAD_PHOTO);
+			MultipartEntity reqEntity = new MultipartEntity(
+					HttpMultipartMode.BROWSER_COMPATIBLE);
+			reqEntity.addPart("user", new StringBody(user));
+			reqEntity.addPart("password", new StringBody(password));
+			reqEntity.addPart("pid", new StringBody(pid));
+			reqEntity.addPart("md5", new StringBody(md5));
+			
+			FileBody bin = new FileBody(file);
+			reqEntity.addPart("imagefile", bin);
+			post.setEntity(reqEntity);
+			HttpResponse response = client.execute(post);
+			int statucode = response.getStatusLine().getStatusCode();
+			if (statucode == HttpStatus.SC_OK)
+			{
+				HttpEntity resEntity = response.getEntity();
+				if (resEntity != null)
+				{
+					Log.d(TAG,
+							"Response: content len==>"
+									+ resEntity.getContentLength());
+					InputStream is = resEntity.getContent();
+					try
+					{
+
+						BufferedReader br = new BufferedReader(
+								new InputStreamReader(is, "utf-8"), 8);
+						StringBuilder sb = new StringBuilder();
+						String line = null;
+						while ((line = br.readLine()) != null)
+						{
+							sb.append(line + "\n");
+						}
+
+						Log.d(TAG, "Response: content begin");
+						Log.d(TAG, sb.toString());
+						Log.d(TAG, "Response: content end");
+
+						if (sb.length()<=0)
+						{
+							
+							return RESULT_NET_ERROR;
+						}
+						JSONObject obj = new JSONObject(sb.toString());
+						if (obj.length() > 0)
+						{
+							// JSONObject obj = array.getJSONObject(0);
+							try
+							{
+								int uploadresult = Integer.parseInt(obj
+										.getString("result"));
+								if (uploadresult == Network.AP_UPLOAD_SUCCESS)
+								{
+									return RESULT_TRUE;
+								}
+								else if(uploadresult == Network.AP_USER_NOT_AUTH)
+								{
+									Log.d(TAG,"RESULT_ERR_USERAUTH");
+									return RESULT_USERAUTH_ERROR;
+								}
+								else
+								{
+									return RESULT_FALSE;
+								}
+							}
+							catch (Exception e)
+							{
+								Log.e(TAG, e.toString());
+								return RESULT_FALSE;
+							}
+						}
+					}
+					catch (Exception e)
+					{
+						Log.e(TAG, e.toString());
+						return RESULT_ERROR;
+						// TODO: handle exception
+					}
+					finally
+					{
+						is.close();
+
+					}
+
+				}
+				else
+				{
+					/*
+					 * resEntity is null
+					 */
+					Log.d(TAG, "RESPONSE ENTITY IS NULL");
+					return RESULT_NET_ERROR;
+				}
+
+			}
+			else
+			{
+				/*
+				 * Http error; out put error code;
+				 */
+				Log.d(TAG, "HTTP " + statucode);
+
+				HttpEntity resEntity = response.getEntity();
+				if (resEntity != null)
+				{
+
+					InputStream is = resEntity.getContent();
+					try
+					{
+
+						BufferedReader br = new BufferedReader(
+								new InputStreamReader(is, "utf-8"), 8);
+						StringBuilder sb = new StringBuilder();
+						String line = null;
+						while ((line = br.readLine()) != null)
+						{
+							sb.append(line + "\n");
+						}
+
+						Log.d(TAG, "Response: content begin");
+						Log.d(TAG, sb.toString());
+						Log.d(TAG, "Response: content end");
+						return RESULT_ERROR;
+					}
+					catch (Exception e)
+					{
+						Log.e(TAG, e.toString());
+						return RESULT_ERROR;
+						// TODO: handle exception
+					}
+					finally
+					{
+						is.close();
+
+					}
+
+				}
+				else
+				{
+					/*
+					 * resEntity is null
+					 */
+					Log.e(TAG, "RESPONSE ENTITY IS NULL");
+					return RESULT_NET_ERROR;
+				}
+			}
+
+		}
+		catch (ConnectTimeoutException e)
+		{
+			Log.d(TAG, "request time out");
+			return RESULT_NET_ERROR;
+
+		}
+		catch (Exception e)
+		{
+			Log.d(TAG, e.toString());
+			return RESULT_ERROR;
+		}		
+		
+		return RESULT_FALSE;
+
+//		try
+//		{
+//			HttpClient client = new DefaultHttpClient();
+//			HttpPost post = new HttpPost(url);
+//			MultipartEntity reqEntity = new MultipartEntity(
+//					HttpMultipartMode.BROWSER_COMPATIBLE);
+//			reqEntity.addPart("user", new StringBody(user));
+//			reqEntity.addPart("password", new StringBody(password));
+//			reqEntity.addPart("pid", new StringBody(pid));
+//			FileBody bin = new FileBody(file);
+//			reqEntity.addPart("imagefile", bin);
+//			post.setEntity(reqEntity);
+//			HttpResponse response = client.execute(post);
+//			HttpEntity resEntity = response.getEntity();
+//			if (resEntity != null)
+//			{
+//
+//				String result = EntityUtils.toString(resEntity);
+//				Log.d(TAG, "Response:" + result);
+//				return Integer.parseInt(result);
+//				// if(Boolean.parseBoolean(result)==true)
+//				// return true;
+//				// else
+//				// return false;
+//			}
+//
+//		}
+//		catch (Exception e)
+//		{
+//			e.printStackTrace();
+//		}
+//		return 0;
+	}
+
+	public static boolean NetworkIsAvailable(Context context)
+	{
+		String TAG = "net_dbg@CheckNetwork";
+		ConnectivityManager connManager = (ConnectivityManager) context
+				.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+		NetworkInfo networkInfo = connManager.getActiveNetworkInfo();
+		if (networkInfo == null)
+		{
+			Log.d(TAG, "can not get Active NetworkInfo!");
+			// dbgUtil.Log(Log.DEBUG, "Current Network info",
+			// "can not get Active NetworkInfo!");
+			return false;
+		}
+		NetworkInfo.State netState = networkInfo.getState();
+		if (netState != NetworkInfo.State.CONNECTED)
+		{
+			Log.d(TAG, "not Connected!State=" + netState);
+			// dbgUtil.Log(Log.DEBUG, "Current Network info",
+			// "not Connected!State=" + netState);
+			return false;
+		}
+		// int iconntype = -1;
+		// iconntype = networkInfo.getType();
+
+		// boolean bUseMobileNetwork = context.getSharedPreferences(
+		// "PhoneAsstPref", 0).getBoolean("UseMobileNetwork", false);
+		//
+		// if (bUseMobileNetwork == false
+		// && iconntype != ConnectivityManager.TYPE_WIFI && iconntype != 9/*
+		// earthnet */)
+		// {
+		// Log.d(TAG,);
+		// dbgUtil.Log(Log.DEBUG, "Current Network info",
+		// "not allowed!Connection type=" + networkInfo.getTypeName());
+		// return false;
+		// }
+		boolean bavailable = networkInfo.isAvailable();
+		String strtype = networkInfo.getTypeName();
+
+		Log.d(TAG, " type = " + strtype + " abailable = " + bavailable
+				+ " state " + netState);
+		// dbgUtil.Log(Log.INFO, "Current Network info", " type = " + strtype
+		// + " abailable = " + bavailable + " state " + netState);
+		return bavailable;
+	}
+
+}

+ 66 - 0
RedAnt Photo/src/com/usai/util/SqlOpenHelper.java

@@ -0,0 +1,66 @@
+package com.usai.util;
+
+//import android.R.array;
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class SqlOpenHelper extends SQLiteOpenHelper{
+
+	private ArrayList<String> initSQL = new ArrayList<String>();
+	public void addInitSQL(String sql)
+	{
+		initSQL.add(sql);
+		
+	}
+	public int get_RecordCount(String tablename)
+	{
+		return 0;
+		
+	}
+	public SQLiteDatabase OpenDB(boolean writable)
+	{
+		if (writable)
+			return getWritableDatabase();
+		else
+			return getReadableDatabase();
+	}
+	
+	private void initDB(SQLiteDatabase db)
+	{
+		for(int i=0;i<initSQL.size();i++)
+		{
+			db.execSQL(initSQL.get(i));
+		}
+	
+		
+	}
+	public SqlOpenHelper(Context context, String name, CursorFactory factory,
+			int version) {
+		super(context, name, factory, version);
+		// TODO Auto-generated constructor stub
+	}
+
+	@Override
+	public void onCreate(SQLiteDatabase db) {
+		// TODO Auto-generated method stub
+		initDB(db);
+		
+	}
+
+	@Override
+	public void onOpen(SQLiteDatabase db) {
+		// TODO Auto-generated method stub
+		super.onOpen(db);
+	}
+
+	@Override
+	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов