winstronzeng пре 3 година
родитељ
комит
3a3fbab594
100 измењених фајлова са 9630 додато и 0 уклоњено
  1. 13 0
      .gitignore
  2. 21 0
      .idea/encodings.xml
  3. 21 0
      .idea/gradle.xml
  4. 36 0
      .idea/inspectionProfiles/Project_Default.xml
  5. 9 0
      .idea/misc.xml
  6. 12 0
      .idea/runConfigurations.xml
  7. 6 0
      .idea/vcs.xml
  8. 1 0
      app/.gitignore
  9. 1 0
      app/Readme
  10. 74 0
      app/build.gradle
  11. BIN
      app/libs/ScannerAPI.jar
  12. BIN
      app/libs/android-core-3.1.1-SNAPSHOT.jar
  13. BIN
      app/libs/commons-jymf-label-4.0.jar
  14. BIN
      app/libs/core_3.0.1.jar
  15. BIN
      app/libs/glide-3.7.0.jar
  16. BIN
      app/libs/google-collect-1.0.jar
  17. BIN
      app/libs/httpclient-4.5.13.jar
  18. BIN
      app/libs/httpcore-4.4.13.jar
  19. BIN
      app/libs/pinyin.jar
  20. BIN
      app/libs/pinyin4j-2.5.0.jar
  21. BIN
      app/libs/scan.jar
  22. BIN
      app/libs/sun.misc.BASE64Decoder.jar
  23. BIN
      app/liquidgas.jks
  24. 21 0
      app/proguard-rules.pro
  25. 27 0
      app/src/androidTest/java/com/zz/jiuzdwine/ExampleInstrumentedTest.java
  26. 250 0
      app/src/main/AndroidManifest.xml
  27. BIN
      app/src/main/assets/city.db
  28. 74 0
      app/src/main/java/cilico/tools/barcode/CilicoSoundUtils.java
  29. 104 0
      app/src/main/java/cilico/tools/barcode/FlyScanSetting.java
  30. 22 0
      app/src/main/java/cilico/tools/barcode/PhoneCilicoSoundUtils.java
  31. 96 0
      app/src/main/java/cilico/tools/barcode/PhoneScanner.java
  32. 288 0
      app/src/main/java/cilico/tools/barcode/Scanner.java
  33. 165 0
      app/src/main/java/cilico/tools/barcode/SeuicScanSetting.java
  34. 50 0
      app/src/main/java/cilico/tools/barcode/ddjc/BroadcastConfig.java
  35. 350 0
      app/src/main/java/cilico/tools/barcode/ddjc/ListnerBiz.java
  36. 99 0
      app/src/main/java/cn/jymf/scan/AmbientLightManager.java
  37. 158 0
      app/src/main/java/cn/jymf/scan/BeepManager.java
  38. 515 0
      app/src/main/java/cn/jymf/scan/CaptureActivity.java
  39. 49 0
      app/src/main/java/cn/jymf/scan/FinishListener.java
  40. 149 0
      app/src/main/java/cn/jymf/scan/InactivityTimer.java
  41. 26 0
      app/src/main/java/cn/jymf/scan/IntentSource.java
  42. 278 0
      app/src/main/java/cn/jymf/scan/Intents.java
  43. 122 0
      app/src/main/java/cn/jymf/scan/camera/AutoFocusManager.java
  44. 359 0
      app/src/main/java/cn/jymf/scan/camera/CameraConfigurationManager.java
  45. 435 0
      app/src/main/java/cn/jymf/scan/camera/CameraManager.java
  46. 43 0
      app/src/main/java/cn/jymf/scan/camera/FrontLightMode.java
  47. 67 0
      app/src/main/java/cn/jymf/scan/camera/OpenCameraInterface.java
  48. 65 0
      app/src/main/java/cn/jymf/scan/camera/PreviewCallback.java
  49. 59 0
      app/src/main/java/cn/jymf/scan/common/BitmapUtils.java
  50. 27 0
      app/src/main/java/cn/jymf/scan/common/Runnable.java
  51. 54 0
      app/src/main/java/cn/jymf/scan/config/Config.java
  52. 75 0
      app/src/main/java/cn/jymf/scan/decode/BitmapDecoder.java
  53. 37 0
      app/src/main/java/cn/jymf/scan/decode/BitmapLuminanceSource.java
  54. 222 0
      app/src/main/java/cn/jymf/scan/decode/CaptureActivityHandler.java
  55. 107 0
      app/src/main/java/cn/jymf/scan/decode/DecodeFormatManager.java
  56. 148 0
      app/src/main/java/cn/jymf/scan/decode/DecodeHandler.java
  57. 114 0
      app/src/main/java/cn/jymf/scan/decode/DecodeThread.java
  58. 35 0
      app/src/main/java/cn/jymf/scan/view/ViewfinderResultPointCallback.java
  59. 332 0
      app/src/main/java/cn/jymf/scan/view/ViewfinderView.java
  60. 86 0
      app/src/main/java/cn/net/communal/cpzshandset/MyHandsetApp.java
  61. 148 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ActivateBean.java
  62. 86 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/CarNoBean.java
  63. 47 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ChangeDeviceID.java
  64. 67 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/City.java
  65. 54 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ConfigBean.java
  66. 61 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/DealerInfoBean.java
  67. 160 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/DriverInfoBean.java
  68. 83 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ExchangeCargoBean.java
  69. 163 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/HandsetParameterBean.java
  70. 38 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/HomeBean.java
  71. 94 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/InvoiceBean.java
  72. 100 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/JinLiquorOutWarehouseBean.java
  73. 59 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/JinLiquorUploadBean.java
  74. 58 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/OrderFail.java
  75. 72 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/PackBean.java
  76. 73 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/PackPackageInfoBean.java
  77. 58 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/PackSubLabelInfoBean.java
  78. 18 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ProductBeanList.java
  79. 51 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ProductInfo.java
  80. 41 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ReplenishBingBean.java
  81. 38 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ReturnedGoodsBean.java
  82. 106 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/SaleBean.java
  83. 105 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ShipmentOnlineOrderBean.java
  84. 135 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ShipmentProductBean.java
  85. 134 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/ShipmentUploadRecordBean.java
  86. 77 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/SingleLabelOptionBean.java
  87. 74 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/StationManagerBean.java
  88. 29 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/TestBean.java
  89. 106 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/TrainInvoiceBean.java
  90. 64 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/TruckAddressBean.java
  91. 51 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/TruckConsigeeBean.java
  92. 202 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/TruckInvoiceBean.java
  93. 52 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/UnpackBean.java
  94. 59 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/UploadBean.java
  95. 123 0
      app/src/main/java/cn/net/communal/cpzshandset/bean/WarehouseBean.java
  96. 187 0
      app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/BitmapUtil.java
  97. 47 0
      app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/FileCache.java
  98. 285 0
      app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/ImageLoader.java
  99. 840 0
      app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/MBitmapService.java
  100. 83 0
      app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/MemoryCache.java

+ 13 - 0
.gitignore

@@ -0,0 +1,13 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild

+ 21 - 0
.idea/encodings.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" addBOMForNewFiles="with NO BOM">
+    <file url="file://$PROJECT_DIR$/app/libs/ScannerAPI.jar" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/libs/core_3.0.1.jar" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/libs/scan.jar" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/libs/sun.misc.BASE64Decoder.jar" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/CilicoSoundUtils.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/CilicoSoundUtils.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/FlyScanSetting.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/FlyScanSetting.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/PhoneCilicoSoundUtils.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/PhoneScanner.java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/Scanner.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/Scanner.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/SeuicScanSetting.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cilico/tools/barcode/SeuicScanSetting.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cn/net/handsetlib/common/HandsetConstant.java" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/app/src/main/java/cn/net/handsetlib/common/HandsetConstant.java" charset="GBK" />
+  </component>
+</project>

+ 21 - 0
.idea/gradle.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <compositeConfiguration>
+          <compositeBuild compositeDefinitionSource="SCRIPT" />
+        </compositeConfiguration>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+          </set>
+        </option>
+        <option name="resolveModulePerSourceSet" value="false" />
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 36 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,36 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="TOP_LEVEL_CLASS_OPTIONS">
+        <value>
+          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+          <option name="REQUIRED_TAGS" value="" />
+        </value>
+      </option>
+      <option name="INNER_CLASS_OPTIONS">
+        <value>
+          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+          <option name="REQUIRED_TAGS" value="" />
+        </value>
+      </option>
+      <option name="METHOD_OPTIONS">
+        <value>
+          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+          <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
+        </value>
+      </option>
+      <option name="FIELD_OPTIONS">
+        <value>
+          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+          <option name="REQUIRED_TAGS" value="" />
+        </value>
+      </option>
+      <option name="IGNORE_DEPRECATED" value="false" />
+      <option name="IGNORE_JAVADOC_PERIOD" value="true" />
+      <option name="IGNORE_DUPLICATED_THROWS" value="false" />
+      <option name="IGNORE_POINT_TO_ITSELF" value="false" />
+      <option name="myAdditionalJavadocTags" value="date" />
+    </inspection_tool>
+  </profile>
+</component>

+ 9 - 0
.idea/misc.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+</project>

+ 12 - 0
.idea/runConfigurations.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RunConfigurationProducerService">
+    <option name="ignoredProducers">
+      <set>
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
+      </set>
+    </option>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 1 - 0
app/.gitignore

@@ -0,0 +1 @@
+/build

+ 1 - 0
app/Readme

@@ -0,0 +1 @@
+通用版app 标准版通用版

+ 74 - 0
app/build.gradle

@@ -0,0 +1,74 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 26
+    buildToolsVersion "29.0.3"
+
+    defaultConfig {
+        applicationId "cn.net.communal.cpzshandset"
+        minSdkVersion 16
+        targetSdkVersion 28
+        versionCode 1
+        versionName "1.3.1"
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+//        ndk {
+//            abiFilters "armeabi", "armeabi-v7a"
+////// 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之类的so会被过滤掉)
+//        }
+    }
+//    splits {
+//        abi {
+//            enable true
+//            reset()
+//            include 'x86', 'armeabi-v7a'
+//            universalApk true
+//        }
+//    }
+    signingConfigs {
+        release {
+            storeFile file('liquidgas.jks')
+            keyAlias "liquid"
+            keyPassword "liquid"
+            storePassword "liquid"
+        }
+        debug {
+            storeFile file('liquidgas.jks')
+            keyAlias "liquid"
+            keyPassword "liquid"
+            storePassword "liquid"
+        }
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    lintOptions {
+        checkReleaseBuilds false
+        abortOnError false
+
+    }
+    packagingOptions {
+        exclude 'META-INF/DEPENDENCIES'
+//        exclude 'META-INF/NOTICE'
+//        exclude 'META-INF/LICENSE'
+//        exclude 'META-INF/LICENSE.txt'
+//        exclude 'META-INF/NOTICE.txt'
+    }
+}
+
+dependencies {
+    implementation fileTree(include: ['*.jar'], dir: 'libs')
+    testImplementation 'junit:junit:4.12'
+    implementation 'com.android.support:appcompat-v7:26.0.0'
+    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
+    implementation files('libs/scan.jar')
+    implementation files('libs/core_3.0.1.jar')
+    implementation files('libs/commons-jymf-label-4.0.jar')
+    implementation files('libs/httpclient-4.5.13.jar')
+    implementation files('libs/httpcore-4.4.13.jar')
+    implementation 'com.github.ctiao:ndkbitmap-armv5:0.9.21'
+    implementation 'com.github.ctiao:ndkbitmap-x86:0.9.21'
+    implementation 'com.facebook.stetho:stetho:1.3.1'
+}

BIN
app/libs/ScannerAPI.jar


BIN
app/libs/android-core-3.1.1-SNAPSHOT.jar


BIN
app/libs/commons-jymf-label-4.0.jar


BIN
app/libs/core_3.0.1.jar


BIN
app/libs/glide-3.7.0.jar


BIN
app/libs/google-collect-1.0.jar


BIN
app/libs/httpclient-4.5.13.jar


BIN
app/libs/httpcore-4.4.13.jar


BIN
app/libs/pinyin.jar


BIN
app/libs/pinyin4j-2.5.0.jar


BIN
app/libs/scan.jar


BIN
app/libs/sun.misc.BASE64Decoder.jar


BIN
app/liquidgas.jks


+ 21 - 0
app/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 27 - 0
app/src/androidTest/java/com/zz/jiuzdwine/ExampleInstrumentedTest.java

@@ -0,0 +1,27 @@
+package com.zz.jiuzdwine;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.zz.jiuzdwine", appContext.getPackageName());
+    }
+}

+ 250 - 0
app/src/main/AndroidManifest.xml

@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="cn.net.communal.cpzshandset"
+    android:versionCode="1"
+    android:versionName="1.2.0" >
+
+
+    <!-- 安装权限 -->
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
+    <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+
+    <uses-feature android:name="android.hardware.camera" />
+    <uses-feature android:name="android.hardware.camera.autofocus" />
+
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.GET_TASKS" />
+
+    <application
+        android:name=".MyHandsetApp"
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:usesCleartextTraffic="true"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".ui.activity.SplashActivity"
+            android:screenOrientation="portrait" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".ui.activity.HomeActivity"
+            android:launchMode="singleTask" >
+
+            <!--
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            -->
+
+        </activity>
+        <activity android:name=".test.TestActivity" >
+
+            <!--
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+
+            -->
+        </activity>
+        <activity
+            android:name="cn.jymf.scan.CaptureActivity"
+            android:configChanges="orientation|keyboardHidden"
+            android:launchMode="singleTop"
+            android:screenOrientation="portrait"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            android:windowSoftInputMode="stateAlwaysHidden" >
+        </activity>
+        <activity
+            android:name=".ui.activity.OptionHistoryListStyleActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.ActivateConfigActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.SettingActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.DeviceIdConfigActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.ProductDetailListActivity"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.PackConfigActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.UnpackActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.WarehouseConfigActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.SaleConfigActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.SingleLabelScannerActivity"
+            android:launchMode="singleTop" >
+
+            <!-- 王哥测试使用 -->
+            <!--
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            -->
+        </activity>
+        <activity
+            android:name=".ui.activity.BatchLabelScannerActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.ProductDetailGvActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.JianCeActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.UploadStatusActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.ModifyHandsetVersionActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.TrainInvoiceConfigActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.ChoiceAddressStyleActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.ShipmentScannerActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.TruckInvoiceConfigActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.TruckInvoiceInputStyleConfigActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.SearchByInputStyleActivity"
+            android:windowSoftInputMode="adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.ShipmentSingleScannerActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name="cn.net.communal.cpzshandset.ui.activity.QueryActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateHidden|adjustResize" >
+        </activity>
+        <activity
+            android:name=".ui.activity.LoginActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.ExchangeCargoConfigActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.InputQRCodeActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.OptionSubListStyleActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.CheckLabelStatusActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".common.bitmap.crop.ContractImageActivity"
+            android:screenOrientation="portrait"
+            android:theme="@android:style/Theme.Black.NoTitleBar" >
+        </activity>
+        <activity
+            android:name=".common.bitmap.crop.CropImageActivity"
+            android:screenOrientation="portrait"
+            android:theme="@android:style/Theme.Black.NoTitleBar" >
+        </activity>
+        <activity
+            android:name=".ui.activity.CarNoDetailListActivity"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="adjustPan|stateHidden" >
+        </activity>
+        <activity
+            android:name=".ui.activity.CarSaleConfigActivity"
+            android:launchMode="singleTop" >
+        </activity>
+        <activity
+            android:name=".ui.activity.CarLingLiaoChuKuAvtivity"
+            android:launchMode="singleTop" >
+        </activity>
+
+        <provider
+            android:name="android.support.v4.content.FileProvider"
+            android:authorities="cn.net.communal.cpzshandset.pro.fileprovider"
+            android:exported="false"
+            android:grantUriPermissions="true" >
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/file_paths" />
+        </provider>
+    </application>
+
+</manifest>

BIN
app/src/main/assets/city.db


+ 74 - 0
app/src/main/java/cilico/tools/barcode/CilicoSoundUtils.java

@@ -0,0 +1,74 @@
+package cilico.tools.barcode;
+
+import android.annotation.SuppressLint;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+
+public class CilicoSoundUtils {
+
+	private final static int duration = 1; // seconds
+	private final static int sampleRate = 2000;
+	private final static int numSamples = duration * sampleRate;
+	private final static double sample[] = new double[numSamples];
+	private final static double freqOfTone = 1600; // hz
+	private final static byte generatedSnd[] = new byte[2 * numSamples];
+
+	public static void genTone() {
+		// fill out the array
+		for (int i = 0; i < numSamples; ++i) {
+			sample[i] = Math.sin(2 * Math.PI * i / (sampleRate / freqOfTone));
+		}
+
+		int idx = 0;
+		for (double dVal : sample) {
+			short val = (short) (dVal * 32767);
+			generatedSnd[idx++] = (byte) (val & 0x00ff);
+			generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
+		}
+
+	}
+
+	@SuppressLint("NewApi")
+	public static void playSound() {
+		AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
+				AudioFormat.CHANNEL_CONFIGURATION_MONO,
+				AudioFormat.ENCODING_PCM_16BIT, numSamples,
+				AudioTrack.MODE_STATIC);
+		audioTrack.write(generatedSnd, 0, numSamples);
+		audioTrack.play();
+		try {
+			Thread.sleep(30);
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		audioTrack.release();
+
+	}
+
+	/**
+	 * 成功声音 2014-5-9下午12:38:54
+	 */
+	public static void play() {
+		Thread thread = new Thread(new Runnable() {
+			public void run() {
+				genTone();
+				playSound();
+			}
+		});
+		thread.start();
+	}
+
+	/**
+	 * 扫描按钮事件 2014-5-19下午3:17:19
+	 * 
+	 * @param keyCode
+	 */
+	public static void scanKeyDown(int keyCode) {
+		if ((keyCode == 211 | keyCode == 212)) {
+			Scanner.Read();
+		}
+	}
+
+}

+ 104 - 0
app/src/main/java/cilico/tools/barcode/FlyScanSetting.java

@@ -0,0 +1,104 @@
+package cilico.tools.barcode;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build;
+
+import com.olc.scan.ScanManager;
+
+/**
+ * @Description: java类作用描述 富力叶手持机 scan 设置
+ * @Author: winstronzeng
+ * @CreateDate: 2020/4/15 16:44
+ * @UpdateUser: 更新者:
+ * @UpdateDate: 2020/4/15 16:44
+ * @UpdateRemark: 更新说明:
+ * @Version: 1.0
+ */
+public class FlyScanSetting {
+    private final static String MANUFACTURER = "alps";
+    private final static String MODEL = "Android Handheld Terminal";
+    private final String SCAN_KEY = "com.barcode.sendBroadcast";
+    private ScanCodeBroadcastReceiver receiver;
+    private ScanCodeResult scanCodeResult;
+
+    public FlyScanSetting onCreate(Activity activity, ScanCodeResult scanCodeResult) {
+        String manufacturer = Build.MANUFACTURER;
+        String model = Build.MODEL;
+        if (manufacturer.contains(MANUFACTURER) || model.contains(MODEL)) {
+            setScanModel(activity);
+        }
+        this.scanCodeResult = scanCodeResult;
+        receiver = new ScanCodeBroadcastReceiver();
+        final IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(SCAN_KEY);
+        activity.getApplicationContext().registerReceiver(receiver, intentFilter);
+        return this;
+    }
+
+    private void setScanModel(Activity activity) {
+        String serviceName = "olc_service_scan";
+        ScanManager sm = (ScanManager) activity.getSystemService(serviceName);
+        if (null == sm) {
+            return;
+        }
+        sm.setScanSwitchLeft(true);
+        sm.setScanSwitchMiddle(true);
+        sm.setScanSwitchRight(true);
+        sm.setBarcodeReceiveModel(2);
+    }
+
+    public void onDestroy(Activity activity) {
+        if (null != activity && null != receiver) {
+        
+            activity.getApplicationContext().unregisterReceiver(receiver);
+        }
+    }
+
+    private class ScanCodeBroadcastReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (null != intent) {
+                if (SCAN_KEY.equals(intent.getAction())) {
+                    String codeKey = "BARCODE";
+                    String codeSource = intent.getStringExtra(codeKey);
+                    if (null != scanCodeResult) {
+                        scanCodeResult.scanCodeResultByBroadcastReceiver(codeSource);
+                    }
+                }
+            }
+        }
+    }
+
+    public interface ScanCodeResult {
+        /**
+         * 扫描结果
+         *
+         * @param code code
+         */
+        void scanCodeResultByBroadcastReceiver(String code);
+    }
+
+    /**
+     * 是否是手机
+     * @return boolean
+     */
+    public static boolean isHandPhone() {
+        String manufacturer = Build.MANUFACTURER;
+        String model = Build.MODEL;
+        return manufacturer.contains(MANUFACTURER) || model.contains(MODEL);
+    }
+
+    /**
+     * 调用手持机红外扫描
+     */
+    public static void startHandScan(Context activity) {
+        Intent intent = new Intent();
+        intent.setAction("com.barcode.sendBroadcastScan");
+        activity.sendBroadcast(intent);
+    }
+}

+ 22 - 0
app/src/main/java/cilico/tools/barcode/PhoneCilicoSoundUtils.java

@@ -0,0 +1,22 @@
+package cilico.tools.barcode;
+
+
+public class PhoneCilicoSoundUtils extends CilicoSoundUtils{
+
+	/**
+	 * 成功声音 2014-5-9下午12:38:54
+	 */
+	public static void play() {
+		if(PhoneScanner.isPhone){
+			//是手机,就手机的声音播放
+			return;
+		}
+		Thread thread = new Thread(new Runnable() {
+			public void run() {
+				genTone();
+				playSound();
+			}
+		});
+		thread.start();
+	}
+}

+ 96 - 0
app/src/main/java/cilico/tools/barcode/PhoneScanner.java

@@ -0,0 +1,96 @@
+package cilico.tools.barcode;
+
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.KeyEvent;
+import android.widget.Toast;
+
+import cilico.tools.barcode.ddjc.BroadcastConfig;
+import cn.jymf.scan.CaptureActivity;
+import cn.net.communal.cpzshandset.R;
+import cn.net.communal.cpzshandset.common.config.ConfigCreateService;
+import cn.net.communal.cpzshandset.common.util.CacheGet;
+import cn.net.communal.cpzshandset.ui.activity.base.BaseScanActivity;
+import cn.net.handsetlib.common.HandsetConstant;
+
+/**
+ * 扫描和摄像头切换
+ *
+ * @author zwj
+ * <p>
+ * 2015-3-10
+ */
+public class PhoneScanner extends Scanner {
+    static public boolean isPhone = false;
+    static boolean open;
+
+    static public void Read(ConfigCreateService createService, CacheGet cacheG, Context context) {
+        int scannerMode = createService.getScannerMode(cacheG, context);
+        if (scannerMode == 1) {
+            Intent intent = new Intent(context, CaptureActivity.class);
+            context.startActivity(intent);
+        } else if (SeuicScanSetting.isHandPhone()) {
+
+            //东大集成的手持机扫码
+//            Intent intent = new Intent(BroadcastConfig.SCAN_START);
+//            context.sendBroadcast(intent);
+//            com.seuic.scanner.Scanner scanner = ScannerFactory.getScanner(context.getApplicationContext());
+            if (context.getClass().getSuperclass() == BaseScanActivity.class) {
+//                SeuicScanSetting.startHandScan();
+            }
+//			Intent intent = new Intent();
+//			intent.setAction("com.barcode.sendBroadcastScan");
+//			sendBroadcast(intent);
+        } else {
+            // 2021-08-12
+			if(HandsetConstant.isHHW()){
+				Intent intent = new Intent(BroadcastConfig.SCAN_START);
+				context.sendBroadcast(intent);
+			}else{
+				String version = android.os.Build.VERSION.RELEASE;
+				if (version.equals("4.2.2")) {
+
+					Read();
+				}else {
+                    // 2021-08-12   富力叶的 手动扫描
+					Intent intent = new Intent(BroadcastConfig.SCAN_START);
+					context.sendBroadcast(intent);
+				}
+//				ScanHelper.setScanSound(MainActivity.this, bsound);
+			}
+        }
+    }
+
+    /**
+     * 屏蔽返回,搜索,菜单三个按钮, HOME这个键无法屏蔽,暂时没找到好的办法 2014-7-23下午9:21:47
+     *
+     * @param keyCode
+     * @return
+     */
+    public static boolean isShieldKey(int keyCode) {
+        if (keyCode == KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH
+                || keyCode == KeyEvent.KEYCODE_BACK) {
+            // KEYCODE_HOME这个键无法屏蔽,暂时没找到好的办法
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 点击两次后才返回或者退出 2014-7-22下午9:16:14
+     *
+     * @param difTime 时间差 1s内点击两次作为退出
+     * @param context
+     * @return
+     */
+    public static boolean doubleBack(Long difTime, Context context) {
+        if (difTime < 1000) {
+            return true;
+        } else {
+            // 这样就显示一次Toast
+            Toast.makeText(context, context.getString(R.string.dialog_back_ui), Toast.LENGTH_SHORT).show();
+        }
+        return false;
+    }
+}

+ 288 - 0
app/src/main/java/cilico/tools/barcode/Scanner.java

@@ -0,0 +1,288 @@
+package cilico.tools.barcode;
+
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+import cn.net.cpzslibs.label.LabelUtils;
+import cn.net.handsetlib.utils.ReadDeviceIDUtil;
+
+public class Scanner {
+	private static String TAG = "echoScanner";
+	/**
+	 * Tab建作为分隔符,商城模式的商铺id
+	 */
+	public static String splitStr = "	";
+	/**
+	 * 是设置设备id的界面
+	 */
+	public static boolean isDeviceId = false;
+	public static boolean isForTestData = false;//读取的数据不做任何处理,直接返回
+	/**
+	 * 扫描内容
+	 */
+	static public final int BARCODE_READ = 10;
+	/**
+	 * 未扫描到内容
+	 */
+	static public final int BARCODE_NOREAD = 12;
+	/**
+	 * 扫描非16位追溯码
+	 */
+	static public final int BARCODE_ERR_LABEL = 13;
+	/**
+	 * 扫描设备id错误
+	 */
+	static public final int BARCODE_ERR_DeviceID = 14;
+
+	static Boolean m_bASYC = false;
+	static int m_nCommand = 0;
+	static public Handler m_handler = null;
+
+	/**
+	 * 同步扫描一维/二维码,扫描不到将等待一段时间,摩托罗拉的扫描头等待最长3秒,
+	 * 自主研发扫描头最长等待10秒,自动识别是自主研发扫描头还是摩托罗拉的扫描头
+	 * 
+	 * @return :返回扫描到的条码,如果没扫到将为空字符串
+	 */
+	static public native String ReadSCAAuto();
+
+	/**
+	 * 同步扫描一维/二维码,扫描不到将等待一段时间,摩托罗拉的扫描头等待最长3秒, 自主研发扫描头最长等待10秒
+	 * 
+	 * @param nCode
+	 *            :扫描头标示,自主研发扫描头0x55,摩托罗拉扫描头0x00
+	 * @return :返回扫描到的条码,如果没扫到将为空字符串
+	 */
+	static public native String ReadSCA(int nCode);
+
+	/**
+	 * 同步扫描一维/二维码,扫描不到将等待一段时间,摩托罗拉的扫描头等待最长3秒, 自主研发扫描头最长等待10秒
+	 * 
+	 * @param nCommand
+	 *            :扫描头标示,自主研发扫描头0x55,摩托罗拉扫描头0x00
+	 * @param nCode
+	 *            :条码的编码方式,GB2312为1,UTF为0
+	 * @return :返回扫描到的条码,如果没扫到将为空字符串
+	 */
+	static public native String ReadSCAEx(int nCommand, int nCode);
+
+	/**
+	 * 同步扫描一维/二维码,扫描不到将等待一段时间,摩托罗拉的扫描头等待最长3秒, 自主研发扫描头最长等待10秒
+	 * 
+	 * @param nCommand
+	 *            :扫描头标示,自主研发扫描头0x55,摩托罗拉扫描头0x00
+	 * @param buf
+	 *            :存放条码内容,读回来后根据条码本身格式转成字符串
+	 * @return :返回扫描到的条码,如果没扫到将为空字符串
+	 */
+	static public native int ReadDataSCA(int nCommand, byte[] buf);
+
+	/**
+	 * 同步扫描一维/二维码,扫描不到将等待一段时间,摩托罗拉的扫描头等待最长3秒, 自主研发扫描头最长等待10秒
+	 * 
+	 * @param nCommand
+	 *            :扫描头标示,自主研发扫描头0x55,摩托罗拉扫描头0x00
+	 * @return :返回扫描到的条码内容
+	 */
+	static public native byte[] ReadData(int nCommand);
+
+	/**
+	 * 初始化设备
+	 * 
+	 * @return :成功返回0
+	 */
+	static public native int InitSCA();
+
+	/**
+	 * 异步扫描,调用该函数会创建一个扫描线程去扫描, 扫描到条码或者扫描超时都会通过handle发送消息给接受者,
+	 * 所以使用异步扫描的话必须在你的接收代码里创建个handle, 并把handle赋给m_handler,扫描到条码发送Message
+	 * BARCODE_READ, 超时发送Message BARCODE_NOREAD
+	 */
+	static public void Read() {
+//		Log.e("echo", "m_bASYC:" + m_bASYC);
+		if (m_bASYC) {
+			return;
+		} else {
+			// m_nCommand=nCode;
+			StartASYC();
+		}
+	}
+
+	/**
+	 * 扫描线程
+	 */
+	static void StartASYC() {
+		m_bASYC = true;
+		Thread thread = new Thread(new Runnable() {
+			public void run() {
+
+				if (m_handler != null) {
+					// ----------------------add by echo at 2016-10-9
+					// 15:05:19------用于有些扫描头读取慢,读取数据不全的问题------------------------------------------------------------------------------------
+					/*
+					 * try { Thread.sleep(100); } catch (InterruptedException e)
+					 * { // TODO Auto-generated catch block e.printStackTrace();
+					 * }
+					 */
+					// ----------------------add by echo at 2016-10-9
+					// 15:05:19------------------------------------------------------------------------------------------
+//					--------------------测试回车使用---------------------------------------------------------
+//					StringBuffer sb = new StringBuffer();
+//					boolean end = false;
+//					while(!end){
+//						String str1 = ReadSCAAuto().trim();
+//						if (str1.endsWith("\n")) {
+//							end = true;
+//						}
+//						sb.append(str1);
+//					}
+//					String str = sb.toString().trim();
+//					--------------------测试回车使用---------------------------------------------------------
+					
+					String str = ReadSCAAuto().trim();
+					Message msg = new Message();
+					msg.what = str.length() > 0 ? BARCODE_READ : BARCODE_NOREAD;
+					Log.d(TAG, "StartASYC  ReadSCAAuto: 读取数据完成" + str);
+					/*if (str.endsWith("\n")) {
+						Log.i("Scanner", "换行符");
+					}*/
+					if (str.length() <= 0) {
+						m_handler.sendMessage(msg);
+						m_bASYC = false;
+						return;
+					}
+					
+					//------------------------------------测试使用---------------------------------
+					//读取的数据不做任何处理,直接返回
+					if (isForTestData) {
+						m_bASYC = false;
+						msg.obj = str;
+						m_handler.sendMessage(msg);
+						return;
+					}
+					
+					str = LabelUtils.getLabelSplits(str);
+					if (isNumber(str)) {
+						// 这里要判断扫描的是否为数字
+						if (LabelUtils.checkLabelLength(str)) {// 简单验证追溯码的合法性
+							msg.obj = str;
+						} else {
+							msg.what = BARCODE_ERR_LABEL;
+							msg.obj = str;
+						}
+					} else {
+						if (isDeviceId) {
+							String deviceId = ReadDeviceIDUtil.readScanDecrypt(str);
+							if (isNumber(deviceId) || deviceId.contains(splitStr)) {
+								// 是设备id加密文件||商城模式,tab前为设备id,后为产品id
+								msg.obj = str;
+							} else {
+								msg.what = BARCODE_ERR_DeviceID;
+								msg.obj = "扫描设备id错误";
+							}
+						} else {
+							msg.what = BARCODE_ERR_LABEL;
+							msg.obj = str;
+						}
+					}
+					m_handler.sendMessage(msg);
+				}
+				m_bASYC = false;
+			}
+		});
+		thread.start();
+	}
+
+	/**
+	 * 虚拟键盘消息,可以把String按键盘消息方式发送给系统
+	 * 
+	 * @param str
+	 *            :要发送的字符串
+	 */
+	static public void SendString(String str) {
+		try {
+			Runtime.getRuntime().exec("input keyevent 66");
+			Runtime.getRuntime().exec("input text " + str);
+
+		} catch (IOException e) {
+			// Auto-generated catch block
+			e.printStackTrace();
+			Log.i("run", e.toString());
+		}
+	}
+
+	static private void showToast(String str) {
+		Toast.makeText(null, str, Toast.LENGTH_SHORT).show();
+	}
+
+	static {
+		// System.loadLibrary("Cilico-Scan");
+//		System.loadLibrary("tiny-tools");
+	}
+
+	/**
+	 * 
+	 * 发送内容<br/>
+	 * 2015-1-29下午12:59:34
+	 * 
+	 * @param m_handler
+	 * @param scanContent
+	 *            扫描到的内容
+	 */
+	public static void sendHandler(String scanContent) {
+		if (m_handler != null) {
+			Message msg = new Message();
+			msg.what = scanContent.length() > 0 ? BARCODE_READ : BARCODE_NOREAD;
+			// --------------修改扫码相关-------------------------------------------------
+			Log.d(TAG, "sendHandler:" + scanContent);
+			if (isDeviceId) {
+				msg.what = BARCODE_READ;
+				msg.obj = scanContent;
+				m_handler.sendMessage(msg);
+				return;
+			}
+			scanContent = LabelUtils.getLabelSplits(scanContent);
+
+			if (isNumber(scanContent)) {
+				// 这里要判断扫描的是否为数字
+				if (scanContent.length() >= 16) {// 简单验证追溯码的合法性
+					msg.obj = scanContent;
+				} else if (scanContent.length() > 0) {
+					msg.what = BARCODE_ERR_LABEL;
+					msg.obj = scanContent;
+				}
+			} else {
+				String deviceId = ReadDeviceIDUtil.readScanDecrypt(scanContent).trim();
+				if (isDeviceId) {
+					if (isNumber(deviceId) || deviceId.contains(splitStr)) {
+						// 是设备id加密文件||//商城模式,tab前为设备id,后为产品id
+						msg.obj = scanContent;
+					} else {
+						msg.what = BARCODE_ERR_DeviceID;
+						msg.obj = "扫描设备id错误";
+					}
+				} else {
+					msg.what = BARCODE_ERR_LABEL;
+					msg.obj = scanContent;
+				}
+			}
+			m_handler.sendMessage(msg);
+
+		}
+	}
+
+	/**
+	 * 判断是不是数字 2014-5-28下午1:56:22
+	 * 
+	 * @param str
+	 * @return
+	 */
+	public static boolean isNumber(String str) {
+		return Pattern.compile("^\\d*$").matcher(str).matches();
+	}
+}

+ 165 - 0
app/src/main/java/cilico/tools/barcode/SeuicScanSetting.java

@@ -0,0 +1,165 @@
+package cilico.tools.barcode;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build;
+import android.util.Log;
+
+import com.seuic.scanner.Scanner;
+import com.seuic.scanner.ScannerFactory;
+
+/**
+ * @Description: java类作用描述 东大手持机 scan 设置
+ * @Author: winstronzeng
+ * @CreateDate: 2020/4/15 16:44
+ * @UpdateUser: 更新者:
+ * @UpdateDate: 2020/4/15 16:44
+ * @UpdateRemark: 更新说明:
+ * @Version: 1.0
+ */
+public class SeuicScanSetting {
+	private final static String MANUFACTURER = "SEUIC";
+	private final static String MANUFACTURER_AUTOID = "AUTOID";
+	private final static String MODEL = "CRUISE Ge";
+	private String acceptKey = "BARCODE";
+	private ScanCodeBroadcastReceiver receiver;
+	private SeuicScanCodeResult scanCodeResult;
+	private String broadCastName = "com.lib.seuiclibrary.broadcast";
+	private boolean isShow = true;
+	private static Scanner scanner;
+
+	public static void init(Context context) {
+		if (isHandPhone()) {
+			scanner = ScannerFactory
+					.getScanner(context.getApplicationContext());
+	
+			boolean open = scanner.open();
+			Log.e("open", "open=" + open);
+		}
+	}
+
+	public static void closeScan() {
+		if (null != scanner) {
+			scanner.close();
+		}
+	}
+
+	public SeuicScanSetting onCreate(Activity activity,
+                                     SeuicScanCodeResult scanCodeResult) {
+		String manufacturer = Build.MANUFACTURER;
+		String model = Build.MODEL;
+		Log.e("MODEL", "MODEL==" + model + ",manufacturer=" + manufacturer);
+		if (manufacturer.contains(MANUFACTURER)
+				|| manufacturer.contains(MANUFACTURER_AUTOID)
+				|| model.contains(MODEL)) {
+			// 东大集成的手持机扫码
+			setScanModel(activity);
+			setReceiverKeyModel(activity);
+			this.scanCodeResult = scanCodeResult;
+			receiver = new ScanCodeBroadcastReceiver();
+			IntentFilter intentFilter = new IntentFilter(broadCastName);
+			activity.registerReceiver(receiver, intentFilter);
+		}
+		return this;
+	}
+
+	/**
+	 * “FOCUS”: 焦点录入 “BROADCAST”: 广播 “EMUKEY”: 模拟按键 “CLIPBOARD”: 剪贴板
+	 * 
+	 * @param activity
+	 */
+	private void setScanModel(Activity activity) {
+		Intent intent = new Intent("com.android.scanner.service_settings");
+		intent.putExtra("barcode_send_mode", "BROADCAST");
+		activity.sendBroadcast(intent);
+	}
+
+	/**
+	 * 条码广播设置
+	 */
+	private void setReceiverKeyModel(Activity activity) {
+		Intent intent = new Intent("com.android.scanner.service_settings");
+		intent.putExtra("action_barcode_broadcast", broadCastName);
+		intent.putExtra("key_barcode_broadcast", acceptKey);
+		activity.sendBroadcast(intent);
+	}
+
+	public void onStop(Activity activity) {
+		isShow = false;
+	}
+
+	public void onResume(Activity activity) {
+		isShow = true;
+	}
+
+	public void onDestroy(Activity activity) {
+		if (null != activity && null != receiver) {
+			activity.unregisterReceiver(receiver);
+		}
+	}
+
+	private class ScanCodeBroadcastReceiver extends BroadcastReceiver {
+
+		@Override
+		public void onReceive(Context context, Intent intent) {
+			if (isShow) {
+				if (null != intent) {
+					if (broadCastName.equals(intent.getAction())) {
+						String codeSource = intent.getStringExtra(acceptKey);
+						if (null != scanCodeResult) {
+							scanCodeResult
+									.scanCodeSeuicResultByBroadcastReceiver(codeSource);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	public interface SeuicScanCodeResult {
+		/**
+		 * 扫描结果
+		 * 
+		 * @param code
+		 *            code
+		 */
+		void scanCodeSeuicResultByBroadcastReceiver(String code);
+	}
+
+	/**
+	 * 是否是手机
+	 * 
+	 * @return boolean
+	 */
+	public static boolean isHandPhone() {
+		String manufacturer = Build.MANUFACTURER;
+		String model = Build.MODEL;
+		return manufacturer.contains(MANUFACTURER)
+				|| manufacturer.contains(MANUFACTURER_AUTOID)
+				|| model.contains(MODEL);
+	}
+
+	/**
+	 * 调用手持机红外扫描
+	 */
+	public static void startHandScan() {
+		if (null != scanner) {
+			scanner.startScan();
+			// 通过广播形式接收code
+			// scanner.setDecodeInfoCallBack(new DecodeInfoCallBack() {
+			// @Override
+			// public void onDecodeComplete(DecodeInfo decodeInfo) {
+			// scanner.stopScan();
+			// if (null != scanCodeResult) {
+			// scanCodeResult.scanCodeSeuicResultByBroadcastReceiver(decodeInfo.barcode);
+			// }
+			// }
+			// });
+			// Toast.makeText(context, "该机型不支持手动红外扫描请使用物理按钮!",
+			// Toast.LENGTH_SHORT).show();
+		}
+	}
+}

+ 50 - 0
app/src/main/java/cilico/tools/barcode/ddjc/BroadcastConfig.java

@@ -0,0 +1,50 @@
+package cilico.tools.barcode.ddjc;
+
+public class BroadcastConfig {
+	// 扫描工具内应用设置的广播名称action;
+	public final static String BROADCAST_SETTING = "com.android.scanner.service_settings";
+
+	// // 扫描工具内开发者项,广播名称的 key;
+	// public final static String BROADCAST_KEY = "action_barcode_broadcast";
+	// 扫描工具内开发者项,广播名称的 key;
+	public final static String TYPE_BARCODE_BROADCAST_ACTION = "action_barcode_broadcast";
+
+	public final static String BROADCAST_KEY = "key_barcode_broadcast";
+
+	// 自定义扫描工具内开发者项内广播名称value;com.example.chinaautoid
+	// public final static String CUSTOM_NAME =
+	// "com.cpzs.read.QRCodeBroadcast";//seuic.android.scanner.scannertestreciever
+	public final static String CUSTOM_NAME = "com.barcode.sendBroadcast";
+	// 扫描工具内应用设置下的条码发送方式的广播名称key;
+	public final static String SEND_KEY = "barcode_send_mode";
+
+	// 扫描工具内应用设置下的条码结束符广播名称key;
+	public final static String END_KEY = "endchar";
+
+	// 扫描工具内应用设置下的扫描声音广播名称key
+	public final static String SOUND_KEY = "sound_play";
+
+	// private final String TYPE_PLAYSOUND = "sound_play";
+	// private final String TYPE_VIBERATE = "viberate";
+
+	// 扫描工具内应用设置下的振动广播名称key
+	public final static String VIBERATE_KEY = "viberate";
+	// 设置开机启动
+	public static final String TYPE_BOOT_START = "boot_start";
+
+	// 扫描工具内应用设置下的连续扫描 (循环扫描) 对应的广播key
+	public final static String CONTINIU_KEY = "scan_continue";
+
+	// 调用模拟按键button来实现扫描开启的广播action
+//	public final static String SCAN_START = "com.scan.onStartScan";
+	public final static String SCAN_START ="com.barcode.sendBroadcastScan";
+
+	// ͣ调用模拟按键button来实现扫描关闭的广播action
+	public final static String SCAN_STOP = "com.scan.onEndScan";
+
+	// 打开或者关闭扫描工具的广播action,此项只是控制扫描灯而不会停止扫描工具服务
+	public final static String SCAN_LIGHT = "com.android.scanner.ENABLED";
+
+	// 扫描工具下,条码设置对应的广播action
+	public final static String ACTION_PARAM_SETTINGS = "com.seuic.scanner.action.PARAM_SETTINGS";
+}

+ 350 - 0
app/src/main/java/cilico/tools/barcode/ddjc/ListnerBiz.java

@@ -0,0 +1,350 @@
+package cilico.tools.barcode.ddjc;
+
+import android.annotation.SuppressLint;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+import android.view.View.OnTouchListener;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.Switch;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+public class ListnerBiz {
+	/**
+	 * 扫描工具内应用设置下, 控制声音
+	 * 
+	 * @param context
+	 * @param stSound
+	 */
+	public static void setSound(final Context context, final SharedPreferences sp, Switch stSound) {
+
+		stSound.setChecked(sp.getBoolean("sound", false));
+
+		stSound.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+			@Override
+			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+
+				Intent intent = new Intent(BroadcastConfig.BROADCAST_SETTING);
+
+				if (isChecked) {
+
+					intent.putExtra(BroadcastConfig.SOUND_KEY, isChecked);
+					context.sendBroadcast(intent);
+					sp.edit().putBoolean("sound", true).commit();
+
+				} else {
+
+					intent.putExtra(BroadcastConfig.SOUND_KEY, isChecked);
+					context.sendBroadcast(intent);
+					sp.edit().putBoolean("sound", false).commit();
+
+				}
+			}
+		});
+	}
+
+	/**
+	 * 扫描工具内应用设置下, 控制声音
+	 * 
+	 * @param context
+	 * @param stSound
+	 */
+	public static void setSound(final Context context, final SharedPreferences sp, boolean stSound) {
+		Intent intent = new Intent(BroadcastConfig.BROADCAST_SETTING);
+		intent.putExtra(BroadcastConfig.SOUND_KEY, stSound);
+		context.sendBroadcast(intent);
+		sp.edit().putBoolean("sound", stSound).commit();
+	}
+
+	/**
+	 * 扫描工具内应用设置下, 控制震动
+	 * 
+	 * @param context
+	 * @param stVibrate
+	 */
+	public static void setVibrate(final Context context, final SharedPreferences sp, Switch stVibrate) {
+		stVibrate.setChecked(sp.getBoolean("viberate", false));
+		stVibrate.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+			@Override
+			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+
+				Intent intent = new Intent(BroadcastConfig.BROADCAST_SETTING);
+
+				if (isChecked) {
+
+					intent.putExtra(BroadcastConfig.VIBERATE_KEY, isChecked);
+					context.sendBroadcast(intent);
+					sp.edit().putBoolean("viberate", true).commit();
+
+				} else {
+
+					intent.putExtra(BroadcastConfig.VIBERATE_KEY, isChecked);
+					context.sendBroadcast(intent);
+					sp.edit().putBoolean("viberate", false).commit();
+
+				}
+			}
+		});
+	}
+
+	/**
+	 * 扫描工具内应用设置下, 控制震动
+	 * 
+	 * @param context
+	 * @param stVibrate
+	 */
+	public static void setVibrate(final Context context, final SharedPreferences sp, boolean stVibrate) {
+		Intent intent = new Intent(BroadcastConfig.BROADCAST_SETTING);
+		intent.putExtra(BroadcastConfig.VIBERATE_KEY, stVibrate);
+		context.sendBroadcast(intent);
+		sp.edit().putBoolean("viberate", stVibrate).commit();
+	}
+
+	/**
+	 * 扫描工具内应用设置下,循环扫描控制
+	 * 
+	 * @param context
+	 * @param stContinue
+	 */
+	public static void setContinue(final Context context, final SharedPreferences sp, boolean stContinue) {
+		Intent intent = new Intent(BroadcastConfig.BROADCAST_SETTING);
+		intent.putExtra(BroadcastConfig.CONTINIU_KEY, stContinue);
+		context.sendBroadcast(intent);
+		sp.edit().putBoolean("continiu", stContinue).commit();
+	}
+
+	/**
+	 * 扫描工具内应用设置下,循环扫描控制
+	 * 
+	 * @param context
+	 * @param stContinue
+	 */
+	public static void setContinue(final Context context, final SharedPreferences sp, Switch stContinue) {
+		stContinue.setChecked(sp.getBoolean("continiu", false));
+		stContinue.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+			@Override
+			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+
+				Intent intent = new Intent(BroadcastConfig.BROADCAST_SETTING);
+
+				if (isChecked) {
+
+					intent.putExtra(BroadcastConfig.CONTINIU_KEY, isChecked);
+					context.sendBroadcast(intent);
+					sp.edit().putBoolean("continiu", true).commit();
+
+				} else {
+
+					intent.putExtra(BroadcastConfig.CONTINIU_KEY, isChecked);
+					context.sendBroadcast(intent);
+					sp.edit().putBoolean("continiu", false).commit();
+
+				}
+			}
+		});
+	}
+
+	/**
+	 * 扫描工具内条码设置下,基本设置内单次光持续时间的修改,配合 扫描工具内应用设置下,循环扫描一起使用可以达到扫描灯的自定义出光频率
+	 * 
+	 * @param context
+	 * @param stContinue
+	 */
+	public static void setChixu(final Context context, final SharedPreferences sp, Button bt4, final EditText et4) {
+		et4.setText(sp.getString("chixutime", ""));
+		bt4.setOnClickListener(new OnClickListener() {
+
+			@Override
+			public void onClick(View v) {
+				String chixuTime = et4.getText().toString().trim();
+				if (chixuTime.equals("")) {
+					Toast.makeText(context, "请输入时间", Toast.LENGTH_LONG).show();
+					return;
+				}
+				Intent intent = new Intent(BroadcastConfig.ACTION_PARAM_SETTINGS);
+				// 持续时间对应的key 和 value
+				intent.putExtra("number", 0x01);
+				// 持续时间对应的可配置时间的修改项的key 和 value
+				intent.putExtra("value", Integer.parseInt(chixuTime));
+				context.sendBroadcast(intent);
+				sp.edit().putString("chixutime", chixuTime).commit();
+				Toast.makeText(context, "修改成功", Toast.LENGTH_SHORT).show();
+			}
+		});
+	}
+
+	/**
+	 * 扫描工具内应用设置下,间隔时间的修改,这个需要配合循环扫描一起使用
+	 * 
+	 * @param context
+	 * @param stContinue
+	 */
+	public static void setContinueTime(final Context context, final SharedPreferences sp, final EditText et3,
+			final Button bt3) {
+		et3.setText(sp.getString("continiutime", ""));
+		bt3.setOnClickListener(new OnClickListener() {
+
+			@Override
+			public void onClick(View v) {
+				String etTime = et3.getText().toString().trim();
+				if (etTime.equals("")) {
+					Toast.makeText(context, "请输入时间", Toast.LENGTH_LONG).show();
+					return;
+				}
+				Intent intent = new Intent(BroadcastConfig.BROADCAST_SETTING);
+				intent.putExtra("interval", Integer.parseInt(etTime));
+				context.sendBroadcast(intent);
+				sp.edit().putString("continiutime", etTime).commit();
+				Toast.makeText(context, "修改成功", Toast.LENGTH_SHORT).show();
+			}
+		});
+	}
+
+	/**
+	 * 调用模拟按键button来控制扫描光的熄灭
+	 * 
+	 * @param context
+	 * @param btScan
+	 */
+	public static void setScanClick(final Context context, View btScan) {
+
+		btScan.setOnTouchListener(new OnTouchListener() {
+
+			@SuppressLint("ClickableViewAccessibility")
+			@Override
+			public boolean onTouch(View v, MotionEvent event) {
+
+				if (event.getAction() == KeyEvent.ACTION_DOWN) {
+
+					Intent intent = new Intent(BroadcastConfig.SCAN_START);
+					context.sendBroadcast(intent);
+
+				} else if (event.getAction() == KeyEvent.ACTION_UP) {
+
+					Intent intent = new Intent(BroadcastConfig.SCAN_STOP);
+					context.sendBroadcast(intent);
+
+				}
+
+				return false;
+			}
+		});
+	}
+
+	// 特殊需求,如果switch设置打开,则demo开启后会自动连续出光,和上述的循环扫描不是一个概念
+	static boolean flag;
+
+	public static void setChixutime(final Context context, Switch st4) {
+		st4.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+			@Override
+			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+				flag = isChecked;
+				new Thread() {
+					public void run() {
+						if (flag) {
+							while (flag) {
+								Intent intent = new Intent(BroadcastConfig.SCAN_START);
+								context.sendBroadcast(intent);
+								try {
+									Thread.sleep(100);
+									Log.e("tag", Thread.currentThread().getName());
+								} catch (InterruptedException e) {
+									e.printStackTrace();
+								}
+							}
+						} else {
+							Intent intent2 = new Intent(BroadcastConfig.SCAN_STOP);
+							context.sendBroadcast(intent2);
+						}
+					}
+				}.start();
+				Log.e("tag", Thread.currentThread().getName());
+			}
+		});
+	}
+	
+	/**
+	 * 二维扫描头修改,一维不必修改
+	 * 
+	 * @param context
+	 * @param value:曝光级别:0(auto),1(low),2(mid),3(high) 
+	 */
+	public static void setExposure(final Context context, final int value) {
+//		final String[] items = { "auto", "low", "mid", "high" };
+		Intent intent = new Intent(BroadcastConfig.ACTION_PARAM_SETTINGS);
+		intent.putExtra("number", 0x0d);
+		intent.putExtra("value", value);
+		context.sendBroadcast(intent);
+	}
+
+	/**
+	 * 二维扫描头修改,一维不必修改
+	 * 
+	 * @param context
+	 * @param tvExposure
+	 */
+	public static void setExposure(final Context context, final TextView tvExposure) {
+		tvExposure.setOnClickListener(new OnClickListener() {
+
+			@Override
+			public void onClick(View v) {
+				Builder builder = new Builder(context);
+				final String[] items = { "auto", "low", "mid", "high" };
+				builder.setItems(items, new DialogInterface.OnClickListener() {
+
+					@Override
+					public void onClick(DialogInterface dialog, int which) {
+						tvExposure.setText(items[which]);
+						Intent intent = new Intent(BroadcastConfig.ACTION_PARAM_SETTINGS);
+						intent.putExtra("number", 0x0d);
+						intent.putExtra("value", which);
+						context.sendBroadcast(intent);
+					}
+				});
+				builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
+					@Override
+					public void onClick(DialogInterface dialog, int which) {
+						dialog.dismiss();
+					}
+				});
+				builder.show();
+			}
+		});
+
+	}
+
+	/**
+	 * 长按扫描框清除内容
+	 * 
+	 * @param context
+	 * @param etScan
+	 */
+	public static void setetScan(final Context context, final EditText etScan) {
+		etScan.setOnLongClickListener(new OnLongClickListener() {
+
+			@Override
+			public boolean onLongClick(View v) {
+				etScan.setText("");
+				Toast.makeText(context, "清除成功", Toast.LENGTH_SHORT).show();
+				return false;
+			}
+		});
+	}
+}

+ 99 - 0
app/src/main/java/cn/jymf/scan/AmbientLightManager.java

@@ -0,0 +1,99 @@
+/*
+ * 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 cn.jymf.scan;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.preference.PreferenceManager;
+import cn.jymf.scan.camera.CameraManager;
+import cn.jymf.scan.camera.FrontLightMode;
+
+/**
+ * Detects ambient light and switches on the front light when very dark, and off
+ * again when sufficiently light.
+ * 
+ * @author Sean Owen
+ * @author Nikolaus Huber
+ */
+final class AmbientLightManager implements SensorEventListener {
+
+	private static final float TOO_DARK_LUX = 45.0f;
+	private static final float BRIGHT_ENOUGH_LUX = 450.0f;
+
+	private final Context context;
+	private CameraManager cameraManager;
+
+	/**
+	 * 光传感器
+	 */
+	private Sensor lightSensor;
+
+	AmbientLightManager(Context context) {
+		this.context = context;
+	}
+
+	void start(CameraManager cameraManager) {
+		this.cameraManager = cameraManager;
+		SharedPreferences sharedPrefs = PreferenceManager
+				.getDefaultSharedPreferences(context);
+		if (FrontLightMode.readPref(sharedPrefs) == FrontLightMode.AUTO) {
+			SensorManager sensorManager = (SensorManager) context
+					.getSystemService(Context.SENSOR_SERVICE);
+			lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+			if (lightSensor != null) {
+				sensorManager.registerListener(this, lightSensor,
+						SensorManager.SENSOR_DELAY_NORMAL);
+			}
+		}
+	}
+
+	void stop() {
+		if (lightSensor != null) {
+			SensorManager sensorManager = (SensorManager) context
+					.getSystemService(Context.SENSOR_SERVICE);
+			sensorManager.unregisterListener(this);
+			cameraManager = null;
+			lightSensor = null;
+		}
+	}
+
+	/**
+	 * 该方法会在周围环境改变后回调,然后根据设置好的临界值决定是否打开闪光灯
+	 */
+	@Override
+	public void onSensorChanged(SensorEvent sensorEvent) {
+		float ambientLightLux = sensorEvent.values[0];
+		if (cameraManager != null) {
+			if (ambientLightLux <= TOO_DARK_LUX) {
+				cameraManager.setTorch(true);
+			}
+			else if (ambientLightLux >= BRIGHT_ENOUGH_LUX) {
+				cameraManager.setTorch(false);
+			}
+		}
+	}
+
+	@Override
+	public void onAccuracyChanged(Sensor sensor, int accuracy) {
+		// do nothing
+	}
+
+}

+ 158 - 0
app/src/main/java/cn/jymf/scan/BeepManager.java

@@ -0,0 +1,158 @@
+/*
+ * 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 cn.jymf.scan;
+
+import java.io.IOException;
+
+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 cn.jymf.scan.config.Config;
+import cn.net.communal.cpzshandset.R;
+
+/**
+ * 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();
+	}
+
+	/**
+	 * 扫描成功后可以播放提示音并震动,这两种功能都是用户自定义的 在Barcode Scanner中点击菜单键,点设置即可看到这两项的设置
+	 */
+	synchronized void updatePrefs() {
+		SharedPreferences prefs = PreferenceManager
+				.getDefaultSharedPreferences(activity);
+		playBeep = shouldBeep(prefs, activity);
+		vibrate = prefs.getBoolean(Config.KEY_VIBRATE, false);
+		if (playBeep && mediaPlayer == null) {
+			// The volume on STREAM_SYSTEM is not adjustable, and users found it
+			// too loud,
+			// so we now play on the music stream.
+			activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
+			mediaPlayer = buildMediaPlayer(activity);
+		}
+	}
+
+	/**
+	 * 根据配置播放提示音和震动
+	 */
+	synchronized void playBeepSoundAndVibrate() {
+		if (playBeep && mediaPlayer != null) {
+			mediaPlayer.start();
+		}
+		if (vibrate) {
+			Vibrator vibrator = (Vibrator) activity
+					.getSystemService(Context.VIBRATOR_SERVICE);
+			vibrator.vibrate(VIBRATE_DURATION);
+		}
+	}
+
+	private static boolean shouldBeep(SharedPreferences prefs, Context activity) {
+		boolean shouldPlayBeep = prefs.getBoolean(Config.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;
+	}
+
+	/**
+	 * 新增
+	 * 关闭beep声音
+	 */
+	public synchronized void close() {
+		if (mediaPlayer != null) {
+			mediaPlayer.release();
+			mediaPlayer = null;
+		}
+	}
+
+}

+ 515 - 0
app/src/main/java/cn/jymf/scan/CaptureActivity.java

@@ -0,0 +1,515 @@
+package cn.jymf.scan;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.util.Collection;
+import java.util.Map;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.Result;
+import com.google.zxing.client.result.ResultParser;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Toast;
+import cilico.tools.barcode.PhoneScanner;
+import cn.jymf.scan.camera.CameraManager;
+import cn.jymf.scan.common.BitmapUtils;
+import cn.jymf.scan.decode.BitmapDecoder;
+import cn.jymf.scan.decode.CaptureActivityHandler;
+import cn.jymf.scan.view.ViewfinderView;
+import cn.net.communal.cpzshandset.common.config.TConfig;
+import cn.net.communal.cpzshandset.common.util.LogUtil;
+import cn.net.communal.cpzshandset.R;
+
+/**
+ * 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.
+ * 
+ * 此Activity所做的事: 1.开启camera,在后台独立线程中完成扫描任务;
+ * 2.绘制了一个扫描区(viewfinder)来帮助用户将条码置于其中以准确扫描; 3.扫描成功后会将扫描结果展示在界面上。
+ * 
+ * @author dswitkin@google.com (Daniel Switkin)
+ * @author Sean Owen
+ */
+public final class CaptureActivity extends Activity implements SurfaceHolder.Callback, View.OnClickListener {
+
+	private static final String TAG = CaptureActivity.class.getSimpleName();
+
+	private static final int REQUEST_CODE = 100;
+
+	private static final int PARSE_BARCODE_FAIL = 300;
+	private static final int PARSE_BARCODE_SUC = 200;
+
+	/**
+	 * 是否有预览
+	 */
+	private boolean hasSurface;
+
+	/**
+	 * 活动监控器。如果手机没有连接电源线,那么当相机开启后如果一直处于不被使用状态则该服务会将当前activity关闭。
+	 * 活动监控器全程监控扫描活跃状态,与CaptureActivity生命周期相同.每一次扫描过后都会重置该监控,即重新倒计时。
+	 */
+	private InactivityTimer inactivityTimer;
+
+	/**
+	 * 声音震动管理器。如果扫描成功后可以播放一段音频,也可以震动提醒,可以通过配置来决定扫描成功后的行为。
+	 */
+	private BeepManager beepManager;
+
+	/**
+	 * 闪光灯调节器。自动检测环境光线强弱并决定是否开启闪光灯
+	 */
+	private AmbientLightManager ambientLightManager;
+
+	private CameraManager cameraManager;
+	/**
+	 * 扫描区域
+	 */
+	private ViewfinderView viewfinderView;
+
+	private CaptureActivityHandler handler;
+
+	private Result lastResult;
+
+	private boolean isFlashlightOpen;
+
+	/**
+	 * 【辅助解码的参数(用作MultiFormatReader的参数)】 编码类型,该参数告诉扫描器采用何种编码方式解码,即EAN-13,QR
+	 * Code等等 对应于DecodeHintType.POSSIBLE_FORMATS类型
+	 * 参考DecodeThread构造函数中如下代码:hints.put(DecodeHintType.POSSIBLE_FORMATS,
+	 * decodeFormats);
+	 */
+	private Collection<BarcodeFormat> decodeFormats;
+
+	/**
+	 * 【辅助解码的参数(用作MultiFormatReader的参数)】 该参数最终会传入MultiFormatReader,
+	 * 上面的decodeFormats和characterSet最终会先加入到decodeHints中 最终被设置到MultiFormatReader中
+	 * 参考DecodeHandler构造器中如下代码:multiFormatReader.setHints(hints);
+	 */
+	private Map<DecodeHintType, ?> decodeHints;
+
+	/**
+	 * 【辅助解码的参数(用作MultiFormatReader的参数)】 字符集,告诉扫描器该以何种字符集进行解码
+	 * 对应于DecodeHintType.CHARACTER_SET类型
+	 * 参考DecodeThread构造器如下代码:hints.put(DecodeHintType.CHARACTER_SET,
+	 * characterSet);
+	 */
+	private String characterSet;
+
+	private Result savedResultToShow;
+
+	private IntentSource source;
+
+	/**
+	 * 图片的路径
+	 */
+	private String photoPath;
+
+	private Handler mHandler = new MyHandler(this);
+
+	static class MyHandler extends Handler {
+
+		private WeakReference<Activity> activityReference;
+
+		public MyHandler(Activity activity) {
+			activityReference = new WeakReference<Activity>(activity);
+		}
+
+		@Override
+		public void handleMessage(Message msg) {
+
+			switch (msg.what) {
+				case PARSE_BARCODE_SUC : // 解析图片成功
+					Toast.makeText(activityReference.get(),
+							activityReference.get().getString(R.string.capture_parse_image_ok) + msg.obj,
+							Toast.LENGTH_SHORT).show();
+					break;
+
+				case PARSE_BARCODE_FAIL :// 解析图片失败
+
+					Toast.makeText(activityReference.get(),
+							activityReference.get().getString(R.string.capture_parse_image_err), Toast.LENGTH_SHORT)
+							.show();
+					break;
+
+				default :
+					break;
+			}
+
+			super.handleMessage(msg);
+		}
+
+	}
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+
+		Window window = getWindow();
+		window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+		setContentView(R.layout.scan);
+
+		hasSurface = false;
+		inactivityTimer = new InactivityTimer(this);
+		beepManager = new BeepManager(this);
+		ambientLightManager = new AmbientLightManager(this);
+
+		// 监听图片识别按钮
+		findViewById(R.id.scan_local_photo).setOnClickListener(this);
+		// 闪光灯按钮
+		findViewById(R.id.scan_flashlight).setOnClickListener(this);
+		// 返回
+		findViewById(R.id.scan_button_back).setOnClickListener(this);
+
+	}
+
+	@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.
+
+		// 相机初始化的动作需要开启相机并测量屏幕大小,这些操作
+		// 不建议放到onCreate中,因为如果在onCreate中加上首次启动展示帮助信息的代码的 话,
+		// 会导致扫描窗口的尺寸计算有误的bug
+		cameraManager = new CameraManager(getApplication());
+
+		viewfinderView = (ViewfinderView) findViewById(R.id.scan_viewfinder_view);
+		viewfinderView.setCameraManager(cameraManager);
+
+		handler = null;
+		lastResult = null;
+
+		// 摄像头预览功能必须借助SurfaceView,因此也需要在一开始对其进行初始化
+		// 如果需要了解SurfaceView的原理
+		// 参考:http://blog.csdn.net/luoshengyang/article/details/8661317
+		SurfaceView surfaceView = (SurfaceView) findViewById(R.id.scan_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 {
+			// 防止sdk8的设备初始化预览异常
+			surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+
+			// Install the callback and wait for surfaceCreated() to init the
+			// camera.
+			surfaceHolder.addCallback(this);
+		}
+
+		// 加载声音配置,其实在BeemManager的构造器中也会调用该方法,即在onCreate的时候会调用一次
+		beepManager.updatePrefs();
+
+		// 启动闪光灯调节器
+		ambientLightManager.start(cameraManager);
+
+		// 恢复活动监控器
+		inactivityTimer.onResume();
+
+		source = IntentSource.NONE;
+		decodeFormats = null;
+		characterSet = null;
+	}
+
+	@Override
+	protected void onPause() {
+		if (handler != null) {
+			handler.quitSynchronously();
+			handler = null;
+		}
+		inactivityTimer.onPause();
+		ambientLightManager.stop();
+		beepManager.close();
+
+		// 关闭摄像头
+		cameraManager.closeDriver();
+		if (!hasSurface) {
+			SurfaceView surfaceView = (SurfaceView) findViewById(R.id.scan_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.NONE) && 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;
+
+			case KeyEvent.KEYCODE_VOLUME_UP :
+				cameraManager.zoomIn();
+				return true;
+
+			case KeyEvent.KEYCODE_VOLUME_DOWN :
+				cameraManager.zoomOut();
+				return true;
+
+		}
+		return super.onKeyDown(keyCode, event);
+	}
+
+	@Override
+	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+
+		if (resultCode == RESULT_OK) {
+			final ProgressDialog progressDialog;
+			switch (requestCode) {
+				case REQUEST_CODE :
+
+					// 获取选中图片的路径
+					Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null);
+					if (cursor.moveToFirst()) {
+						photoPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
+					}
+					cursor.close();
+
+					progressDialog = new ProgressDialog(this);
+					progressDialog.setMessage(getString(R.string.capture_scaning));
+					progressDialog.setCancelable(false);
+					progressDialog.show();
+
+					new Thread(new Runnable() {
+
+						@Override
+						public void run() {
+
+							Bitmap img = BitmapUtils.getCompressedBitmap(photoPath);
+
+							BitmapDecoder decoder = new BitmapDecoder(CaptureActivity.this);
+							Result result = decoder.getRawResult(img);
+
+							if (result != null) {
+								Message m = mHandler.obtainMessage();
+								m.what = PARSE_BARCODE_SUC;
+								m.obj = ResultParser.parseResult(result).toString();
+								mHandler.sendMessage(m);
+							} else {
+								Message m = mHandler.obtainMessage();
+								m.what = PARSE_BARCODE_FAIL;
+								mHandler.sendMessage(m);
+							}
+
+							progressDialog.dismiss();
+
+						}
+					}).start();
+
+					break;
+
+			}
+		}
+
+	}
+
+	@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 surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+		hasSurface = false;
+	}
+
+	@Override
+	public void surfaceDestroyed(SurfaceHolder holder) {
+
+	}
+
+	/**
+	 * 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;
+
+		// 把图片画到扫描框
+		viewfinderView.drawResultBitmap(barcode);
+
+		beepManager.playBeepSoundAndVibrate();
+		String scanContent = ResultParser.parseResult(rawResult).toString();
+		//扫码结果显示
+		LogUtil.d(TConfig.EchoScanner, "手机扫码结果:"  + scanContent);
+//		LogUtils
+		PhoneScanner.sendHandler(scanContent);
+		finish();
+
+	}
+
+	public void restartPreviewAfterDelay(long delayMS) {
+		if (handler != null) {
+			handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
+		}
+		resetStatusView();
+	}
+
+	public ViewfinderView getViewfinderView() {
+		return viewfinderView;
+	}
+
+	public Handler getHandler() {
+		return handler;
+	}
+
+	public CameraManager getCameraManager() {
+		return cameraManager;
+	}
+
+	private void resetStatusView() {
+		viewfinderView.setVisibility(View.VISIBLE);
+		lastResult = null;
+	}
+
+	public void drawViewfinder() {
+		viewfinderView.drawViewfinder();
+	}
+
+	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();
+		}
+	}
+
+	/**
+	 * 向CaptureActivityHandler中发送消息,并展示扫描到的图像
+	 * 
+	 * @param bitmap
+	 * @param result
+	 */
+	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;
+		}
+	}
+
+	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();
+	}
+
+	@Override
+	public void onClick(View v) {
+		switch (v.getId()) {
+			case R.id.scan_local_photo : // 图片识别
+				// 打开手机中的相册
+				Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
+				innerIntent.setType("image/*");
+				Intent wrapperIntent = Intent.createChooser(innerIntent, getString(R.string.capture_qrimage_select));
+				this.startActivityForResult(wrapperIntent, REQUEST_CODE);
+				break;
+
+			case R.id.scan_flashlight :
+				if (isFlashlightOpen) {
+					cameraManager.setTorch(false); // 关闭闪光灯
+					isFlashlightOpen = false;
+				} else {
+					cameraManager.setTorch(true); // 打开闪光灯
+					isFlashlightOpen = true;
+				}
+				break;
+			case R.id.scan_button_back :// 不扫描返回
+				finish();
+				break;
+			default :
+				break;
+		}
+
+	}
+
+}

+ 49 - 0
app/src/main/java/cn/jymf/scan/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 cn.jymf.scan;
+
+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();
+  }
+
+}

+ 149 - 0
app/src/main/java/cn/jymf/scan/InactivityTimer.java

@@ -0,0 +1,149 @@
+/*
+ * 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 cn.jymf.scan;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncTask;
+import android.os.BatteryManager;
+import android.util.Log;
+import cn.jymf.scan.common.Runnable;
+
+/**
+ * Finishes an activity after a period of inactivity if the device is on battery
+ * power. <br/>
+ * <br/>
+ * 
+ * 该活动监控器全程监控扫描活跃状态,与CaptureActivity生命周期相同
+ */
+final class InactivityTimer {
+
+	private static final String TAG = InactivityTimer.class.getSimpleName();
+
+	/**
+	 * 如果在5min内扫描器没有被使用过,则自动finish掉activity
+	 */
+	private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
+
+	/**
+	 * 在本app中,此activity即为CaptureActivity
+	 */
+	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();
+		Runnable.execAsync(inactivityTask);
+	}
+
+	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();
+				}
+			}
+		}
+	}
+
+	/**
+	 * 该任务很简单,就是在INACTIVITY_DELAY_MS时间后终结activity
+	 */
+	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;
+		}
+	}
+
+}

+ 26 - 0
app/src/main/java/cn/jymf/scan/IntentSource.java

@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.jymf.scan;
+
+enum IntentSource {
+
+  NATIVE_APP_INTENT,
+  PRODUCT_SEARCH_LINK,
+  ZXING_LINK,
+  NONE
+
+}

+ 278 - 0
app/src/main/java/cn/jymf/scan/Intents.java

@@ -0,0 +1,278 @@
+/*
+ * 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 cn.jymf.scan;
+
+/**
+ * This class provides the constants to use when sending an Intent to Barcode Scanner.
+ * These strings are effectively API and cannot be changed.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class Intents {
+  private Intents() {
+  }
+
+  public static final class Scan {
+    /**
+     * Send this intent to open the Barcodes app in scanning mode, find a barcode, and return
+     * the results.
+     */
+    public static final String ACTION = "com.google.zxing.client.android.SCAN";
+
+    /**
+     * By default, sending this will decode all barcodes that we understand. However it
+     * may be useful to limit scanning to certain formats. Use
+     * {@link android.content.Intent#putExtra(String, String)} with one of the values below.
+     *
+     * Setting this is effectively shorthand for setting explicit formats with {@link #FORMATS}.
+     * It is overridden by that setting.
+     */
+    public static final String MODE = "SCAN_MODE";
+
+    /**
+     * Decode only UPC and EAN barcodes. This is the right choice for shopping apps which get
+     * prices, reviews, etc. for products.
+     */
+    public static final String PRODUCT_MODE = "PRODUCT_MODE";
+
+    /**
+     * Decode only 1D barcodes.
+     */
+    public static final String ONE_D_MODE = "ONE_D_MODE";
+
+    /**
+     * Decode only QR codes.
+     */
+    public static final String QR_CODE_MODE = "QR_CODE_MODE";
+
+    /**
+     * Decode only Data Matrix codes.
+     */
+    public static final String DATA_MATRIX_MODE = "DATA_MATRIX_MODE";
+
+    /**
+     * Decode only Aztec.
+     */
+    public static final String AZTEC_MODE = "AZTEC_MODE";
+
+    /**
+     * Decode only PDF417.
+     */
+    public static final String PDF417_MODE = "PDF417_MODE";
+
+    /**
+     * Comma-separated list of formats to scan for. The values must match the names of
+     * {@link com.google.zxing.BarcodeFormat}s, e.g. {@link com.google.zxing.BarcodeFormat#EAN_13}.
+     * Example: "EAN_13,EAN_8,QR_CODE". This overrides {@link #MODE}.
+     */
+    public static final String FORMATS = "SCAN_FORMATS";
+	
+    /**
+     * Optional parameter to specify the id of the camera from which to recognize barcodes.
+     * Overrides the default camera that would otherwise would have been selected.
+     * If provided, should be an int.
+     */
+    public static final String CAMERA_ID = "SCAN_CAMERA_ID";
+
+    /**
+     * @see com.google.zxing.DecodeHintType#CHARACTER_SET
+     */
+    public static final String CHARACTER_SET = "CHARACTER_SET";
+
+    /**
+     * Optional parameters to specify the width and height of the scanning rectangle in pixels.
+     * The app will try to honor these, but will clamp them to the size of the preview frame.
+     * You should specify both or neither, and pass the size as an int.
+     */
+    public static final String WIDTH = "SCAN_WIDTH";
+    public static final String HEIGHT = "SCAN_HEIGHT";
+
+    /**
+     * Desired duration in milliseconds for which to pause after a successful scan before
+     * returning to the calling intent. Specified as a long, not an integer!
+     * For example: 1000L, not 1000.
+     */
+    public static final String RESULT_DISPLAY_DURATION_MS = "RESULT_DISPLAY_DURATION_MS";
+
+    /**
+     * Prompt to show on-screen when scanning by intent. Specified as a {@link String}.
+     */
+    public static final String PROMPT_MESSAGE = "PROMPT_MESSAGE";
+
+    /**
+     * If a barcode is found, Barcodes returns {@link android.app.Activity#RESULT_OK} to
+     * {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)}
+     * of the app which requested the scan via
+     * {@link android.app.Activity#startActivityForResult(android.content.Intent, int)}
+     * The barcodes contents can be retrieved with
+     * {@link android.content.Intent#getStringExtra(String)}. 
+     * If the user presses Back, the result code will be {@link android.app.Activity#RESULT_CANCELED}.
+     */
+    public static final String RESULT = "SCAN_RESULT";
+
+    /**
+     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_FORMAT}
+     * to determine which barcode format was found.
+     * See {@link com.google.zxing.BarcodeFormat} for possible values.
+     */
+    public static final String RESULT_FORMAT = "SCAN_RESULT_FORMAT";
+
+    /**
+     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_UPC_EAN_EXTENSION}
+     * to return the content of any UPC extension barcode that was also found. Only applicable
+     * to {@link com.google.zxing.BarcodeFormat#UPC_A} and {@link com.google.zxing.BarcodeFormat#EAN_13}
+     * formats.
+     */
+    public static final String RESULT_UPC_EAN_EXTENSION = "SCAN_RESULT_UPC_EAN_EXTENSION";
+
+    /**
+     * Call {@link android.content.Intent#getByteArrayExtra(String)} with {@link #RESULT_BYTES}
+     * to get a {@code byte[]} of raw bytes in the barcode, if available.
+     */
+    public static final String RESULT_BYTES = "SCAN_RESULT_BYTES";
+
+    /**
+     * Key for the value of {@link com.google.zxing.ResultMetadataType#ORIENTATION}, if available.
+     * Call {@link android.content.Intent#getIntArrayExtra(String)} with {@link #RESULT_ORIENTATION}.
+     */
+    public static final String RESULT_ORIENTATION = "SCAN_RESULT_ORIENTATION";
+
+    /**
+     * Key for the value of {@link com.google.zxing.ResultMetadataType#ERROR_CORRECTION_LEVEL}, if available.
+     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_ERROR_CORRECTION_LEVEL}.
+     */
+    public static final String RESULT_ERROR_CORRECTION_LEVEL = "SCAN_RESULT_ERROR_CORRECTION_LEVEL";
+
+    /**
+     * Prefix for keys that map to the values of {@link com.google.zxing.ResultMetadataType#BYTE_SEGMENTS},
+     * if available. The actual values will be set under a series of keys formed by adding 0, 1, 2, ...
+     * to this prefix. So the first byte segment is under key "SCAN_RESULT_BYTE_SEGMENTS_0" for example.
+     * Call {@link android.content.Intent#getByteArrayExtra(String)} with these keys.
+     */
+    public static final String RESULT_BYTE_SEGMENTS_PREFIX = "SCAN_RESULT_BYTE_SEGMENTS_";
+
+    /**
+     * Setting this to false will not save scanned codes in the history. Specified as a {@code boolean}.
+     */
+    public static final String SAVE_HISTORY = "SAVE_HISTORY";
+
+    private Scan() {
+    }
+  }
+
+  public static final class History {
+
+    public static final String ITEM_NUMBER = "ITEM_NUMBER";
+
+    private History() {
+    }
+  }
+
+  public static final class Encode {
+    /**
+     * Send this intent to encode a piece of data as a QR code and display it full screen, so
+     * that another person can scan the barcode from your screen.
+     */
+    public static final String ACTION = "com.google.zxing.client.android.ENCODE";
+
+    /**
+     * The data to encode. Use {@link android.content.Intent#putExtra(String, String)} or
+     * {@link android.content.Intent#putExtra(String, android.os.Bundle)}, 
+     * depending on the type and format specified. Non-QR Code formats should
+     * just use a String here. For QR Code, see Contents for details.
+     */
+    public static final String DATA = "ENCODE_DATA";
+
+    /**
+     * The type of data being supplied if the format is QR Code. Use
+     * {@link android.content.Intent#putExtra(String, String)} with one of {@link Contents.Type}.
+     */
+    public static final String TYPE = "ENCODE_TYPE";
+
+    /**
+     * The barcode format to be displayed. If this isn't specified or is blank,
+     * it defaults to QR Code. Use {@link android.content.Intent#putExtra(String, String)}, where
+     * format is one of {@link com.google.zxing.BarcodeFormat}.
+     */
+    public static final String FORMAT = "ENCODE_FORMAT";
+
+    /**
+     * Normally the contents of the barcode are displayed to the user in a TextView. Setting this
+     * boolean to false will hide that TextView, showing only the encode barcode.
+     */
+    public static final String SHOW_CONTENTS = "ENCODE_SHOW_CONTENTS";
+
+    private Encode() {
+    }
+  }
+
+  public static final class SearchBookContents {
+    /**
+     * Use Google Book Search to search the contents of the book provided.
+     */
+    public static final String ACTION = "com.google.zxing.client.android.SEARCH_BOOK_CONTENTS";
+
+    /**
+     * The book to search, identified by ISBN number.
+     */
+    public static final String ISBN = "ISBN";
+
+    /**
+     * An optional field which is the text to search for.
+     */
+    public static final String QUERY = "QUERY";
+
+    private SearchBookContents() {
+    }
+  }
+
+  public static final class WifiConnect {
+    /**
+     * Internal intent used to trigger connection to a wi-fi network.
+     */
+    public static final String ACTION = "com.google.zxing.client.android.WIFI_CONNECT";
+
+    /**
+     * The network to connect to, all the configuration provided here.
+     */
+    public static final String SSID = "SSID";
+
+    /**
+     * The network to connect to, all the configuration provided here.
+     */
+    public static final String TYPE = "TYPE";
+
+    /**
+     * The network to connect to, all the configuration provided here.
+     */
+    public static final String PASSWORD = "PASSWORD";
+
+    private WifiConnect() {
+    }
+  }
+
+  public static final class Share {
+    /**
+     * Give the user a choice of items to encode as a barcode, then render it as a QR Code and
+     * display onscreen for a friend to scan with their phone.
+     */
+    public static final String ACTION = "com.google.zxing.client.android.SHARE";
+
+    private Share() {
+    }
+  }
+}

+ 122 - 0
app/src/main/java/cn/jymf/scan/camera/AutoFocusManager.java

@@ -0,0 +1,122 @@
+/*
+ * 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 cn.jymf.scan.camera;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+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 cn.jymf.scan.common.Runnable;
+import cn.jymf.scan.config.Config;
+
+/**
+ * 由于对焦不是一次性完成的任务(手抖),而系统提供的对焦仅有Camera.autoFocus()方法,
+ * 因此需要一个线程来不断调用Camera.autoFocus()直到用户满意按下快门为止
+ */
+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(Config.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();
+			Runnable.execAsync(outstandingTask);
+		}
+	}
+
+	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;
+		}
+	}
+
+}

+ 359 - 0
app/src/main/java/cn/jymf/scan/camera/CameraConfigurationManager.java

@@ -0,0 +1,359 @@
+/*
+ * 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 cn.jymf.scan.camera;
+
+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 android.annotation.SuppressLint;
+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 cn.jymf.scan.config.Config;
+
+/**
+ * A class which deals with reading, parsing, and setting the camera parameters
+ * which are used to configure the camera hardware.
+ * 
+ * <br/>
+ * 
+ * 摄像头参数的设置类
+ */
+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();
+
+		// sdk8出错
+		// display.getSize(theScreenResolution);
+
+		// 改为此方式
+		theScreenResolution = getDisplaySize(display);
+
+		screenResolution = theScreenResolution;
+		Log.i(TAG, "Screen resolution: " + screenResolution);
+		Point  screenResolutionForCamera = new  Point();
+		screenResolutionForCamera.x  = screenResolution.x;
+		screenResolutionForCamera.y  = screenResolution.y;
+		if  (screenResolution.x < screenResolution.y) {
+		    screenResolutionForCamera.x  = screenResolution.y;
+		    screenResolutionForCamera.y  = screenResolution.x;
+		   }
+		cameraResolution = findBestPreviewSizeValue(parameters,
+				screenResolutionForCamera);
+		Log.i(TAG, "Camera resolution: " + cameraResolution);
+	}
+
+	@SuppressLint("NewApi")
+	private Point getDisplaySize(final Display display) {
+		final Point point = new Point();
+		try {
+			display.getSize(point);
+		}
+		catch (java.lang.NoSuchMethodError ignore) { // Older device
+			point.x = display.getWidth();
+			point.y = display.getHeight();
+		}
+		return point;
+	}
+
+	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 = findSettableValue(
+				parameters.getSupportedFocusModes(),
+				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(Config.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;
+		}
+
+		camera.setDisplayOrientation(90);
+	}
+
+	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);
+		}
+	}
+
+	/**
+	 * 从相机支持的分辨率中计算出最适合的预览界面尺寸
+	 * 
+	 * @param parameters
+	 * @param screenResolution
+	 * @return
+	 */
+	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;
+	}
+
+	/**
+	 * 在supportedValues中寻找desiredValues,找不到则返回null
+	 * 
+	 * @param supportedValues
+	 * @param desiredValues
+	 * @return
+	 */
+	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;
+	}
+
+}

+ 435 - 0
app/src/main/java/cn/jymf/scan/camera/CameraManager.java

@@ -0,0 +1,435 @@
+/*
+ * 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 cn.jymf.scan.camera;
+
+import java.io.IOException;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.Camera;
+import android.os.Handler;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import com.google.zxing.PlanarYUVLuminanceSource;
+
+/**
+ * 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. <br/>
+ * <br/>
+ * 
+ * 该类封装了相机的所有服务并且是该app中唯一与相机打交道的类
+ * 
+ * @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 MAX_FRAME_WIDTH = 1200; // = 5/8 * 1920
+
+	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;
+		}
+
+		// 设置摄像头预览view
+		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) {
+			// Starts capturing and drawing preview frames to the screen
+			// Preview will not actually start until a surface is supplied with
+			// setPreviewDisplay(SurfaceHolder) or
+			// setPreviewTexture(SurfaceTexture).
+			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 org.madmatrix.zxing.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. <br/>
+	 * 
+	 * 两个绑定操作:<br/>
+	 * 1:将handler与回调函数绑定;<br/>
+	 * 2:将相机与回调函数绑定<br/>
+	 * 综上,该函数的作用是当相机的预览界面准备就绪后就会调用hander向其发送传入的message
+	 * 
+	 * @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);
+
+			// 绑定相机回调函数,当预览界面准备就绪后会回调Camera.PreviewCallback.onPreviewFrame
+			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 = width;
+
+			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;
+	}
+
+	/**
+	 * Target 5/8 of each dimension<br/>
+	 * 计算结果在hardMin~hardMax之间
+	 * 
+	 * @param resolution
+	 * @param hardMin
+	 * @param hardMax
+	 * @return
+	 */
+	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.y / screenResolution.x;
+			rect.right = rect.right * cameraResolution.y / screenResolution.x;
+			rect.top = rect.top * cameraResolution.x / screenResolution.y;
+			rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
+			framingRectInPreview = rect;
+
+			Log.d(TAG, "Calculated framingRectInPreview rect: "
+					+ framingRectInPreview);
+			Log.d(TAG, "cameraResolution: " + cameraResolution);
+			Log.d(TAG, "screenResolution: " + screenResolution);
+		}
+
+		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);
+	}
+
+	/**
+	 * 焦点放小
+	 */
+	public void zoomOut() {
+		if (camera != null && camera.getParameters().isZoomSupported()) {
+
+			Camera.Parameters parameters = camera.getParameters();
+			if (parameters.getZoom() <= 0) {
+				return;
+			}
+
+			parameters.setZoom(parameters.getZoom() - 1);
+			camera.setParameters(parameters);
+
+		}
+	}
+
+	/**
+	 * 焦点放大
+	 */
+	public void zoomIn() {
+		if (camera != null && camera.getParameters().isZoomSupported()) {
+
+			Camera.Parameters parameters = camera.getParameters();
+			if (parameters.getZoom() >= parameters.getMaxZoom()) {
+				return;
+			}
+
+			parameters.setZoom(parameters.getZoom() + 1);
+			camera.setParameters(parameters);
+
+		}
+	}
+
+	/*
+	 * 缩放
+	 * 
+	 * @param scale
+	 */
+	public void setCameraZoom(int scale) {
+		if (camera != null && camera.getParameters().isZoomSupported()
+				&& scale <= camera.getParameters().getMaxZoom() && scale >= 0) {
+
+			Camera.Parameters parameters = camera.getParameters();
+
+			parameters.setZoom(scale);
+			camera.setParameters(parameters);
+
+		}
+	}
+}

+ 43 - 0
app/src/main/java/cn/jymf/scan/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 cn.jymf.scan.camera;
+
+import android.content.SharedPreferences;
+import cn.jymf.scan.config.Config;
+
+/**
+ * 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(
+				Config.KEY_FRONT_LIGHT_MODE, null));
+	}
+
+}

+ 67 - 0
app/src/main/java/cn/jymf/scan/camera/OpenCameraInterface.java

@@ -0,0 +1,67 @@
+/*
+ * 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 cn.jymf.scan.camera;
+
+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);
+			// CAMERA_FACING_BACK:手机背面的摄像头
+			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;
+	}
+
+}

+ 65 - 0
app/src/main/java/cn/jymf/scan/camera/PreviewCallback.java

@@ -0,0 +1,65 @@
+/*
+ * 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 cn.jymf.scan.camera;
+
+import android.graphics.Point;
+import android.hardware.Camera;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * 该类的作用是在预览界面加载好后向ui线程发消息
+ */
+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;
+	}
+
+	/**
+	 * 绑定handler,用于发消息到ui线程
+	 * 
+	 * @param previewHandler
+	 * @param previewMessage
+	 */
+	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");
+		}
+	}
+
+}

+ 59 - 0
app/src/main/java/cn/jymf/scan/common/BitmapUtils.java

@@ -0,0 +1,59 @@
+package cn.jymf.scan.common;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+public class BitmapUtils {
+
+	public static Bitmap decodeSampledBitmapFromResource(Resources res,
+			int resId, int reqWidth, int reqHeight) {
+
+		// First decode with inJustDecodeBounds=true to check dimensions
+		final BitmapFactory.Options options = new BitmapFactory.Options();
+		options.inJustDecodeBounds = true;
+		BitmapFactory.decodeResource(res, resId, options);
+
+		// Calculate inSampleSize
+		options.inSampleSize = calculateInSampleSize(options, reqWidth,
+				reqHeight);
+
+		// Decode bitmap with inSampleSize set
+		options.inJustDecodeBounds = false;
+		return BitmapFactory.decodeResource(res, resId, options);
+	}
+
+	public static int calculateInSampleSize(BitmapFactory.Options options,
+			int reqWidth, int reqHeight) {
+		// Raw height and width of image
+		final int height = options.outHeight;
+		final int width = options.outWidth;
+		int inSampleSize = 1;
+
+		if (height > reqHeight || width > reqWidth) {
+
+			// Calculate ratios of height and width to requested height and
+			// width
+			final int heightRatio = Math.round((float) height
+					/ (float) reqHeight);
+			final int widthRatio = Math.round((float) width / (float) reqWidth);
+
+			// Choose the smallest ratio as inSampleSize value, this will
+			// guarantee
+			// a final image with both dimensions larger than or equal to the
+			// requested height and width.
+			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
+		}
+
+		return inSampleSize;
+	}
+
+	public static Bitmap getCompressedBitmap(String path) {
+		BitmapFactory.Options options = new BitmapFactory.Options();
+		options.inJustDecodeBounds = true;
+		BitmapFactory.decodeFile(path, options);
+		options.inSampleSize = calculateInSampleSize(options, 480, 800);
+		options.inJustDecodeBounds = false;
+		return BitmapFactory.decodeFile(path, options);
+	}
+}

+ 27 - 0
app/src/main/java/cn/jymf/scan/common/Runnable.java

@@ -0,0 +1,27 @@
+package cn.jymf.scan.common;
+
+import android.annotation.SuppressLint;
+import android.os.AsyncTask;
+import android.os.Build;
+
+/**
+ * 兼容低版本的子线程开启任务
+ * 
+ * @author hugo
+ * 
+ */
+public class Runnable {
+
+	@SuppressLint("NewApi")
+	@SuppressWarnings("unchecked")
+	public static void execAsync(AsyncTask<?, ?, ?> task) {
+		if (Build.VERSION.SDK_INT >= 11) {
+			task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+		}
+		else {
+			task.execute();
+		}
+
+	}
+
+}

+ 54 - 0
app/src/main/java/cn/jymf/scan/config/Config.java

@@ -0,0 +1,54 @@
+/*
+ * 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 cn.jymf.scan.config;
+
+/**
+ * The main settings activity.
+ * 
+ * @author dswitkin@google.com (Daniel Switkin)
+ * @author Sean Owen
+ */
+public final class Config {
+	public static final String KEY_DECODE_1D = "preferences_decode_1D";
+	public static final String KEY_DECODE_1D_PRODUCT = "preferences_decode_1D_product";
+	public static final String KEY_DECODE_1D_INDUSTRIAL = "preferences_decode_1D_industrial";
+	public static final String KEY_DECODE_QR = "preferences_decode_QR";
+	public static final String KEY_DECODE_DATA_MATRIX = "preferences_decode_Data_Matrix";
+	public static final String KEY_DECODE_AZTEC = "preferences_decode_Aztec";
+	public static final String KEY_DECODE_PDF417 = "preferences_decode_PDF417";
+
+	public static final String KEY_CUSTOM_PRODUCT_SEARCH = "preferences_custom_product_search";
+
+	public static final String KEY_PLAY_BEEP = "preferences_play_beep";
+	public static final String KEY_VIBRATE = "preferences_vibrate";
+	public static final String KEY_COPY_TO_CLIPBOARD = "preferences_copy_to_clipboard";
+	public static final String KEY_FRONT_LIGHT_MODE = "preferences_front_light_mode";
+	public static final String KEY_BULK_MODE = "preferences_bulk_mode";
+	public static final String KEY_REMEMBER_DUPLICATES = "preferences_remember_duplicates";
+	public static final String KEY_SUPPLEMENTAL = "preferences_supplemental";
+	public static final String KEY_AUTO_FOCUS = "preferences_auto_focus";
+	public static final String KEY_INVERT_SCAN = "preferences_invert_scan";
+	public static final String KEY_SEARCH_COUNTRY = "preferences_search_country";
+	public static final String KEY_DISABLE_AUTO_ORIENTATION = "preferences_orientation";
+
+	public static final String KEY_DISABLE_CONTINUOUS_FOCUS = "preferences_disable_continuous_focus";
+	public static final String KEY_DISABLE_EXPOSURE = "preferences_disable_exposure";
+	public static final String KEY_DISABLE_METERING = "preferences_disable_metering";
+	public static final String KEY_DISABLE_BARCODE_SCENE_MODE = "preferences_disable_barcode_scene_mode";
+	public static final String KEY_AUTO_OPEN_WEB = "preferences_auto_open_web";
+
+}

+ 75 - 0
app/src/main/java/cn/jymf/scan/decode/BitmapDecoder.java

@@ -0,0 +1,75 @@
+package cn.jymf.scan.decode;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.Result;
+import com.google.zxing.common.HybridBinarizer;
+
+/**
+ * 从bitmap解码
+ * 
+ * @author hugo
+ * 
+ */
+public class BitmapDecoder {
+
+	MultiFormatReader multiFormatReader;
+
+	public BitmapDecoder(Context context) {
+
+		multiFormatReader = new MultiFormatReader();
+
+		// 解码的参数
+		Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(
+				2);
+		// 可以解析的编码类型
+		Vector<BarcodeFormat> decodeFormats = new Vector<BarcodeFormat>();
+		if (decodeFormats == null || decodeFormats.isEmpty()) {
+			decodeFormats = new Vector<BarcodeFormat>();
+
+			// 这里设置可扫描的类型,我这里选择了都支持
+			decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
+			decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
+			decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
+		}
+		hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
+
+		// 设置继续的字符编码格式为UTF8
+		hints.put(DecodeHintType.CHARACTER_SET, "UTF8");
+
+		// 设置解析配置参数
+		multiFormatReader.setHints(hints);
+
+	}
+
+	/**
+	 * 获取解码结果
+	 * 
+	 * @param bitmap
+	 * @return
+	 */
+	public Result getRawResult(Bitmap bitmap) {
+		if (bitmap == null) {
+			return null;
+		}
+
+		try {
+			return multiFormatReader.decodeWithState(new BinaryBitmap(
+					new HybridBinarizer(new BitmapLuminanceSource(bitmap))));
+		}
+		catch (NotFoundException e) {
+			e.printStackTrace();
+		}
+
+		return null;
+	}
+}

+ 37 - 0
app/src/main/java/cn/jymf/scan/decode/BitmapLuminanceSource.java

@@ -0,0 +1,37 @@
+package cn.jymf.scan.decode;
+
+import android.graphics.Bitmap;
+
+import com.google.zxing.LuminanceSource;
+
+public class BitmapLuminanceSource extends LuminanceSource {
+
+	private byte bitmapPixels[];
+
+	protected BitmapLuminanceSource(Bitmap bitmap) {
+		super(bitmap.getWidth(), bitmap.getHeight());
+
+		// 首先,要取得该图片的像素数组内容
+		int[] data = new int[bitmap.getWidth() * bitmap.getHeight()];
+		this.bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
+		bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight());
+
+		// 将int数组转换为byte数组,也就是取像素值中蓝色值部分作为辨析内容
+		for (int i = 0; i < data.length; i++) {
+			this.bitmapPixels[i] = (byte) data[i];
+		}
+	}
+
+	@Override
+	public byte[] getMatrix() {
+		// 返回我们生成好的像素数据
+		return bitmapPixels;
+	}
+
+	@Override
+	public byte[] getRow(int y, byte[] row) {
+		// 这里要得到指定行的像素数据
+		System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth());
+		return row;
+	}
+}

+ 222 - 0
app/src/main/java/cn/jymf/scan/decode/CaptureActivityHandler.java

@@ -0,0 +1,222 @@
+/*
+ * 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 cn.jymf.scan.decode;
+
+import java.util.Collection;
+import java.util.Map;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Browser;
+import android.util.Log;
+import cn.jymf.scan.CaptureActivity;
+import cn.jymf.scan.camera.CameraManager;
+import cn.jymf.scan.view.ViewfinderResultPointCallback;
+import cn.net.communal.cpzshandset.R;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.Result;
+
+/**
+ * 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
+	}
+
+	public 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));
+
+				/**
+				 * 这段代码是zxing项目组想要用chrome打开浏览器浏览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;
+
+			// 向decodeThread绑定的handler(DecodeHandler)发送解码消息
+			cameraManager.requestPreviewFrame(decodeThread.getHandler(),
+					R.id.decode);
+			activity.drawViewfinder();
+		}
+	}
+
+}

+ 107 - 0
app/src/main/java/cn/jymf/scan/decode/DecodeFormatManager.java

@@ -0,0 +1,107 @@
+/*
+ * 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 cn.jymf.scan.decode;
+
+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 cn.jymf.scan.Intents;
+
+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;
+	}
+
+}

+ 148 - 0
app/src/main/java/cn/jymf/scan/decode/DecodeHandler.java

@@ -0,0 +1,148 @@
+/*
+ * 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 cn.jymf.scan.decode;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Map;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import cn.jymf.scan.CaptureActivity;
+import cn.net.communal.cpzshandset.R;
+
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.PlanarYUVLuminanceSource;
+import com.google.zxing.ReaderException;
+import com.google.zxing.Result;
+import com.google.zxing.common.HybridBinarizer;
+
+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;
+
+		byte[] rotatedData = new byte[data.length];
+		for (int y = 0; y < height; y++) {
+			for (int x = 0; x < width; x++)
+				rotatedData[x * height + height - y - 1] = data[x + y * width];
+		}
+		int tmp = width;
+		width = height;
+		height = tmp;
+
+		PlanarYUVLuminanceSource source = activity.getCameraManager()
+				.buildLuminanceSource(rotatedData, width, height);
+		if (source != null) {
+			BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+			try {
+				// 预览界面最终取到的是个bitmap,然后对其进行解码
+				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());
+	}
+
+}

+ 114 - 0
app/src/main/java/cn/jymf/scan/decode/DecodeThread.java

@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.jymf.scan.decode;
+
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.Looper;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import cn.jymf.scan.CaptureActivity;
+import cn.jymf.scan.config.Config;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.ResultPointCallback;
+
+/**
+ * This thread does all the heavy lifting of decoding the images.
+ * 
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+final class DecodeThread extends Thread {
+
+	public static final String BARCODE_BITMAP = "barcode_bitmap";
+
+	public static final String BARCODE_SCALED_FACTOR = "barcode_scaled_factor";
+
+	private final CaptureActivity activity;
+
+	private final Map<DecodeHintType, Object> hints;
+
+	private Handler handler;
+
+	private final CountDownLatch handlerInitLatch;
+
+	DecodeThread(CaptureActivity activity,
+			Collection<BarcodeFormat> decodeFormats,
+			Map<DecodeHintType, ?> baseHints, String characterSet,
+			ResultPointCallback resultPointCallback) {
+
+		this.activity = activity;
+		handlerInitLatch = new CountDownLatch(1);
+
+		hints = new EnumMap<DecodeHintType, 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(Config.KEY_DECODE_1D, false)) {
+				decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
+			}
+			if (prefs.getBoolean(Config.KEY_DECODE_QR, false)) {
+				decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
+			}
+			if (prefs.getBoolean(Config.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();
+	}
+
+}

+ 35 - 0
app/src/main/java/cn/jymf/scan/view/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 cn.jymf.scan.view;
+
+import com.google.zxing.ResultPoint;
+import com.google.zxing.ResultPointCallback;
+
+public final class ViewfinderResultPointCallback implements ResultPointCallback {
+
+	private final ViewfinderView viewfinderView;
+
+	public ViewfinderResultPointCallback(ViewfinderView viewfinderView) {
+		this.viewfinderView = viewfinderView;
+	}
+
+	@Override
+	public void foundPossibleResultPoint(ResultPoint point) {
+		viewfinderView.addPossibleResultPoint(point);
+	}
+
+}

+ 332 - 0
app/src/main/java/cn/jymf/scan/view/ViewfinderView.java

@@ -0,0 +1,332 @@
+package cn.jymf.scan.view;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.util.AttributeSet;
+import android.view.View;
+import cn.jymf.scan.camera.CameraManager;
+import cn.net.communal.cpzshandset.R;
+
+import com.google.zxing.ResultPoint;
+
+/**
+ * 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.
+ * 
+ * <br/>
+ * <br/>
+ * 该视图是覆盖在相机的预览视图之上的一层视图。扫描区构成原理,其实是在预览视图上画四块遮罩层,
+ * 中间留下的部分保持透明,并画上一条激光线,实际上该线条就是展示而已,与扫描功能没有任何关系。
+ * 
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class ViewfinderView extends View {
+
+	/**
+	 * 刷新界面的时间
+	 */
+	private static final long ANIMATION_DELAY = 10L;
+	private static final int OPAQUE = 0xFF;
+
+	private int CORNER_PADDING;
+
+	/**
+	 * 扫描框中的中间线的宽度
+	 */
+	private static int MIDDLE_LINE_WIDTH;
+
+	/**
+	 * 扫描框中的中间线的与扫描框左右的间隙
+	 */
+	private static int MIDDLE_LINE_PADDING;
+
+	/**
+	 * 中间那条线每次刷新移动的距离
+	 */
+	private static final int SPEEN_DISTANCE = 10;
+
+	/**
+	 * 画笔对象的引用
+	 */
+	private Paint paint;
+
+	/**
+	 * 中间滑动线的最顶端位置
+	 */
+	private int slideTop;
+
+	/**
+	 * 中间滑动线的最底端位置
+	 */
+	private int slideBottom;
+
+	private static final int MAX_RESULT_POINTS = 20;
+
+	private Bitmap resultBitmap;
+
+	/**
+	 * 遮掩层的颜色
+	 */
+	private final int maskColor;
+	private final int resultColor;
+
+	private final int resultPointColor;
+	private List<ResultPoint> possibleResultPoints;
+
+	private List<ResultPoint> lastPossibleResultPoints;
+
+	/**
+	 * 第一次绘制控件
+	 */
+	boolean isFirst = true;
+
+	private CameraManager cameraManager;
+
+	// This constructor is used when the class is built from an XML resource.
+	public ViewfinderView(Context context, AttributeSet attrs) {
+		super(context, attrs);
+
+		CORNER_PADDING = dip2px(context, 0.0F);
+		MIDDLE_LINE_PADDING = dip2px(context, 20.0F);
+		MIDDLE_LINE_WIDTH = dip2px(context, 3.0F);
+
+		paint = new Paint(Paint.ANTI_ALIAS_FLAG); // 开启反锯齿
+
+		Resources resources = getResources();
+		maskColor = resources.getColor(R.color.viewfinder_mask); // 遮掩层颜色
+		resultColor = resources.getColor(R.color.result_view);
+
+		resultPointColor = resources.getColor(R.color.possible_result_points);
+		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();
+		if (frame == null) {
+			return;
+		}
+
+		// 绘制遮掩层
+		drawCover(canvas, frame);
+
+		if (resultBitmap != null) { // 绘制扫描结果的图
+			// Draw the opaque result bitmap over the scanning rectangle
+			paint.setAlpha(0xA0);
+			canvas.drawBitmap(resultBitmap, null, frame, paint);
+		}
+		else {
+
+			// 画扫描框边上的角
+			drawRectEdges(canvas, frame);
+
+			// 绘制扫描线
+			drawScanningLine(canvas, frame);
+
+			List<ResultPoint> currentPossible = possibleResultPoints;
+			Collection<ResultPoint> currentLast = lastPossibleResultPoints;
+			if (currentPossible.isEmpty()) {
+				lastPossibleResultPoints = null;
+			}
+			else {
+				possibleResultPoints = new ArrayList<ResultPoint>(5);
+				lastPossibleResultPoints = currentPossible;
+				paint.setAlpha(OPAQUE);
+				paint.setColor(resultPointColor);
+				for (ResultPoint point : currentPossible) {
+					canvas.drawCircle(frame.left + point.getX(), frame.top
+							+ point.getY(), 6.0f, paint);
+				}
+			}
+			if (currentLast != null) {
+				paint.setAlpha(OPAQUE / 2);
+				paint.setColor(resultPointColor);
+				for (ResultPoint point : currentLast) {
+					canvas.drawCircle(frame.left + point.getX(), frame.top
+							+ point.getY(), 3.0f, paint);
+				}
+			}
+
+			// 只刷新扫描框的内容,其他地方不刷新
+			postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top,
+					frame.right, frame.bottom);
+
+		}
+	}
+
+	/**
+	 * 绘制扫描线
+	 * 
+	 * @param canvas
+	 * @param frame
+	 *            扫描框
+	 */
+	private void drawScanningLine(Canvas canvas, Rect frame) {
+
+		// 初始化中间线滑动的最上边和最下边
+		if (isFirst) {
+			isFirst = false;
+			slideTop = frame.top;
+			slideBottom = frame.bottom;
+		}
+
+		// 绘制中间的线,每次刷新界面,中间的线往下移动SPEEN_DISTANCE
+		slideTop += SPEEN_DISTANCE;
+		if (slideTop >= slideBottom) {
+			slideTop = frame.top;
+		}
+
+		// 从图片资源画扫描线
+		Rect lineRect = new Rect();
+		lineRect.left = frame.left + MIDDLE_LINE_PADDING;
+		lineRect.right = frame.right - MIDDLE_LINE_PADDING;
+		lineRect.top = slideTop;
+		lineRect.bottom = (slideTop + MIDDLE_LINE_WIDTH);
+//		canvas.drawBitmap(((BitmapDrawable) (BitmapDrawable) getResources()
+//				.getDrawable(R.drawable.scan_laser)).getBitmap(), null,
+//				lineRect, paint);
+		paint.setColor(Color.GREEN);
+		canvas.drawRect(frame.left + MIDDLE_LINE_PADDING, slideTop
+				- MIDDLE_LINE_WIDTH / 2, frame.right - MIDDLE_LINE_PADDING,
+				slideTop + MIDDLE_LINE_WIDTH / 2, paint);
+
+	}
+
+	/**
+	 * 绘制遮掩层
+	 * 
+	 * @param canvas
+	 * @param frame
+	 */
+	private void drawCover(Canvas canvas, Rect frame) {
+
+		// 获取屏幕的宽和高
+		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);
+	}
+
+	/**
+	 * 描绘方形的四个角
+	 * 
+	 * @param canvas
+	 * @param frame
+	 */
+	private void drawRectEdges(Canvas canvas, Rect frame) {
+
+		paint.setColor(Color.WHITE);
+		paint.setAlpha(OPAQUE);
+
+		Resources resources = getResources();
+		/**
+		 * 这些资源可以用缓存进行管理,不需要每次刷新都新建
+		 */
+		Bitmap bitmapCornerTopleft = BitmapFactory.decodeResource(resources,
+				R.drawable.scan_corner_top_left);
+		Bitmap bitmapCornerTopright = BitmapFactory.decodeResource(resources,
+				R.drawable.scan_corner_top_right);
+		Bitmap bitmapCornerBottomLeft = BitmapFactory.decodeResource(resources,
+				R.drawable.scan_corner_bottom_left);
+		Bitmap bitmapCornerBottomRight = BitmapFactory.decodeResource(
+				resources, R.drawable.scan_corner_bottom_right);
+
+		canvas.drawBitmap(bitmapCornerTopleft, frame.left + CORNER_PADDING,
+				frame.top + CORNER_PADDING, paint);
+		canvas.drawBitmap(bitmapCornerTopright, frame.right - CORNER_PADDING
+				- bitmapCornerTopright.getWidth(), frame.top + CORNER_PADDING,
+				paint);
+		canvas.drawBitmap(bitmapCornerBottomLeft, frame.left + CORNER_PADDING,
+				2 + (frame.bottom - CORNER_PADDING - bitmapCornerBottomLeft
+						.getHeight()), paint);
+		canvas.drawBitmap(bitmapCornerBottomRight, frame.right - CORNER_PADDING
+				- bitmapCornerBottomRight.getWidth(), 2 + (frame.bottom
+				- CORNER_PADDING - bitmapCornerBottomRight.getHeight()), paint);
+
+		bitmapCornerTopleft.recycle();
+		bitmapCornerTopleft = null;
+		bitmapCornerTopright.recycle();
+		bitmapCornerTopright = null;
+		bitmapCornerBottomLeft.recycle();
+		bitmapCornerBottomLeft = null;
+		bitmapCornerBottomRight.recycle();
+		bitmapCornerBottomRight = null;
+
+	}
+
+	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();
+			}
+		}
+	}
+
+	/**
+	 * dp转px
+	 * 
+	 * @param context
+	 * @param dipValue
+	 * @return
+	 */
+	public int dip2px(Context context, float dipValue) {
+		final float scale = context.getResources().getDisplayMetrics().density;
+		return (int) (dipValue * scale + 0.5f);
+	}
+
+}

+ 86 - 0
app/src/main/java/cn/net/communal/cpzshandset/MyHandsetApp.java

@@ -0,0 +1,86 @@
+package cn.net.communal.cpzshandset;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.util.Log;
+
+import com.facebook.stetho.Stetho;
+
+import cilico.tools.barcode.SeuicScanSetting;
+import cn.net.communal.cpzshandset.common.config.Config;
+import cn.net.communal.cpzshandset.common.config.TConfig;
+import cn.net.communal.cpzshandset.common.util.CrashHandler;
+
+public class MyHandsetApp extends Application {
+    private List<Activity> activities;
+    private static Context applicationContext;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        activities = new ArrayList<Activity>();
+        applicationContext = getApplicationContext();
+        if ((!Config.isDebuger) || Config.testForJC) {
+            CrashHandler catchHandler = CrashHandler.getInstance();
+            catchHandler.init(getApplicationContext());
+        }
+//        SeuicScanSetting.init(this);
+        Stetho.initializeWithDefaults(this);
+    }
+
+    public static int getProt(){
+    	SharedPreferences preferences=getAppContext().getSharedPreferences("currentProtTypeConfig", Context.MODE_PRIVATE);
+    	int prot = preferences.getInt("currentProtType", 1);
+    	return prot;
+    }
+    public static int saveProt(){
+    	SharedPreferences preferences=getAppContext().getSharedPreferences("currentProtTypeConfig", Context.MODE_PRIVATE);
+    	int prot = preferences.getInt("currentProtType", 1);
+    	Editor editor=preferences.edit();
+    	int modifyProt = -1 * prot;
+//    	Log.i(TConfig.Echo, "修改为currentProtType:" + modifyProt);
+    	editor.putInt("currentProtType", modifyProt);
+    	editor.commit();
+    	return prot;
+    }
+    public static Context getAppContext() {
+
+        return applicationContext;
+    }
+
+    /**
+     * 将activity 添加到list中
+     *
+     * @param activity
+     */
+    public void addActivity(Activity activity) {
+        activities.add(activity);
+    }
+
+    /**
+     * 从集合中删除当前activity
+     *
+     * @param activity
+     */
+    public void removeActivity(Activity activity) {
+        activities.remove(activity);
+    }
+
+    /**
+     * 退出应用
+     */
+    public void exitApplication() {
+        if (activities != null) {
+            for (Activity activity : activities) {
+                activity.finish();
+            }
+            System.exit(0);
+        }
+    }
+}

+ 148 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ActivateBean.java

@@ -0,0 +1,148 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class ActivateBean implements Serializable{
+	private int id;//id INTEGER PRIMARY KEY AUTOINCREMENT
+	private String product_id;//product_id VARCHAR(20)
+	private String product_date;//product_date VARCHAR(20)
+	private String product_batch_number;//product_batch_number INTEGER
+	private String producer;//producer VARCHAR(20)
+	private long group_number_id;//班组信息
+	private int option_mode = 0;//option_mode INTEGER 0:单标激活  1:批量激活    起亚汽车30 单标 31 批量 
+	private int status = 0;//status INTEGER
+	private int error_code;//error_code INTEGER
+	private String createDate;//createDate DATE DEFAULT (date('now','localtime')))
+	//云天化添加
+	
+	private String group_number;//班组编号  VARCHAR(20),云天化使用
+	private String factory_code = "358000000_6";//厂区编号,云天化使用
+	
+	//--------------------激活并打包添加----------------------------------
+	private int type = 0;//0:激活   1:激活并打包
+	private String package_label_id;//包标签
+	private int packCount;//打包数量
+	
+	//养殖户添加
+	private String farmerName;//养殖户名字
+	private String farmerID;//养殖户id
+	
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getProduct_id() {
+		return product_id;
+	}
+	public void setProduct_id(String product_id) {
+		this.product_id = product_id;
+	}
+	public String getProduct_date() {
+		return product_date;
+	}
+	public void setProduct_date(String product_date) {
+		this.product_date = product_date;
+	}
+	public String getProduct_batch_number() {
+		return product_batch_number;
+	}
+	public void setProduct_batch_number(String product_batch_number) {
+		this.product_batch_number = product_batch_number;
+	}
+	public String getProducer() {
+		return producer;
+	}
+	public void setProducer(String producer) {
+		this.producer = producer;
+	}
+	public int getOption_mode() {
+		return option_mode;
+	}
+	public void setOption_mode(int option_mode) {
+		this.option_mode = option_mode;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(String createDate) {
+		this.createDate = createDate;
+	}
+	public String getGroup_number() {
+		return group_number;
+	}
+	public void setGroup_number(String group_number) {
+		this.group_number = group_number;
+	}
+	
+	public String getFactory_code() {
+		return factory_code;
+	}
+	public void setFactory_code(String factory_code) {
+		this.factory_code = factory_code;
+	}
+	
+	public long getGroup_number_id() {
+		return group_number_id;
+	}
+	public void setGroup_number_id(long group_number_id) {
+		this.group_number_id = group_number_id;
+	}
+	public int getType() {
+		return type;
+	}
+	public void setType(int type) {
+		this.type = type;
+	}
+	public String getPackage_label_id() {
+		return package_label_id;
+	}
+	public void setPackage_label_id(String package_label_id) {
+		this.package_label_id = package_label_id;
+	}
+	public int getPackCount() {
+		return packCount;
+	}
+	public void setPackCount(int packCount) {
+		this.packCount = packCount;
+	}
+	public String getFarmerName() {
+		return farmerName;
+	}
+	public void setFarmerName(String farmerName) {
+		this.farmerName = farmerName;
+	}
+	public String getFarmerID() {
+		return farmerID;
+	}
+	public void setFarmerID(String farmerID) {
+		this.farmerID = farmerID;
+	}
+	@Override
+	public String toString() {
+		return "ActivateBean [id=" + id + ", product_id=" + product_id
+				+ ", product_date=" + product_date + ", product_batch_number="
+				+ product_batch_number + ", producer=" + producer
+				+ ", group_number_id=" + group_number_id + ", option_mode="
+				+ option_mode + ", status=" + status + ", error_code="
+				+ error_code + ", createDate=" + createDate + ", group_number="
+				+ group_number + ", factory_code=" + factory_code + ", type="
+				+ type + ", package_label_id=" + package_label_id
+				+ ", packCount=" + packCount + ", farmerName=" + farmerName
+				+ ", farmerID=" + farmerID + "]";
+	}
+	
+}

+ 86 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/CarNoBean.java

@@ -0,0 +1,86 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class CarNoBean implements Serializable{
+	
+
+	
+	private String carId ;
+	private String carNo;
+	private String carDate;
+	
+	private String engine_number;
+	private String vin;
+	private String label_id;
+
+	
+	private int type = 0;
+	private int num = 0;
+	private int  flag = 1 ;
+	public String getCarId() {
+		return carId;
+	}
+	public void setCarId(String carId) {
+		this.carId = carId;
+	}
+	public String getCarNo() {
+		return carNo;
+	}
+	public void setCarNo(String carNo) {
+		this.carNo = carNo;
+	}
+	public String getCarDate() {
+		return carDate;
+	}
+	public void setCarDate(String carDate) {
+		this.carDate = carDate;
+	}
+	public String getEngine_number() {
+		return engine_number;
+	}
+	public void setEngine_number(String engine_number) {
+		this.engine_number = engine_number;
+	}
+	public String getVin() {
+		return vin;
+	}
+	public void setVin(String vin) {
+		this.vin = vin;
+	}
+	public String getLabel_id() {
+		return label_id;
+	}
+	public void setLabel_id(String label_id) {
+		this.label_id = label_id;
+	}
+	public int getType() {
+		return type;
+	}
+	public void setType(int type) {
+		this.type = type;
+	}
+	public int getNum() {
+		return num;
+	}
+	public void setNum(int num) {
+		this.num = num;
+	}
+	public int getFlag() {
+		return flag;
+	}
+	public void setFlag(int flag) {
+		this.flag = flag;
+	}
+	@Override
+	public String toString() {
+		return "CarNoBean [carId=" + carId + ", carNo=" + carNo + ", carDate="
+				+ carDate + ", engine_number=" + engine_number + ", vin=" + vin
+				+ ", label_id=" + label_id + ", type=" + type + ", num=" + num
+				+ ", flag=" + flag + "]";
+	}
+	
+	
+	
+
+}

+ 47 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ChangeDeviceID.java

@@ -0,0 +1,47 @@
+package cn.net.communal.cpzshandset.bean;
+
+/**
+ * @Description: java类作用描述
+ * @Author: winstronzeng
+ * @CreateDate: 2021/04/19 11:14
+ * @UpdateUser: 更新者:
+ * @UpdateDate: 2021/04/19 11:14
+ * @UpdateRemark: 更新说明:
+ * @Version: 1.0
+ */
+public class ChangeDeviceID {
+
+    /**
+     * Flag : true
+     * Message : 获取企业信息成功!
+     * Data : 358001781
+     */
+
+    private boolean Flag;
+    private String Message;
+    private String Data;
+
+    public boolean isFlag() {
+        return Flag;
+    }
+
+    public void setFlag(boolean Flag) {
+        this.Flag = Flag;
+    }
+
+    public String getMessage() {
+        return Message;
+    }
+
+    public void setMessage(String Message) {
+        this.Message = Message;
+    }
+
+    public String getData() {
+        return Data;
+    }
+
+    public void setData(String Data) {
+        this.Data = Data;
+    }
+}

+ 67 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/City.java

@@ -0,0 +1,67 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class City implements Serializable{
+	private int id;
+	private String provinceName;
+	private String cityName;
+	private int cityCode;
+	private String areasName;
+	
+	public City() {
+	}
+	
+	public City(String provinceName,int cityCode) {
+		this.provinceName = provinceName;
+		this.cityCode = cityCode;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getProvinceName() {
+		return provinceName;
+	}
+
+	public void setProvinceName(String provinceName) {
+		this.provinceName = provinceName;
+	}
+
+	public String getCityName() {
+		return cityName;
+	}
+
+	public void setCityName(String cityName) {
+		this.cityName = cityName;
+	}
+
+	public int getCityCode() {
+		return cityCode;
+	}
+
+	public void setCityCode(int cityCode) {
+		this.cityCode = cityCode;
+	}
+
+	public String getAreasName() {
+		return areasName;
+	}
+
+	public void setAreasName(String areasName) {
+		this.areasName = areasName;
+	}
+
+	@Override
+	public String toString() {
+		return "City [id=" + id + ", provinceName=" + provinceName + ", cityName=" + cityName + ", cityCode=" + cityCode
+				+ ", areasName=" + areasName + "]";
+	}
+
+	
+}

+ 54 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ConfigBean.java

@@ -0,0 +1,54 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class ConfigBean {
+
+	private int handsetMode;//手持机的版本模式(其中的插入值对应于HandsetVersionConstant类中的值),主键,不能重复
+	private String deviceId;//该模式手持机对应的设备ID,存储加密后的数据
+	private int status = 1;
+	private String expand1;
+	private String expand2;
+	
+	public ConfigBean(int handsetMode,String deviceId) {
+		this.handsetMode = handsetMode;
+		this.deviceId = deviceId;
+	}
+	public ConfigBean() {
+	}
+	
+	public String getDeviceId() {
+		return deviceId;
+	}
+	public void setDeviceId(String deviceId) {
+		this.deviceId = deviceId;
+	}
+	public int getHandsetMode() {
+		return handsetMode;
+	}
+	public void setHandsetMode(int handsetMode) {
+		this.handsetMode = handsetMode;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public String getExpand1() {
+		return expand1;
+	}
+	public void setExpand1(String expand1) {
+		this.expand1 = expand1;
+	}
+	public String getExpand2() {
+		return expand2;
+	}
+	public void setExpand2(String expand2) {
+		this.expand2 = expand2;
+	}
+	@Override
+	public String toString() {
+		return "ConfigBean [handsetMode=" + handsetMode + ", deviceId=" + deviceId + ", status=" + status + ", expand1="
+				+ expand1 + ", expand2=" + expand2 + "]";
+	}
+	
+}

+ 61 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/DealerInfoBean.java

@@ -0,0 +1,61 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class DealerInfoBean implements Serializable{
+	private long id;
+	private String name;
+	private int sales_area;
+	private String contacter;
+	private String contacter_phone;
+	private String remark;
+	private int status;
+	public long getId() {
+		return id;
+	}
+	public void setId(long id) {
+		this.id = id;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public int getSales_area() {
+		return sales_area;
+	}
+	public void setSales_area(int sales_area) {
+		this.sales_area = sales_area;
+	}
+	public String getContacter() {
+		return contacter;
+	}
+	public void setContacter(String contacter) {
+		this.contacter = contacter;
+	}
+	public String getContacter_phone() {
+		return contacter_phone;
+	}
+	public void setContacter_phone(String contacter_phone) {
+		this.contacter_phone = contacter_phone;
+	}
+	public String getRemark() {
+		return remark;
+	}
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	@Override
+	public String toString() {
+		return "Prot20037DealerBean [id=" + id + ", name=" + name + ", sales_area=" + sales_area + ", contacter="
+				+ contacter + ", contacter_phone=" + contacter_phone + ", remark=" + remark + ", status=" + status
+				+ "]";
+	}
+}

+ 160 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/DriverInfoBean.java

@@ -0,0 +1,160 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class DriverInfoBean {
+	private long id;
+	private long order_id;//订单ID(关联订单表主键)
+	private String driver_name;//驾驶员姓名
+	private String driver_phone;//驾驶员电话
+	private String car_no;//车牌号
+	private String driver_licenseNo;//驾驶证件号
+	private String out_orderId;//外向交货单号
+	private String num;//计划吨数
+	private String pack_num;//计划包数
+	private int online_status;//状态0:正常1:删除
+	private int native_status;
+	private int error_code;
+	//后添加的
+	private String unit_name;//单位名称
+	private String car_kg;//车货总质量
+	private String huo_kg;//varchar(20) NULL货质量
+	private String dest_addr;//varchar(100) NULL货物流向
+	private String total_money;//varchar(20) NULL运费
+	private String dest_tel;//varchar(20) NULL下货联系电话
+	private String sales_name;//varchar(20) NULL业务员
+	private String remark;//varchar(255) NULL备注
+	
+	public long getId() {
+		return id;
+	}
+	public void setId(long id) {
+		this.id = id;
+	}
+	public long getOrder_id() {
+		return order_id;
+	}
+	public void setOrder_id(long order_id) {
+		this.order_id = order_id;
+	}
+	public String getDriver_name() {
+		return driver_name;
+	}
+	public void setDriver_name(String driver_name) {
+		this.driver_name = driver_name;
+	}
+	public String getDriver_phone() {
+		return driver_phone;
+	}
+	public void setDriver_phone(String driver_phone) {
+		this.driver_phone = driver_phone;
+	}
+	public String getCar_no() {
+		return car_no;
+	}
+	public void setCar_no(String car_no) {
+		this.car_no = car_no;
+	}
+	public String getDriver_licenseNo() {
+		return driver_licenseNo;
+	}
+	public void setDriver_licenseNo(String driver_licenseNo) {
+		this.driver_licenseNo = driver_licenseNo;
+	}
+	public String getOut_orderId() {
+		return out_orderId;
+	}
+	public void setOut_orderId(String out_orderId) {
+		this.out_orderId = out_orderId;
+	}
+	public String getNum() {
+		return num;
+	}
+	public void setNum(String num) {
+		this.num = num;
+	}
+	public String getPack_num() {
+		return pack_num;
+	}
+	public void setPack_num(String pack_num) {
+		this.pack_num = pack_num;
+	}
+	
+	
+	public int getOnline_status() {
+		return online_status;
+	}
+	public void setOnline_status(int online_status) {
+		this.online_status = online_status;
+	}
+	public int getNative_status() {
+		return native_status;
+	}
+	public void setNative_status(int native_status) {
+		this.native_status = native_status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	
+	
+	public String getUnit_name() {
+		return unit_name;
+	}
+	public void setUnit_name(String unit_name) {
+		this.unit_name = unit_name;
+	}
+	public String getCar_kg() {
+		return car_kg;
+	}
+	public void setCar_kg(String car_kg) {
+		this.car_kg = car_kg;
+	}
+	public String getHuo_kg() {
+		return huo_kg;
+	}
+	public void setHuo_kg(String huo_kg) {
+		this.huo_kg = huo_kg;
+	}
+	public String getDest_addr() {
+		return dest_addr;
+	}
+	public void setDest_addr(String dest_addr) {
+		this.dest_addr = dest_addr;
+	}
+	public String getTotal_money() {
+		return total_money;
+	}
+	public void setTotal_money(String total_money) {
+		this.total_money = total_money;
+	}
+	public String getDest_tel() {
+		return dest_tel;
+	}
+	public void setDest_tel(String dest_tel) {
+		this.dest_tel = dest_tel;
+	}
+	public String getSales_name() {
+		return sales_name;
+	}
+	public void setSales_name(String sales_name) {
+		this.sales_name = sales_name;
+	}
+	public String getRemark() {
+		return remark;
+	}
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+	@Override
+	public String toString() {
+		return "DriverInfoBean [id=" + id + ", order_id=" + order_id + ", driver_name=" + driver_name
+				+ ", driver_phone=" + driver_phone + ", car_no=" + car_no + ", driver_licenseNo=" + driver_licenseNo
+				+ ", out_orderId=" + out_orderId + ", num=" + num + ", pack_num=" + pack_num + ", online_status="
+				+ online_status + ", native_status=" + native_status + ", error_code=" + error_code + ", unit_name="
+				+ unit_name + ", car_kg=" + car_kg + ", huo_kg=" + huo_kg + ", dest_addr=" + dest_addr
+				+ ", total_money=" + total_money + ", dest_tel=" + dest_tel + ", sales_name=" + sales_name + ", remark="
+				+ remark + "]";
+	}
+}

+ 83 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ExchangeCargoBean.java

@@ -0,0 +1,83 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class ExchangeCargoBean implements Serializable{
+	private int id;//id:主键自增
+	private int product_id;//product_id:产品id
+	private int from_dealer_id;//from_dealer_id:发货方经销商id
+	private int to_dealer_id;//to_dealer_id:收货方经销商id
+	private int to_dealer_sale_area = 0;
+	private int exchange_count;//exchange_count:调货数量
+	private int option_mode;//option_mode:操作方式 0:单标激活 1:批量激活
+	private int status=0;//status:提交状态 0:未提交 1:提交失败
+	private int error_code;//error_code:服务器返回的错误码
+	private String createDate;//
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public int getProduct_id() {
+		return product_id;
+	}
+	public void setProduct_id(int product_id) {
+		this.product_id = product_id;
+	}
+	public int getFrom_dealer_id() {
+		return from_dealer_id;
+	}
+	public void setFrom_dealer_id(int from_dealer_id) {
+		this.from_dealer_id = from_dealer_id;
+	}
+	public int getTo_dealer_id() {
+		return to_dealer_id;
+	}
+	public void setTo_dealer_id(int to_dealer_id) {
+		this.to_dealer_id = to_dealer_id;
+	}
+	public int getExchange_count() {
+		return exchange_count;
+	}
+	public void setExchange_count(int exchange_count) {
+		this.exchange_count = exchange_count;
+	}
+	public int getOption_mode() {
+		return option_mode;
+	}
+	public void setOption_mode(int option_mode) {
+		this.option_mode = option_mode;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(String createDate) {
+		this.createDate = createDate;
+	}
+	public int getTo_dealer_sale_area() {
+		return to_dealer_sale_area;
+	}
+	public void setTo_dealer_sale_area(int to_dealer_sale_area) {
+		this.to_dealer_sale_area = to_dealer_sale_area;
+	}
+	@Override
+	public String toString() {
+		return "ExchangeCargoBean [id=" + id + ", product_id=" + product_id + ", from_dealer_id=" + from_dealer_id
+				+ ", to_dealer_id=" + to_dealer_id + ", to_dealer_sale_area=" + to_dealer_sale_area
+				+ ", exchange_count=" + exchange_count + ", option_mode=" + option_mode + ", status=" + status
+				+ ", error_code=" + error_code + ", createDate=" + createDate + "]";
+	}
+}

+ 163 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/HandsetParameterBean.java

@@ -0,0 +1,163 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class HandsetParameterBean implements Serializable{
+	private String imei;
+	private String mac;
+	private String serial;//序列号
+	private String brand;//品牌
+	private String androidReleaseVersion;
+	private String cpuName;
+	private String wifiIp;
+	private List<String> appInfos;
+	private long memoryTotalCapacity = 0L;
+	private String memoryTotalCapacityDes;
+	private long memoryAvailableCapacity = 0L;
+	private String memoryAvailableCapacityDes;
+	private long sdcardTotalCapacity = 0L;
+	private String sdcardTotalCapacityDes;
+	private long sdcardAvailableCapacity = 0L;
+	private String sdcardAvailableCapacityDes;
+	private long sysTotalCapacity = 0L;
+	private String sysTotalCapacityDes;
+	private long sysAvailableCapacity = 0L;
+	private String sysAvailableCapacityDes;
+	public String getImei() {
+		return imei;
+	}
+	public void setImei(String imei) {
+		this.imei = imei;
+	}
+	public String getMac() {
+		return mac;
+	}
+	public void setMac(String mac) {
+		this.mac = mac;
+	}
+	public String getSerial() {
+		return serial;
+	}
+	public void setSerial(String serial) {
+		this.serial = serial;
+	}
+	public String getBrand() {
+		return brand;
+	}
+	public void setBrand(String brand) {
+		this.brand = brand;
+	}
+	public String getAndroidReleaseVersion() {
+		return androidReleaseVersion;
+	}
+	public void setAndroidReleaseVersion(String androidReleaseVersion) {
+		this.androidReleaseVersion = androidReleaseVersion;
+	}
+	public String getCpuName() {
+		return cpuName;
+	}
+	public void setCpuName(String cpuName) {
+		this.cpuName = cpuName;
+	}
+	public String getWifiIp() {
+		return wifiIp;
+	}
+	public void setWifiIp(String wifiIp) {
+		this.wifiIp = wifiIp;
+	}
+	public List<String> getAppInfos() {
+		return appInfos;
+	}
+	public void setAppInfos(List<String> appInfos) {
+		this.appInfos = appInfos;
+	}
+	public long getMemoryTotalCapacity() {
+		return memoryTotalCapacity;
+	}
+	public void setMemoryTotalCapacity(long memoryTotalCapacity) {
+		this.memoryTotalCapacity = memoryTotalCapacity;
+	}
+	public String getMemoryTotalCapacityDes() {
+		return memoryTotalCapacityDes;
+	}
+	public void setMemoryTotalCapacityDes(String memoryTotalCapacityDes) {
+		this.memoryTotalCapacityDes = memoryTotalCapacityDes;
+	}
+	public long getMemoryAvailableCapacity() {
+		return memoryAvailableCapacity;
+	}
+	public void setMemoryAvailableCapacity(long memoryAvailableCapacity) {
+		this.memoryAvailableCapacity = memoryAvailableCapacity;
+	}
+	public String getMemoryAvailableCapacityDes() {
+		return memoryAvailableCapacityDes;
+	}
+	public void setMemoryAvailableCapacityDes(String memoryAvailableCapacityDes) {
+		this.memoryAvailableCapacityDes = memoryAvailableCapacityDes;
+	}
+	public long getSdcardTotalCapacity() {
+		return sdcardTotalCapacity;
+	}
+	public void setSdcardTotalCapacity(long sdcardTotalCapacity) {
+		this.sdcardTotalCapacity = sdcardTotalCapacity;
+	}
+	public String getSdcardTotalCapacityDes() {
+		return sdcardTotalCapacityDes;
+	}
+	public void setSdcardTotalCapacityDes(String sdcardTotalCapacityDes) {
+		this.sdcardTotalCapacityDes = sdcardTotalCapacityDes;
+	}
+	public long getSdcardAvailableCapacity() {
+		return sdcardAvailableCapacity;
+	}
+	public void setSdcardAvailableCapacity(long sdcardAvailableCapacity) {
+		this.sdcardAvailableCapacity = sdcardAvailableCapacity;
+	}
+	public String getSdcardAvailableCapacityDes() {
+		return sdcardAvailableCapacityDes;
+	}
+	public void setSdcardAvailableCapacityDes(String sdcardAvailableCapacityDes) {
+		this.sdcardAvailableCapacityDes = sdcardAvailableCapacityDes;
+	}
+	
+	
+	public long getSysTotalCapacity() {
+		return sysTotalCapacity;
+	}
+	public void setSysTotalCapacity(long sysTotalCapacity) {
+		this.sysTotalCapacity = sysTotalCapacity;
+	}
+	public String getSysTotalCapacityDes() {
+		return sysTotalCapacityDes;
+	}
+	public void setSysTotalCapacityDes(String sysTotalCapacityDes) {
+		this.sysTotalCapacityDes = sysTotalCapacityDes;
+	}
+	public long getSysAvailableCapacity() {
+		return sysAvailableCapacity;
+	}
+	public void setSysAvailableCapacity(long sysAvailableCapacity) {
+		this.sysAvailableCapacity = sysAvailableCapacity;
+	}
+	public String getSysAvailableCapacityDes() {
+		return sysAvailableCapacityDes;
+	}
+	public void setSysAvailableCapacityDes(String sysAvailableCapacityDes) {
+		this.sysAvailableCapacityDes = sysAvailableCapacityDes;
+	}
+	@Override
+	public String toString() {
+		return "HandsetParameterBean [imei=" + imei + ", mac=" + mac + ", serial=" + serial + ", brand=" + brand
+				+ ", androidReleaseVersion=" + androidReleaseVersion + ", cpuName=" + cpuName + ", wifiIp=" + wifiIp
+				+ ", appInfos=" + appInfos + ", memoryTotalCapacity=" + memoryTotalCapacity
+				+ ", memoryTotalCapacityDes=" + memoryTotalCapacityDes + ", memoryAvailableCapacity="
+				+ memoryAvailableCapacity + ", memoryAvailableCapacityDes=" + memoryAvailableCapacityDes
+				+ ", sdcardTotalCapacity=" + sdcardTotalCapacity + ", sdcardTotalCapacityDes=" + sdcardTotalCapacityDes
+				+ ", sdcardAvailableCapacity=" + sdcardAvailableCapacity + ", sdcardAvailableCapacityDes="
+				+ sdcardAvailableCapacityDes + ", sysTotalCapacity=" + sysTotalCapacity + ", sysTotalCapacityDes="
+				+ sysTotalCapacityDes + ", sysAvailableCapacity=" + sysAvailableCapacity + ", sysAvailableCapacityDes="
+				+ sysAvailableCapacityDes + "]";
+	}
+
+}

+ 38 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/HomeBean.java

@@ -0,0 +1,38 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class HomeBean implements Serializable{
+	private int operationId;//
+	private int iconId;
+	private String opreationName;
+	public HomeBean() {
+	}
+	public HomeBean(int operationId,int iconId,String opreationName){
+		this.operationId = operationId;
+		this.iconId = iconId;
+		this.opreationName = opreationName;
+	}
+	public int getOperationId() {
+		return operationId;
+	}
+	public void setOperationId(int operationId) {
+		this.operationId = operationId;
+	}
+	public int getIconId() {
+		return iconId;
+	}
+	public void setIconId(int iconId) {
+		this.iconId = iconId;
+	}
+	public String getOpreationName() {
+		return opreationName;
+	}
+	public void setOpreationName(String opreationName) {
+		this.opreationName = opreationName;
+	}
+	@Override
+	public String toString() {
+		return "HomeBean [operationId=" + operationId + ", iconId=" + iconId + ", opreationName=" + opreationName + "]";
+	}
+}

+ 94 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/InvoiceBean.java

@@ -0,0 +1,94 @@
+package cn.net.communal.cpzshandset.bean;
+
+/**
+ * 发运单
+ * @author echo
+ *
+ */
+public class InvoiceBean {
+	private int id;//发货单主键
+	private int transmode;//发运方式: 1:火车发运(车皮)  2:汽车发运(货车)
+	private int transid;//发运单id(火车发运单/汽车发运单)
+	private long transOnlineId;
+	private long trans_product_id;//发货的货物id
+	private long driver_id;//司机id
+	
+	private int elemtype;//类型  1:托盘包含的标签    2:单个产品的标签
+	private String labelid;//标签ID
+	private String timestamp;//时间戳
+	private String package_id;//labelid  对应的 package_idvarchar(32)
+	private int labelStatus = 0;//0:默认状态     1:重复发货
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public int getTransmode() {
+		return transmode;
+	}
+	public void setTransmode(int transmode) {
+		this.transmode = transmode;
+	}
+	public int getTransid() {
+		return transid;
+	}
+	public void setTransid(int transid) {
+		this.transid = transid;
+	}
+	public int getElemtype() {
+		return elemtype;
+	}
+	public void setElemtype(int elemtype) {
+		this.elemtype = elemtype;
+	}
+	public String getLabelid() {
+		return labelid;
+	}
+	public void setLabelid(String labelid) {
+		this.labelid = labelid;
+	}
+	public String getTimestamp() {
+		return timestamp;
+	}
+	public void setTimestamp(String timestamp) {
+		this.timestamp = timestamp;
+	}
+	public String getPackage_id() {
+		return package_id;
+	}
+	public void setPackage_id(String package_id) {
+		this.package_id = package_id;
+	}
+	public long getTransOnlineId() {
+		return transOnlineId;
+	}
+	public void setTransOnlineId(long transOnlineId) {
+		this.transOnlineId = transOnlineId;
+	}
+	public int getLabelStatus() {
+		return labelStatus;
+	}
+	public void setLabelStatus(int labelStatus) {
+		this.labelStatus = labelStatus;
+	}
+	public long getTrans_product_id() {
+		return trans_product_id;
+	}
+	public void setTrans_product_id(long trans_product_id) {
+		this.trans_product_id = trans_product_id;
+	}
+	public long getDriver_id() {
+		return driver_id;
+	}
+	public void setDriver_id(long driver_id) {
+		this.driver_id = driver_id;
+	}
+	@Override
+	public String toString() {
+		return "InvoiceBean [id=" + id + ", transmode=" + transmode + ", transid=" + transid + ", transOnlineId="
+				+ transOnlineId + ", trans_product_id=" + trans_product_id + ", driver_id=" + driver_id + ", elemtype="
+				+ elemtype + ", labelid=" + labelid + ", timestamp=" + timestamp + ", package_id=" + package_id
+				+ ", labelStatus=" + labelStatus + "]";
+	}
+}

+ 100 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/JinLiquorOutWarehouseBean.java

@@ -0,0 +1,100 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class JinLiquorOutWarehouseBean implements Serializable{
+	private long id;
+	private String outWarehouseNo;
+	private String dealerName;
+	private String receiveDealerName;
+	private String warehouseName;
+	private String productName;
+	private int planTrayCount;
+	private int planLabelCount;
+	private int realTrayCount;
+	private int realLabelCount;
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public String getOutWarehouseNo() {
+		return outWarehouseNo;
+	}
+
+	public void setOutWarehouseNo(String outWarehouseNo) {
+		this.outWarehouseNo = outWarehouseNo;
+	}
+
+	public String getDealerName() {
+		return dealerName;
+	}
+
+	public void setDealerName(String dealerName) {
+		this.dealerName = dealerName;
+	}
+
+	public String getReceiveDealerName() {
+		return receiveDealerName;
+	}
+
+	public void setReceiveDealerName(String receiveDealerName) {
+		this.receiveDealerName = receiveDealerName;
+	}
+
+	public int getPlanTrayCount() {
+		return planTrayCount;
+	}
+
+	public void setPlanTrayCount(int planTrayCount) {
+		this.planTrayCount = planTrayCount;
+	}
+
+	public int getPlanLabelCount() {
+		return planLabelCount;
+	}
+
+	public void setPlanLabelCount(int planLabelCount) {
+		this.planLabelCount = planLabelCount;
+	}
+
+	public int getRealTrayCount() {
+		return realTrayCount;
+	}
+
+	public void setRealTrayCount(int realTrayCount) {
+		this.realTrayCount = realTrayCount;
+	}
+
+	public int getRealLabelCount() {
+		return realLabelCount;
+	}
+
+	public void setRealLabelCount(int realLabelCount) {
+		this.realLabelCount = realLabelCount;
+	}
+	public String getProductName() {
+		return productName;
+	}
+	public void setProductName(String productName) {
+		this.productName = productName;
+	}
+
+	public String getWarehouseName() {
+		return warehouseName;
+	}
+	public void setWarehouseName(String warehouseName) {
+		this.warehouseName = warehouseName;
+	}
+	@Override
+	public String toString() {
+		return "JinLiquorOutWarehouseBean [id=" + id + ", outWarehouseNo=" + outWarehouseNo + ", dealerName="
+				+ dealerName + ", receiveDealerName=" + receiveDealerName + ", planTrayCount=" + planTrayCount
+				+ ", planLabelCount=" + planLabelCount + ", realTrayCount=" + realTrayCount + ", realLabelCount="
+				+ realLabelCount + "]";
+	}
+}

+ 59 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/JinLiquorUploadBean.java

@@ -0,0 +1,59 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class JinLiquorUploadBean {
+	private int id;
+	private int option_type;
+	private int tray_count;
+	private int label_count;
+	private String upload_date;
+	private String outWarehouseNo;
+	private String dealer_name;
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public int getOption_type() {
+		return option_type;
+	}
+	public void setOption_type(int option_type) {
+		this.option_type = option_type;
+	}
+	public int getTray_count() {
+		return tray_count;
+	}
+	public void setTray_count(int tray_count) {
+		this.tray_count = tray_count;
+	}
+	public int getLabel_count() {
+		return label_count;
+	}
+	public void setLabel_count(int label_count) {
+		this.label_count = label_count;
+	}
+	public String getUpload_date() {
+		return upload_date;
+	}
+	public void setUpload_date(String upload_date) {
+		this.upload_date = upload_date;
+	}
+	public String getOutWarehouseNo() {
+		return outWarehouseNo;
+	}
+	public void setOutWarehouseNo(String outWarehouseNo) {
+		this.outWarehouseNo = outWarehouseNo;
+	}
+	public String getDealer_name() {
+		return dealer_name;
+	}
+	public void setDealer_name(String dealer_name) {
+		this.dealer_name = dealer_name;
+	}
+	@Override
+	public String toString() {
+		return "JinLiquorUploadBean [id=" + id + ", option_type=" + option_type + ", tray_count=" + tray_count
+				+ ", label_count=" + label_count + ", upload_date=" + upload_date + ", outWarehouseNo=" + outWarehouseNo
+				+ "]";
+	}
+}

+ 58 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/OrderFail.java

@@ -0,0 +1,58 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class OrderFail implements Serializable{
+	//errcode=1064, result=1
+	public OrderFail(int id, int transmode,int errcode,int result) {
+		this.id = id;
+		this.transmode = transmode;
+		this.errcode = errcode;
+		this.result = result;
+	}
+	
+	public OrderFail() {
+	}
+
+	private int errcode;
+	private int result;
+	private int id;//订单id
+	private int transmode;//发运方式: 1:火车发运(车皮)  2:汽车发运(货车)
+	public int getErrcode() {
+		return errcode;
+	}
+
+	public void setErrcode(int errcode) {
+		this.errcode = errcode;
+	}
+
+	public int getResult() {
+		return result;
+	}
+
+	public void setResult(int result) {
+		this.result = result;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public int getTransmode() {
+		return transmode;
+	}
+
+	public void setTransmode(int transmode) {
+		this.transmode = transmode;
+	}
+
+	@Override
+	public String toString() {
+		return "OrderFail [errcode=" + errcode + ", result=" + result + ", id=" + id + ", transmode=" + transmode + "]";
+	}
+	
+}

+ 72 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/PackBean.java

@@ -0,0 +1,72 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+import cn.net.communal.cpzshandset.common.config.Config;
+
+@SuppressWarnings("serial")
+public class PackBean implements Serializable{
+	private int id;//id:表ID,主键自增
+	private String describe;//describe:描述
+	private int count;// count:预设数量
+	private String package_label_id;// package_label_id:包标签
+	private int option_mode = Config.SINGLE_OPTION_LABEL_TYPE;// option_mode:0:单标激活 1:批量激活
+	private int status = 0;// status:提交状态  0:未提交  1:提交失败
+	private int error_code =0;//error_code:服务器返回的错误码
+	private String createDate;// createDate:创建时间
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getDescribe() {
+		return describe;
+	}
+	public void setDescribe(String describe) {
+		this.describe = describe;
+	}
+	public int getCount() {
+		return count;
+	}
+	public void setCount(int count) {
+		this.count = count;
+	}
+	public String getPackage_label_id() {
+		return package_label_id;
+	}
+	public void setPackage_label_id(String package_label_id) {
+		this.package_label_id = package_label_id;
+	}
+	public int getOption_mode() {
+		return option_mode;
+	}
+	public void setOption_mode(int option_mode) {
+		this.option_mode = option_mode;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(String createDate) {
+		this.createDate = createDate;
+	}
+	@Override
+	public String toString() {
+		return "PackBean [id=" + id + ", describe=" + describe + ", count=" + count + ", package_label_id="
+				+ package_label_id + ", option_mode=" + option_mode + ", status=" + status + ", error_code="
+				+ error_code + ", createDate=" + createDate + "]";
+	}
+	
+}

+ 73 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/PackPackageInfoBean.java

@@ -0,0 +1,73 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class PackPackageInfoBean {
+	private int id;
+	private long package_label_id;
+	private int option_id;
+	private int option_type;
+	private int count;
+	private int status;
+	private int error_code;
+	private String bottle_label;
+	private String box_label;
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public long getPackage_label_id() {
+		return package_label_id;
+	}
+	public void setPackage_label_id(long package_label_id) {
+		this.package_label_id = package_label_id;
+	}
+	public int getOption_id() {
+		return option_id;
+	}
+	public void setOption_id(int option_id) {
+		this.option_id = option_id;
+	}
+	public int getOption_type() {
+		return option_type;
+	}
+	public void setOption_type(int option_type) {
+		this.option_type = option_type;
+	}
+	public int getCount() {
+		return count;
+	}
+	public void setCount(int count) {
+		this.count = count;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getBottle_label() {
+		return bottle_label;
+	}
+	public void setBottle_label(String bottle_label) {
+		this.bottle_label = bottle_label;
+	}
+	public String getBox_label() {
+		return box_label;
+	}
+	public void setBox_label(String box_label) {
+		this.box_label = box_label;
+	}
+	@Override
+	public String toString() {
+		return "PackPackageInfoBean [id=" + id + ", package_label_id=" + package_label_id + ", option_id=" + option_id
+				+ ", option_type=" + option_type + ", count=" + count + ", status=" + status + ", error_code="
+				+ error_code + "]";
+	}
+}

+ 58 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/PackSubLabelInfoBean.java

@@ -0,0 +1,58 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class PackSubLabelInfoBean {
+	private int id;
+	private long label_id;
+	private int package_id;//packPackageInfo表中的自增id
+	private int option_id;
+	private int option_type;
+	private int labelStatus;
+	private String sub_label_str;
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public long getLabel_id() {
+		return label_id;
+	}
+	public void setLabel_id(long label_id) {
+		this.label_id = label_id;
+	}
+	public int getPackage_id() {
+		return package_id;
+	}
+	public void setPackage_id(int package_id) {
+		this.package_id = package_id;
+	}
+	public int getOption_id() {
+		return option_id;
+	}
+	public void setOption_id(int option_id) {
+		this.option_id = option_id;
+	}
+	public int getOption_type() {
+		return option_type;
+	}
+	public void setOption_type(int option_type) {
+		this.option_type = option_type;
+	}
+	public int getLabelStatus() {
+		return labelStatus;
+	}
+	public void setLabelStatus(int labelStatus) {
+		this.labelStatus = labelStatus;
+	}
+	public String getSub_label_str() {
+		return sub_label_str;
+	}
+	public void setSub_label_str(String sub_label_str) {
+		this.sub_label_str = sub_label_str;
+	}
+	@Override
+	public String toString() {
+		return "PackSubLabelInfoBean [id=" + id + ", label_id=" + label_id + ", package_id=" + package_id
+				+ ", option_id=" + option_id + ", option_type=" + option_type + ", labelStatus=" + labelStatus + "]";
+	}
+}

Разлика између датотеке није приказан због своје велике величине
+ 18 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ProductBeanList.java


+ 51 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ProductInfo.java

@@ -0,0 +1,51 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class ProductInfo implements Serializable{
+	private int _id;
+	private String product_id;
+	private String name;
+	private String nid;
+	private String product_option;
+	private int addType;
+	public int get_id() {
+		return _id;
+	}
+	public void set_id(int _id) {
+		this._id = _id;
+	}
+	public String getProduct_id() {
+		return product_id;
+	}
+	public void setProduct_id(String product_id) {
+		this.product_id = product_id;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getNid() {
+		return nid;
+	}
+	public void setNid(String nid) {
+		this.nid = nid;
+	}
+	public String getProduct_option() {
+		return product_option;
+	}
+	public void setProduct_option(String product_option) {
+		this.product_option = product_option;
+	}
+	public int getAddType() {
+		return addType;
+	}
+	public void setAddType(int addType) {
+		this.addType = addType;
+	}
+
+	
+	
+}

+ 41 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ReplenishBingBean.java

@@ -0,0 +1,41 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class ReplenishBingBean implements Serializable{
+	private int id;
+	private String packageLabel;
+	private int originalCount;
+	private int canReplenishCount;
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getPackageLabel() {
+		return packageLabel;
+	}
+	public void setPackageLabel(String packageLabel) {
+		this.packageLabel = packageLabel;
+	}
+	public int getOriginalCount() {
+		return originalCount;
+	}
+	public void setOriginalCount(int originalCount) {
+		this.originalCount = originalCount;
+	}
+	public int getCanReplenishCount() {
+		return canReplenishCount;
+	}
+	public void setCanReplenishCount(int canReplenishCount) {
+		this.canReplenishCount = canReplenishCount;
+	}
+	@Override
+	public String toString() {
+		return "ReplenishBingBean [id=" + id + ", packageLabel=" + packageLabel + ", originalCount=" + originalCount
+				+ ", canReplenishCount=" + canReplenishCount + "]";
+	}
+	
+	
+}

+ 38 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ReturnedGoodsBean.java

@@ -0,0 +1,38 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class ReturnedGoodsBean {
+	private int id;
+	private String account;
+	private int status;
+	private int error_code;
+	
+	public String getAccount() {
+		return account;
+	}
+	public void setAccount(String account) {
+		this.account = account;
+	}
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	@Override
+	public String toString() {
+		return "ReturnedGoodsBean [id=" + id + ", account=" + account + ", status=" + status + ", error_code="
+				+ error_code + "]";
+	}
+}

+ 106 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/SaleBean.java

@@ -0,0 +1,106 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+import cn.net.communal.cpzshandset.common.config.Config;
+
+public class SaleBean implements Serializable{
+	private int id;//表ID,自增主键
+	private String describe;//描述
+	private int sales_area;//销售区域的code码
+	private int option_mode = 0;//0:单标激活   1:批量激活
+	private int status = 0;//0:未提交 1:提交失败
+	private int error_code;//提交后服务器返回的错误码
+	private String createDate;//创建时间,insert时自动生成
+	
+	private long dealer_id;//经销商id
+	private int plan_num;//
+	private String purchaser;//采购方
+	private String product_id;//产品id
+	
+	public SaleBean() {
+	}
+	
+	public SaleBean(int sales_area, String describe) {
+		this.sales_area = sales_area;
+		this.describe = describe;
+		option_mode = Config.SINGLE_OPTION_LABEL_TYPE;
+		status = Config.SUBMIT_STATUS_NOT_SUBMIT;
+		error_code = 0;
+		}
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getDescribe() {
+		return describe;
+	}
+	public void setDescribe(String describe) {
+		this.describe = describe;
+	}
+	public int getSales_area() {
+		return sales_area;
+	}
+	public void setSales_area(int sales_area) {
+		this.sales_area = sales_area;
+	}
+	public int getOption_mode() {
+		return option_mode;
+	}
+	public void setOption_mode(int option_mode) {
+		this.option_mode = option_mode;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(String createDate) {
+		this.createDate = createDate;
+	}
+	public long getDealer_id() {
+		return dealer_id;
+	}
+	public void setDealer_id(long dealer_id) {
+		this.dealer_id = dealer_id;
+	}
+
+	public int getPlan_num() {
+		return plan_num;
+	}
+	public void setPlan_num(int plan_num) {
+		this.plan_num = plan_num;
+	}
+	public String getPurchaser() {
+		return purchaser;
+	}
+	public void setPurchaser(String purchaser) {
+		this.purchaser = purchaser;
+	}
+	public String getProduct_id() {
+		return product_id;
+	}
+	public void setProduct_id(String product_id) {
+		this.product_id = product_id;
+	}
+
+	@Override
+	public String toString() {
+		return "SaleBean [id=" + id + ", describe=" + describe + ", sales_area=" + sales_area + ", option_mode="
+				+ option_mode + ", status=" + status + ", error_code=" + error_code + ", createDate=" + createDate
+				+ ", dealer_id=" + dealer_id + ", plan_num=" + plan_num + ", purchaser=" + purchaser + ", product_id="
+				+ product_id + "]";
+	}
+}

+ 105 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ShipmentOnlineOrderBean.java

@@ -0,0 +1,105 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class ShipmentOnlineOrderBean {
+	private long id; 
+	private String orderId;//订单号
+	private String busiUnit;//业务单位
+	private String clientUser;//客户名称
+	private String iszhang;//是否过账,0:未 1:是 2:退单
+	private String pack_num;//件数
+	private String planNum;//计划数量(吨)
+	private String productName;//产品名称
+	private String remark;//备注
+	private String takeAddr;//提货地点
+	private int online_status;//发货状态, 0 是未发货,1是已经发货
+	private int native_status;
+	private int error_code;
+	
+	
+	public long getId() {
+		return id;
+	}
+	public void setId(long id) {
+		this.id = id;
+	}
+	public String getOrderId() {
+		return orderId;
+	}
+	public void setOrderId(String orderId) {
+		this.orderId = orderId;
+	}
+	public String getBusiUnit() {
+		return busiUnit;
+	}
+	public void setBusiUnit(String busiUnit) {
+		this.busiUnit = busiUnit;
+	}
+	public String getClientUser() {
+		return clientUser;
+	}
+	public void setClientUser(String clientUser) {
+		this.clientUser = clientUser;
+	}
+	public String getIszhang() {
+		return iszhang;
+	}
+	public void setIszhang(String iszhang) {
+		this.iszhang = iszhang;
+	}
+	public String getPack_num() {
+		return pack_num;
+	}
+	public void setPack_num(String pack_num) {
+		this.pack_num = pack_num;
+	}
+	public String getPlanNum() {
+		return planNum;
+	}
+	public void setPlanNum(String planNum) {
+		this.planNum = planNum;
+	}
+	public String getProductName() {
+		return productName;
+	}
+	public void setProductName(String productName) {
+		this.productName = productName;
+	}
+	public String getRemark() {
+		return remark;
+	}
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+	public String getTakeAddr() {
+		return takeAddr;
+	}
+	public void setTakeAddr(String takeAddr) {
+		this.takeAddr = takeAddr;
+	}
+	public int getOnline_status() {
+		return online_status;
+	}
+	public void setOnline_status(int online_status) {
+		this.online_status = online_status;
+	}
+	public int getNative_status() {
+		return native_status;
+	}
+	public void setNative_status(int native_status) {
+		this.native_status = native_status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	@Override
+	public String toString() {
+		return "ShipmentOnlineOrderBean [id=" + id + ", orderId=" + orderId + ", busiUnit=" + busiUnit + ", clientUser="
+				+ clientUser + ", iszhang=" + iszhang + ", pack_num=" + pack_num + ", planNum=" + planNum
+				+ ", productName=" + productName + ", remark=" + remark + ", takeAddr=" + takeAddr + ", online_status="
+				+ online_status + ", native_status=" + native_status + ", error_code=" + error_code + "]";
+	}
+	
+}

+ 135 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ShipmentProductBean.java

@@ -0,0 +1,135 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class ShipmentProductBean implements Serializable{
+	private String guozhang_time;//{"guozhang_time":"",
+	private String huowu_name;//"huowu_name":"三环18-5-22尿硫基(50KG)",
+	private long id;//"id":4,
+	private int isguozhang;//"isguozhang":0,
+	private int isshenhe;//"isshenhe":2,
+	private String item_num;//"item_num":"20.0",
+	private String out_order_no;//"out_order_no":"",
+	private String price;//"price":"",
+	private long repertory_id;//"repertory_id":2,
+	private String settle_price;//"settle_price":"2",
+	private int online_status;//"status":2,
+	private String weight;//"weight":"1",
+	private String xiangmu_no;//"xiangmu_no":""}
+	private long driver_id;//driver_id : 1
+	private long order_id;
+	private int native_status;
+	private int error_code;
+	public String getGuozhang_time() {
+		return guozhang_time;
+	}
+	public void setGuozhang_time(String guozhang_time) {
+		this.guozhang_time = guozhang_time;
+	}
+	public String getHuowu_name() {
+		return huowu_name;
+	}
+	public void setHuowu_name(String huowu_name) {
+		this.huowu_name = huowu_name;
+	}
+	public long getId() {
+		return id;
+	}
+	public void setId(long id) {
+		this.id = id;
+	}
+	public int getIsguozhang() {
+		return isguozhang;
+	}
+	public void setIsguozhang(int isguozhang) {
+		this.isguozhang = isguozhang;
+	}
+	public int getIsshenhe() {
+		return isshenhe;
+	}
+	public void setIsshenhe(int isshenhe) {
+		this.isshenhe = isshenhe;
+	}
+	public String getItem_num() {
+		return item_num;
+	}
+	public void setItem_num(String item_num) {
+		this.item_num = item_num;
+	}
+	public String getOut_order_no() {
+		return out_order_no;
+	}
+	public void setOut_order_no(String out_order_no) {
+		this.out_order_no = out_order_no;
+	}
+	public String getPrice() {
+		return price;
+	}
+	public void setPrice(String price) {
+		this.price = price;
+	}
+	public long getRepertory_id() {
+		return repertory_id;
+	}
+	public void setRepertory_id(long repertory_id) {
+		this.repertory_id = repertory_id;
+	}
+	public String getSettle_price() {
+		return settle_price;
+	}
+	public void setSettle_price(String settle_price) {
+		this.settle_price = settle_price;
+	}
+	public String getWeight() {
+		return weight;
+	}
+	public void setWeight(String weight) {
+		this.weight = weight;
+	}
+	public String getXiangmu_no() {
+		return xiangmu_no;
+	}
+	public void setXiangmu_no(String xiangmu_no) {
+		this.xiangmu_no = xiangmu_no;
+	}
+	public int getOnline_status() {
+		return online_status;
+	}
+	public void setOnline_status(int online_status) {
+		this.online_status = online_status;
+	}
+	public int getNative_status() {
+		return native_status;
+	}
+	public void setNative_status(int native_status) {
+		this.native_status = native_status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public long getDriver_id() {
+		return driver_id;
+	}
+	public void setDriver_id(long driver_id) {
+		this.driver_id = driver_id;
+	}
+	public long getOrder_id() {
+		return order_id;
+	}
+	public void setOrder_id(long order_id) {
+		this.order_id = order_id;
+	}
+	@Override
+	public String toString() {
+		return "ShipmentProductBean [guozhang_time=" + guozhang_time + ", huowu_name=" + huowu_name + ", id=" + id
+				+ ", isguozhang=" + isguozhang + ", isshenhe=" + isshenhe + ", item_num=" + item_num + ", out_order_no="
+				+ out_order_no + ", price=" + price + ", repertory_id=" + repertory_id + ", settle_price="
+				+ settle_price + ", online_status=" + online_status + ", weight=" + weight + ", xiangmu_no="
+				+ xiangmu_no + ", driver_id=" + driver_id + ", order_id=" + order_id + ", native_status="
+				+ native_status + ", error_code=" + error_code + "]";
+	}
+	
+}

+ 134 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/ShipmentUploadRecordBean.java

@@ -0,0 +1,134 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class ShipmentUploadRecordBean {
+
+	private long id;
+	private int option_type;//
+	private String account;
+	private long driver_id;
+	private long order_id;
+	private String driver_name;
+	private String driver_tel;
+	private String car_no;
+	private String order_no;
+	private long product_id;
+	private String client_user;
+	private String busi_unit;
+	private String product_name;
+	private int label_count;
+	private String upload_date;
+	private int status;
+	private int error_code;
+	public long getId() {
+		return id;
+	}
+	public void setId(long id) {
+		this.id = id;
+	}
+	public int getOption_type() {
+		return option_type;
+	}
+	public void setOption_type(int option_type) {
+		this.option_type = option_type;
+	}
+	public int getLabel_count() {
+		return label_count;
+	}
+	public void setLabel_count(int label_count) {
+		this.label_count = label_count;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getUpload_date() {
+		return upload_date;
+	}
+	public void setUpload_date(String upload_date) {
+		this.upload_date = upload_date;
+	}
+	public long getDriver_id() {
+		return driver_id;
+	}
+	public void setDriver_id(long driver_id) {
+		this.driver_id = driver_id;
+	}
+	public long getOrder_id() {
+		return order_id;
+	}
+	public void setOrder_id(long order_id) {
+		this.order_id = order_id;
+	}
+	public String getDriver_name() {
+		return driver_name;
+	}
+	public void setDriver_name(String driver_name) {
+		this.driver_name = driver_name;
+	}
+	public String getDriver_tel() {
+		return driver_tel;
+	}
+	public void setDriver_tel(String driver_tel) {
+		this.driver_tel = driver_tel;
+	}
+	public String getCar_no() {
+		return car_no;
+	}
+	public void setCar_no(String car_no) {
+		this.car_no = car_no;
+	}
+	public String getOrder_no() {
+		return order_no;
+	}
+	public void setOrder_no(String order_no) {
+		this.order_no = order_no;
+	}
+	public String getClient_user() {
+		return client_user;
+	}
+	public void setClient_user(String client_user) {
+		this.client_user = client_user;
+	}
+	public String getBusi_unit() {
+		return busi_unit;
+	}
+	public void setBusi_unit(String busi_unit) {
+		this.busi_unit = busi_unit;
+	}
+	public String getProduct_name() {
+		return product_name;
+	}
+	public void setProduct_name(String product_name) {
+		this.product_name = product_name;
+	}
+	public String getAccount() {
+		return account;
+	}
+	public void setAccount(String account) {
+		this.account = account;
+	}
+	public long getProduct_id() {
+		return product_id;
+	}
+	public void setProduct_id(long product_id) {
+		this.product_id = product_id;
+	}
+	@Override
+	public String toString() {
+		return "ShipmentUploadRecordBean [id=" + id + ", option_type=" + option_type + ", account=" + account
+				+ ", driver_id=" + driver_id + ", order_id=" + order_id + ", driver_name=" + driver_name
+				+ ", driver_tel=" + driver_tel + ", car_no=" + car_no + ", order_no=" + order_no + ", product_id="
+				+ product_id + ", client_user=" + client_user + ", busi_unit=" + busi_unit + ", product_name="
+				+ product_name + ", label_count=" + label_count + ", upload_date=" + upload_date + ", status=" + status
+				+ ", error_code=" + error_code + "]";
+	}
+	
+}

+ 77 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/SingleLabelOptionBean.java

@@ -0,0 +1,77 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+@SuppressWarnings("serial")
+public class SingleLabelOptionBean implements Serializable {
+	private int id;
+	private String label_id;
+	private int option_type;
+	private int option_id;
+	private int label_mode = 0;//0:整托  1:单箱
+	private int labelStatus = 0;//0:默认值    1:不合法标签    2:重复激活标签     3:未激活标签
+	
+	public SingleLabelOptionBean() {
+	}
+	
+	public SingleLabelOptionBean(String label_id,int option_type,int option_id) {
+		this.label_id = label_id;
+		this.option_type = option_type;
+		this.option_id = option_id;
+	}
+	public SingleLabelOptionBean(String label_id,int option_type,int option_id,int label_mode) {
+		this.label_id = label_id;
+		this.option_type = option_type;
+		this.option_id = option_id;
+		this.label_mode = label_mode;
+	}
+	public String getLabel_id() {
+		return label_id;
+	}
+
+	public void setLabel_id(String label_id) {
+		this.label_id = label_id;
+	}
+
+	public int getOption_type() {
+		return option_type;
+	}
+
+	public void setOption_type(int option_type) {
+		this.option_type = option_type;
+	}
+
+	public int getOption_id() {
+		return option_id;
+	}
+
+	public void setOption_id(int option_id) {
+		this.option_id = option_id;
+	}
+	
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public int getLabelStatus() {
+		return labelStatus;
+	}
+	public void setLabelStatus(int labelStatus) {
+		this.labelStatus = labelStatus;
+	}
+
+	public int getLabel_mode() {
+		return label_mode;
+	}
+	public void setLabel_mode(int label_mode) {
+		this.label_mode = label_mode;
+	}
+	@Override
+	public String toString() {
+		return "SingleLabelOptionBean [id=" + id + ", label_id=" + label_id + ", option_type=" + option_type
+				+ ", option_id=" + option_id + ", labelStatus=" + labelStatus + "]";
+	}
+}

+ 74 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/StationManagerBean.java

@@ -0,0 +1,74 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+/**
+ * 
+ * @author echo
+ *
+ */
+public class StationManagerBean implements Serializable{
+	private int id;//id:主键
+	private String stationname;//车站名称
+	private String stationdec;//车站描述
+	private String line;//路线
+	private String region;//区域
+	private String regionid;//详细地址列表码的序列(e.g.: 100001,100002,100003)
+	private int transmode;//发送方式  1:火车    2:汽车
+	private int status;//状态  0:有效    1:无效
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getStationname() {
+		return stationname;
+	}
+	public void setStationname(String stationname) {
+		this.stationname = stationname;
+	}
+	public String getStationdec() {
+		return stationdec;
+	}
+	public void setStationdec(String stationdec) {
+		this.stationdec = stationdec;
+	}
+	public String getLine() {
+		return line;
+	}
+	public void setLine(String line) {
+		this.line = line;
+	}
+	public String getRegion() {
+		return region;
+	}
+	public void setRegion(String region) {
+		this.region = region;
+	}
+	public String getRegionid() {
+		return regionid;
+	}
+	public void setRegionid(String regionid) {
+		this.regionid = regionid;
+	}
+	public int getTransmode() {
+		return transmode;
+	}
+	public void setTransmode(int transmode) {
+		this.transmode = transmode;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	
+	@Override
+	public String toString() {
+		return "StationManager [id=" + id + ", stationname=" + stationname + ", stationdec=" + stationdec + ", line="
+				+ line + ", region=" + region + ", regionid=" + regionid + ", transmode=" + transmode + ", status="
+				+ status + "]";
+	}
+}

+ 29 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/TestBean.java

@@ -0,0 +1,29 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class TestBean {
+
+	private int id;
+	private String name;
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@Override
+	public String toString() {
+		return "TestBean [id=" + id + ", name=" + name + "]";
+	}
+
+}

+ 106 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/TrainInvoiceBean.java

@@ -0,0 +1,106 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+import cn.net.communal.cpzshandset.common.config.Config;
+
+/**
+ * 火车发运单
+ * @author echo
+ *
+ */
+public class TrainInvoiceBean implements Serializable{
+	private int id;//主键
+	private String carriageno;//车皮号 P打头后面跟七位数字的字符串
+	private int startingstation;//始发站  目前只有水富站
+	private int terminalstation;//终点站
+	private int consigneeId;
+	private String orderno;//订单号
+	private String timestamp;//时间戳
+	private int labelMode;//0:加法操作     1:减法操作
+	private int status = Config.SUBMIT_STATUS_NOT_SUBMIT;//0:未提交   1:提交失败
+	private int error_code = 0;//:服务器返回的错误码 = 0;
+	private String expand1;
+	private String expand2;
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getCarriageno() {
+		return carriageno;
+	}
+	public void setCarriageno(String carriageno) {
+		this.carriageno = carriageno;
+	}
+	public int getStartingstation() {
+		return startingstation;
+	}
+	public void setStartingstation(int startingstation) {
+		this.startingstation = startingstation;
+	}
+	public int getTerminalstation() {
+		return terminalstation;
+	}
+	public void setTerminalstation(int terminalstation) {
+		this.terminalstation = terminalstation;
+	}
+	public String getOrderno() {
+		return orderno;
+	}
+	public void setOrderno(String orderno) {
+		this.orderno = orderno;
+	}
+	public String getTimestamp() {
+		return timestamp;
+	}
+	public void setTimestamp(String timestamp) {
+		this.timestamp = timestamp;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getLabelMode() {
+		return labelMode;
+	}
+	public void setLabelMode(int labelMode) {
+		this.labelMode = labelMode;
+	}
+	public String getExpand1() {
+		return expand1;
+	}
+	public void setExpand1(String expand1) {
+		this.expand1 = expand1;
+	}
+	public String getExpand2() {
+		return expand2;
+	}
+	public void setExpand2(String expand2) {
+		this.expand2 = expand2;
+	}
+	
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	
+	public int getConsigneeId() {
+		return consigneeId;
+	}
+	public void setConsigneeId(int consigneeId) {
+		this.consigneeId = consigneeId;
+	}
+	@Override
+	public String toString() {
+		return "TrainInvoiceBean [id=" + id + ", carriageno=" + carriageno + ", startingstation=" + startingstation
+				+ ", terminalstation=" + terminalstation + ", consigneeId=" + consigneeId + ", orderno=" + orderno
+				+ ", timestamp=" + timestamp + ", labelMode=" + labelMode + ", status=" + status + ", error_code="
+				+ error_code + ", expand1=" + expand1 + ", expand2=" + expand2 + "]";
+	}
+}

+ 64 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/TruckAddressBean.java

@@ -0,0 +1,64 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class TruckAddressBean {
+
+	private int id;//主键,自增
+	private int cityCode;//cityCode:三级地址信息的Code码
+	private String detailAddress;//detailAddress:详细地址信息的文字信息
+	private int originType;//来源   0:本地生成    1:服务器获取
+	private String createDate;//createDate:创建时间
+	private String updateDate;//updateDate:更新日期
+	
+	public TruckAddressBean() {
+		// TODO Auto-generated constructor stub
+	}
+	public TruckAddressBean(int id,int cityCode,String detailAddress,int originType,String createDate) {
+		this.id = id;
+		this.cityCode = cityCode;
+		this.detailAddress = detailAddress;
+		this.originType = originType;
+		this.createDate = createDate;
+	}
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public int getCityCode() {
+		return cityCode;
+	}
+	public void setCityCode(int cityCode) {
+		this.cityCode = cityCode;
+	}
+	public String getDetailAddress() {
+		return detailAddress;
+	}
+	public void setDetailAddress(String detailAddress) {
+		this.detailAddress = detailAddress;
+	}
+	public int getOriginType() {
+		return originType;
+	}
+	public void setOriginType(int originType) {
+		this.originType = originType;
+	}
+	public String getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(String createDate) {
+		this.createDate = createDate;
+	}
+	public String getUpdateDate() {
+		return updateDate;
+	}
+	public void setUpdateDate(String updateDate) {
+		this.updateDate = updateDate;
+	}
+	@Override
+	public String toString() {
+		return "TruckAddressBean [id=" + id + ", cityCode=" + cityCode + ", detailAddress=" + detailAddress
+				+ ", originType=" + originType + ", createDate=" + createDate + ", updateDate=" + updateDate + "]";
+	}
+	
+}

+ 51 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/TruckConsigeeBean.java

@@ -0,0 +1,51 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class TruckConsigeeBean {
+	private int id;
+	private String consigneeName;
+	private String createDate;
+	private int originType = 0;//originType:来源   0:本地生成    1:服务器获取
+	public TruckConsigeeBean() {
+	}
+	/*public TruckConsigeeBean(int id,String consigneeName,String createDate,int originType) {
+		this.id = id;
+		this.consigneeName = consigneeName;
+		this.createDate = createDate;
+		this.originType = originType;
+	}
+	
+	public TruckConsigeeBean(String consigneeName,int originType) {
+		this.consigneeName = consigneeName;
+		this.originType = originType;
+	}*/
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getConsigneeName() {
+		return consigneeName;
+	}
+	public void setConsigneeName(String consigneeName) {
+		this.consigneeName = consigneeName;
+	}
+	public String getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(String createDate) {
+		this.createDate = createDate;
+	}
+	public int getOriginType() {
+		return originType;
+	}
+	public void setOriginType(int originType) {
+		this.originType = originType;
+	}
+	@Override
+	public String toString() {
+		return "TruckConsigeeBean [id=" + id + ", consigneeName=" + consigneeName + ", createDate=" + createDate
+				+ ", originType=" + originType + "]";
+	}
+	
+}

+ 202 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/TruckInvoiceBean.java

@@ -0,0 +1,202 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+import cn.net.communal.cpzshandset.common.config.Config;
+
+/**
+ * 汽车发运单
+ * 
+ * @author echo
+ *
+ */
+public class TruckInvoiceBean implements Serializable {
+	private int id;// 主键
+	private String responsiblePersonId;//责任人
+	private String truckno;// 车牌号
+	private String drivername;// 司机名称
+	private String driverphone;// 司机电话
+	private String orderno;// 订单号
+	private int startingstation;// 始发站
+	private int terminalstation;// 终点站
+	private int consigneeId;//收货人
+	private String timestamp;// 时间戳
+	private int labelMode;// 1:加法操作  -1:减法操作
+	private int status = Config.SUBMIT_STATUS_NOT_SUBMIT;// 0:未提交 1:提交失败
+	private int error_code = 0;// 服务器返回的错误码
+	private String expand1;
+	private String expand2;
+	private String gruopInfo;//班组信息
+	private int terminalStationCode;//收货地区的Code码
+	private String detailAddress;//收货地址的详细地址
+	private String consignee;//收货单位
+	private int option_mode;//操作方式   0:单标发货   1:托盘发货
+	
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+	
+	public String getResponsiblePersonId() {
+		return responsiblePersonId;
+	}
+	public void setResponsiblePersonId(String responsiblePersonId) {
+		this.responsiblePersonId = responsiblePersonId;
+	}
+
+	public String getTruckno() {
+		return truckno;
+	}
+
+	public void setTruckno(String truckno) {
+		this.truckno = truckno;
+	}
+
+	public String getDrivername() {
+		return drivername;
+	}
+
+	public void setDrivername(String drivername) {
+		this.drivername = drivername;
+	}
+
+	public String getDriverphone() {
+		return driverphone;
+	}
+
+	public void setDriverphone(String driverphone) {
+		this.driverphone = driverphone;
+	}
+
+	public String getOrderno() {
+		return orderno;
+	}
+
+	public void setOrderno(String orderno) {
+		this.orderno = orderno;
+	}
+
+	public int getStartingstation() {
+		return startingstation;
+	}
+
+	public void setStartingstation(int startingstation) {
+		this.startingstation = startingstation;
+	}
+
+	public int getTerminalstation() {
+		return terminalstation;
+	}
+
+	public void setTerminalstation(int terminalstation) {
+		this.terminalstation = terminalstation;
+	}
+
+	public String getTimestamp() {
+		return timestamp;
+	}
+
+	public void setTimestamp(String timestamp) {
+		this.timestamp = timestamp;
+	}
+
+	public int getStatus() {
+		return status;
+	}
+
+	public void setStatus(int status) {
+		this.status = status;
+	}
+
+	public int getLabelMode() {
+		return labelMode;
+	}
+
+	public void setLabelMode(int labelMode) {
+		this.labelMode = labelMode;
+	}
+
+	public String getExpand1() {
+		return expand1;
+	}
+
+	public void setExpand1(String expand1) {
+		this.expand1 = expand1;
+	}
+
+	public String getExpand2() {
+		return expand2;
+	}
+
+	public void setExpand2(String expand2) {
+		this.expand2 = expand2;
+	}
+
+	public int getError_code() {
+		return error_code;
+	}
+
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public int getConsigneeId() {
+		return consigneeId;
+	}
+	public void setConsigneeId(int consigneeId) {
+		this.consigneeId = consigneeId;
+	}
+	
+
+	public String getGruopInfo() {
+		return gruopInfo;
+	}
+
+	public void setGruopInfo(String gruopInfo) {
+		this.gruopInfo = gruopInfo;
+	}
+
+	public int getTerminalStationCode() {
+		return terminalStationCode;
+	}
+
+	public void setTerminalStationCode(int terminalStationCode) {
+		this.terminalStationCode = terminalStationCode;
+	}
+
+	public String getDetailAddress() {
+		return detailAddress;
+	}
+
+	public void setDetailAddress(String detailAddress) {
+		this.detailAddress = detailAddress;
+	}
+
+	public String getConsignee() {
+		return consignee;
+	}
+
+	public void setConsignee(String consignee) {
+		this.consignee = consignee;
+	}
+	public int getOption_mode() {
+		return option_mode;
+	}
+	public void setOption_mode(int option_mode) {
+		this.option_mode = option_mode;
+	}
+
+	@Override
+	public String toString() {
+		return "TruckInvoiceBean [id=" + id + ", responsiblePersonId=" + responsiblePersonId + ", truckno=" + truckno
+				+ ", drivername=" + drivername + ", driverphone=" + driverphone + ", orderno=" + orderno
+				+ ", startingstation=" + startingstation + ", terminalstation=" + terminalstation + ", consigneeId="
+				+ consigneeId + ", timestamp=" + timestamp + ", labelMode=" + labelMode + ", status=" + status
+				+ ", error_code=" + error_code + ", expand1=" + expand1 + ", expand2=" + expand2 + ", gruopInfo="
+				+ gruopInfo + ", terminalStationCode=" + terminalStationCode + ", detailAddress=" + detailAddress
+				+ ", consignee=" + consignee + ", option_mode=" + option_mode + "]";
+	}
+}

+ 52 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/UnpackBean.java

@@ -0,0 +1,52 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class UnpackBean {
+	private int id;
+	private String label_id;
+	private int status = 0;//0:未提交  1:提交失败
+	private int error_code;
+	private String createDate;
+	
+	public UnpackBean() {
+	}
+	public UnpackBean(String label_id) {
+		this.label_id = label_id;
+		this.status = 0;
+		this.error_code = 0;
+	}
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getLabel_id() {
+		return label_id;
+	}
+	public void setLabel_id(String label_id) {
+		this.label_id = label_id;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(String createDate) {
+		this.createDate = createDate;
+	}
+	@Override
+	public String toString() {
+		return "UnpackBean [id=" + id + ", label_id=" + label_id + ", status=" + status + ", error_code=" + error_code
+				+ ", createDate=" + createDate + "]";
+	}
+}

+ 59 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/UploadBean.java

@@ -0,0 +1,59 @@
+package cn.net.communal.cpzshandset.bean;
+
+public class UploadBean {
+
+	private int id;
+	private int option_type;
+	private int label_count;
+	private int status;
+	private int error_code;
+	private String upload_date;
+//	private String account;
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public int getOption_type() {
+		return option_type;
+	}
+	public void setOption_type(int option_type) {
+		this.option_type = option_type;
+	}
+	public int getLabel_count() {
+		return label_count;
+	}
+	public void setLabel_count(int label_count) {
+		this.label_count = label_count;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getUpload_date() {
+		return upload_date;
+	}
+	public void setUpload_date(String upload_date) {
+		this.upload_date = upload_date;
+	}
+//	public String getAccount() {
+//		return account;
+//	}
+//	public void setAccount(String account) {
+//		this.account = account;
+//	}
+//	@Override
+//	public String toString() {
+//		return "UploadBean [id=" + id + ", option_type=" + option_type + ", label_count=" + label_count + ", status="
+//				+ status + ", error_code=" + error_code + ", upload_date=" + upload_date + ", account=" + account + "]";
+//	}
+}

+ 123 - 0
app/src/main/java/cn/net/communal/cpzshandset/bean/WarehouseBean.java

@@ -0,0 +1,123 @@
+package cn.net.communal.cpzshandset.bean;
+
+import java.io.Serializable;
+
+public class WarehouseBean implements Serializable{
+	private int id;//表ID,自增主键
+	private String describe;//描述
+	private int option_type;//操作类型(5:出库4:入库 6:返库 )同HansetOperationConstant中的数据
+	private int option_mode = 0;//0:单标激活  1:批量激活  实质只有单标方式的操作
+	private int sale_area_code;//销售区域
+	private int status = 0;//0:未提交  1:提交失败
+	private int error_code=0;//提交后服务器返回的错误码
+	private String createDate;//创建时间,insert时自动生成的
+	
+	private String planNumber;//计划数目
+	private int outWarehouseType;//出库类型 1 托盘出库 2普通出库 
+	
+	private int plan_num;
+	private long dealer_id;//经销商id
+	private String product_id;
+	private String to_sale_user_account;//出库到人员的账户名称
+	
+	
+	public WarehouseBean() {
+	}
+	public WarehouseBean(String describe,int option_type) {
+		this.describe = describe;
+		this.option_type = option_type;
+	}
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+	public String getDescribe() {
+		return describe;
+	}
+	public void setDescribe(String describe) {
+		this.describe = describe;
+	}
+	public int getOption_type() {
+		return option_type;
+	}
+	public void setOption_type(int option_type) {
+		this.option_type = option_type;
+	}
+	public int getOption_mode() {
+		return option_mode;
+	}
+	public void setOption_mode(int option_mode) {
+		this.option_mode = option_mode;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public int getError_code() {
+		return error_code;
+	}
+	public void setError_code(int error_code) {
+		this.error_code = error_code;
+	}
+	public String getCreateDate() {
+		return createDate;
+	}
+	public void setCreateDate(String createDate) {
+		this.createDate = createDate;
+	}
+	public int getSale_area_code() {
+		return sale_area_code;
+	}
+	public void setSale_area_code(int sale_area_code) {
+		this.sale_area_code = sale_area_code;
+	}
+	
+	public String getPlanNumber() {
+		return planNumber;
+	}
+	public void setPlanNumber(String planNumber) {
+		this.planNumber = planNumber;
+	}
+	public int getOutWarehouseType() {
+		return outWarehouseType;
+	}
+	public void setOutWarehouseType(int outWarehouseType) {
+		this.outWarehouseType = outWarehouseType;
+	}
+	public int getPlan_num() {
+		return plan_num;
+	}
+	public void setPlan_num(int plan_num) {
+		this.plan_num = plan_num;
+	}
+	public long getDealer_id() {
+		return dealer_id;
+	}
+	public void setDealer_id(long dealer_id) {
+		this.dealer_id = dealer_id;
+	}
+	public String getProduct_id() {
+		return product_id;
+	}
+	public void setProduct_id(String product_id) {
+		this.product_id = product_id;
+	}
+	public String getTo_sale_user_account() {
+		return to_sale_user_account;
+	}
+	public void setTo_sale_user_account(String to_sale_user_account) {
+		this.to_sale_user_account = to_sale_user_account;
+	}
+	@Override
+	public String toString() {
+		return "WarehouseBean [id=" + id + ", describe=" + describe + ", option_type=" + option_type + ", option_mode="
+				+ option_mode + ", sale_area_code=" + sale_area_code + ", status=" + status + ", error_code="
+				+ error_code + ", createDate=" + createDate + ", planNumber=" + planNumber + ", outWarehouseType="
+				+ outWarehouseType + ", plan_num=" + plan_num + ", dealer_id=" + dealer_id + ", product_id="
+				+ product_id + ", to_sale_user_account=" + to_sale_user_account + "]";
+	}
+}

+ 187 - 0
app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/BitmapUtil.java

@@ -0,0 +1,187 @@
+package cn.net.communal.cpzshandset.common.bitmap;
+
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+public class BitmapUtil {
+	private static int mDesiredWidth;
+	private static int mDesiredHeight;
+
+	/**
+	 * @description 从Resources中加载图片
+	 *
+	 * @param res
+	 * @param resId
+	 * @param reqWidth
+	 * @param reqHeight
+	 * @return
+	 */
+	public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
+		BitmapFactory.Options options = new BitmapFactory.Options();
+		// 设置成了true,不占用内存,只获取bitmap宽高
+		options.inJustDecodeBounds = true;
+		// 初始化options对象
+		BitmapFactory.decodeResource(res, resId, options);
+		// 得到计算好的options,目标宽、目标高
+		options = getBestOptions(options, reqWidth, reqHeight);
+		Bitmap src = BitmapFactory.decodeResource(res, resId, options); // 载入一个稍大的缩略图
+		return createScaleBitmap(src, mDesiredWidth, mDesiredHeight); // 进一步得到目标大小的缩略图
+	}
+
+	/**
+	 * @description 从SD卡上加载图片
+	 *
+	 * @param pathName
+	 * @param reqWidth
+	 * @param reqHeight
+	 * @return
+	 */
+	public static Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) {
+		BitmapFactory.Options options = new BitmapFactory.Options();
+		options.inJustDecodeBounds = true;
+		BitmapFactory.decodeFile(pathName, options);
+		options = getBestOptions(options, reqWidth, reqHeight);
+		Bitmap src = BitmapFactory.decodeFile(pathName, options);
+		return createScaleBitmap(src, mDesiredWidth, mDesiredHeight);
+	}
+	
+	/**
+	 * @description 压缩加载的网络图片
+	 *
+	 * @param pathName
+	 * @param reqWidth
+	 * @param reqHeight
+	 * @return
+	 */
+	/*public static Bitmap decodeSampledBitmapFromFile(InputStream is, int reqWidth, int reqHeight) {
+		BitmapFactory.Options options = new BitmapFactory.Options();
+		options.inJustDecodeBounds = true;
+		options = getBestOptions(options, reqWidth, reqHeight);
+		Bitmap src = BitmapFactory.decodeStream(is, null, options);
+		return createScaleBitmap(src, mDesiredWidth, mDesiredHeight);
+	}*/
+	
+	/**
+	 * @description 压缩加载的网络图片
+	 *
+	 * @param pathName
+	 * @param reqWidth
+	 * @param reqHeight
+	 * @return
+	 */
+	public static Bitmap decodeSampledBitmapFromFile(Bitmap bitmap, int reqWidth, int reqHeight) {
+		BitmapFactory.Options options = new BitmapFactory.Options();
+		options.inJustDecodeBounds = true;
+		options = getBestOptions(options, reqWidth, reqHeight);
+				
+		return createScaleBitmap(bitmap, mDesiredWidth, mDesiredHeight);
+	}
+
+	/**
+	 * @description 计算目标宽度,目标高度,inSampleSize
+	 *
+	 * @param options
+	 * @param reqWidth
+	 * @param reqHeight
+	 * @return BitmapFactory.Options对象
+	 */
+	private static BitmapFactory.Options getBestOptions(BitmapFactory.Options options, int reqWidth, int reqHeight) {
+		// 读取图片长宽
+		int actualWidth = options.outWidth;
+		int actualHeight = options.outHeight;
+		// Then compute the dimensions we would ideally like to decode to.
+		mDesiredWidth = getResizedDimension(reqWidth, reqHeight, actualWidth, actualHeight);
+		mDesiredHeight = getResizedDimension(reqHeight, reqWidth, actualHeight, actualWidth);
+		// 根据现在得到计算inSampleSize
+		options.inSampleSize = calculateBestInSampleSize(actualWidth, actualHeight, mDesiredWidth, mDesiredHeight);
+		// 使用获取到的inSampleSize值再次解析图片
+		options.inJustDecodeBounds = false;
+		return options;
+	}
+
+	/**
+	 * Scales one side of a rectangle to fit aspect ratio. 最终得到重新测量的尺寸
+	 *
+	 * @param maxPrimary
+	 *            Maximum size of the primary dimension (i.e. width for max
+	 *            width), or zero to maintain aspect ratio with secondary
+	 *            dimension
+	 * @param maxSecondary
+	 *            Maximum size of the secondary dimension, or zero to maintain
+	 *            aspect ratio with primary dimension
+	 * @param actualPrimary
+	 *            Actual size of the primary dimension
+	 * @param actualSecondary
+	 *            Actual size of the secondary dimension
+	 */
+	private static int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary, int actualSecondary) {
+		double ratio = (double) actualSecondary / (double) actualPrimary;
+		int resized = maxPrimary;
+		if (resized * ratio > maxSecondary) {
+			resized = (int) (maxSecondary / ratio);
+		}
+		return resized;
+	}
+
+	/**
+	 * Returns the largest power-of-two divisor for use in downscaling a bitmap
+	 * that will not result in the scaling past the desired dimensions.
+	 *
+	 * @param actualWidth
+	 *            Actual width of the bitmap
+	 * @param actualHeight
+	 *            Actual height of the bitmap
+	 * @param desiredWidth
+	 *            Desired width of the bitmap
+	 * @param desiredHeight
+	 *            Desired height of the bitmap
+	 */
+	// Visible for testing.
+	private static int calculateBestInSampleSize(int actualWidth, int actualHeight, int desiredWidth,
+			int desiredHeight) {
+		double wr = (double) actualWidth / desiredWidth;
+		double hr = (double) actualHeight / desiredHeight;
+		double ratio = Math.min(wr, hr);
+		float inSampleSize = 1.0f;
+		while ((inSampleSize * 2) <= ratio) {
+			inSampleSize *= 2;
+		}
+
+		return (int) inSampleSize;
+	}
+
+	/**
+	 * @description 通过传入的bitmap,进行压缩,得到符合标准的bitmap
+	 *
+	 * @param src
+	 * @param dstWidth
+	 * @param dstHeight
+	 * @return
+	 */
+	public static Bitmap createScaleBitmap(Bitmap tempBitmap, int desiredWidth, int desiredHeight) {
+		// If necessary, scale down to the maximal acceptable size.
+		if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth || tempBitmap.getHeight() > desiredHeight)) {
+			// 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响
+			Bitmap bitmap = Bitmap.createScaledBitmap(tempBitmap, desiredWidth, desiredHeight, true);
+			tempBitmap.recycle(); // 释放Bitmap的native像素数组
+			return bitmap;
+		} else {
+			return tempBitmap; // 如果没有缩放,那么不回收
+		}
+	}
+
+
+
+	private void bitmapRecycle(Bitmap bitmap) {
+		// 先判断是否已经回收
+		if (bitmap != null && !bitmap.isRecycled()) {
+			// 回收并且置为null
+			bitmap.recycle();
+			bitmap = null;
+		}
+		System.gc();
+	}
+
+}

+ 47 - 0
app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/FileCache.java

@@ -0,0 +1,47 @@
+package cn.net.communal.cpzshandset.common.bitmap;
+
+import java.io.File;
+
+public class FileCache
+{
+  private String cachePath;
+
+  public FileCache(String cachePath)
+  {
+    this.cachePath = cachePath;
+    createCacheDir();
+  }
+
+  public String getSavePath(String url) {
+    String filename = String.valueOf(url.hashCode());
+    return this.cachePath + "/" + filename;
+  }
+
+  public File getFile(String url) {
+    File f = new File(getSavePath(url));
+    return f;
+  }
+
+  public void clear()
+  {
+    deleteCache();
+  }
+
+  private void deleteCache()
+  {
+    File cacheFile = new File(this.cachePath);
+    if (cacheFile.isDirectory()) {
+      for (File file : cacheFile.listFiles()) {
+        file.delete();
+      }
+      cacheFile.delete();
+    }
+  }
+
+  private void createCacheDir()
+  {
+    File file = new File(this.cachePath);
+    if (!file.exists())
+      file.mkdirs();
+  }
+}

+ 285 - 0
app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/ImageLoader.java

@@ -0,0 +1,285 @@
+package cn.net.communal.cpzshandset.common.bitmap;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.widget.ImageView;
+import cn.net.communal.cpzshandset.common.util.LogUtil;
+
+public class ImageLoader {
+	private MemoryCache memoryCache = new MemoryCache();
+	private FileCache fileCache;
+	private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap());
+	private ExecutorService executorService;
+	private boolean isLoadOnlyFromCache = false;
+	private ArrayList<Integer> myList = null;
+	private boolean isdownload = false;
+
+	public ImageLoader(String cachePath) {
+		this.myList = new ArrayList();
+		this.fileCache = new FileCache(cachePath);
+		this.executorService = Executors.newFixedThreadPool(3);
+	}
+	
+	public void DisplayImage(String url, ImageView imageView, boolean isC, int w, int h, float r) {
+		this.imageViews.put(imageView, url);
+
+		Bitmap bitmap = this.memoryCache.get(url);
+		if (bitmap != null) {
+			imageView.setBackgroundDrawable(new BitmapDrawable(bitmap));
+		} else if (!this.isLoadOnlyFromCache) {
+			queuePhoto(url, imageView, isC, w, h, r);
+		}
+	}
+
+	public Bitmap createFramedPhoto(int x, int y, Bitmap image, float outerRadiusRat) {
+		Drawable imageDrawable = new BitmapDrawable(image);
+
+		Bitmap output = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
+		Canvas canvas = new Canvas(output);
+
+		RectF outerRect = new RectF(0.0F, 0.0F, x, y);
+
+		Paint paint = new Paint(1);
+		paint.setColor(-65536);
+		canvas.drawRoundRect(outerRect, outerRadiusRat, outerRadiusRat, paint);
+
+		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+		imageDrawable.setBounds(0, 0, x, y);
+		canvas.saveLayer(outerRect, paint, 31);
+		imageDrawable.draw(canvas);
+		canvas.restore();
+
+		return output;
+	}
+
+	@SuppressLint({ "UseValueOf" })
+	public void DisplayNetImage(String url, ImageView imageView, int index, int count, boolean isC, int x, int y,
+			float r) {
+		this.imageViews.put(imageView, url);
+
+		Bitmap bitmap = this.memoryCache.get(url);
+		if (bitmap != null) {
+			imageView.setBackgroundDrawable(new BitmapDrawable(bitmap));
+		} else if (!this.isLoadOnlyFromCache) {
+			if (this.myList.isEmpty()) {
+				this.myList.add(Integer.valueOf(index));
+				this.isdownload = true;
+			} else {
+				int flog = new Integer(((Integer) this.myList.get(this.myList.size() - 1)).toString()).intValue();
+				if ((flog + 1 == index) && (this.myList.size() <= count)) {
+					this.myList.add(Integer.valueOf(index));
+					this.isdownload = true;
+				}
+			}
+
+			if (this.isdownload) {
+				queuePhoto(url, imageView, isC, x, y, r);
+				this.isdownload = false;
+			}
+		}
+	}
+
+	private void queuePhoto(String url, ImageView imageView, boolean isC, int x, int y, float r) {
+		PhotoToLoad p = new PhotoToLoad(url, imageView, isC, x, y, r);
+		this.executorService.submit(new PhotosLoader(p));
+	}
+
+	public static Bitmap returnBitMap(String url, boolean isCut, int x, int y, float outerRadiusRat) {
+		URL myFileUrl = null;
+		Bitmap bitmap = null;
+		try {
+			myFileUrl = new URL(url);
+
+			HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
+
+			conn.setDoInput(true);
+			conn.connect();
+			InputStream is = conn.getInputStream();
+			bitmap = BitmapFactory.decodeStream(is);
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return bitmap;
+	}
+
+	private Bitmap getBitmap(String url, boolean isCut, int x, int y, float outerRadiusRat) {
+		File f = this.fileCache.getFile(url);
+
+		Bitmap b = null;
+		if ((f != null) && (f.exists())) {
+			b = decodeFile(f);
+		}
+		if (b != null) {
+			return b;
+		}
+		try {
+			URL imageUrl = new URL(url);
+			HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
+			conn.setConnectTimeout(30000);
+			conn.setReadTimeout(30000);
+			Bitmap bitmap1 = null;
+			conn.setInstanceFollowRedirects(true);
+			InputStream is = conn.getInputStream();
+			OutputStream os = new FileOutputStream(f);
+			InputStream isBm = null;
+			if (isCut) {
+				Bitmap bitmap = BitmapFactory.decodeStream(is);
+				bitmap1 = createFramedPhoto(x, y, bitmap, outerRadiusRat);
+				ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+				bitmap1.compress(Bitmap.CompressFormat.PNG, 100, baos);
+
+				isBm = new ByteArrayInputStream(baos.toByteArray());
+				CopyStream(isBm, os);
+			} else {
+				CopyStream(is, os);
+				bitmap1 = decodeFile(f);
+			}
+			os.close();
+			return bitmap1;
+		} catch (Exception ex) {
+			LogUtil.e("ImageLoder", "getBitmap catch Exception...\nmessage = " + ex.getMessage());
+		}
+		return null;
+	}
+
+	private Bitmap decodeFile(File f) {
+		try {
+			BitmapFactory.Options o = new BitmapFactory.Options();
+			o.inJustDecodeBounds = true;
+			BitmapFactory.decodeStream(new FileInputStream(f), null, o);
+
+			int REQUIRED_SIZE = 100;
+			int width_tmp = o.outWidth;
+			int height_tmp = o.outHeight;
+			int scale = 1;
+
+			while ((width_tmp / 2 >= 100) && (height_tmp / 2 >= 100)) {
+				width_tmp /= 2;
+				height_tmp /= 2;
+				scale *= 2;
+			}
+
+			BitmapFactory.Options o2 = new BitmapFactory.Options();
+			o2.inSampleSize = scale;
+			return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
+		} catch (FileNotFoundException localFileNotFoundException) {
+		}
+		return null;
+	}
+
+	boolean imageViewReused(PhotoToLoad photoToLoad) {
+		String tag = (String) this.imageViews.get(photoToLoad.imageView);
+
+		return (tag == null) || (!tag.equals(photoToLoad.url));
+	}
+
+	public void clearCache() {
+		this.memoryCache.clear();
+		this.fileCache.clear();
+	}
+
+	public static void CopyStream(InputStream is, OutputStream os) {
+		int buffer_size = 1024;
+		try {
+			byte[] bytes = new byte[1024];
+			while (true) {
+				int count = is.read(bytes, 0, 1024);
+				if (count == -1)
+					break;
+				os.write(bytes, 0, count);
+			}
+		} catch (Exception ex) {
+			LogUtil.e("ImageLoder", "CopyStream catch Exception...");
+		}
+	}
+
+	class BitmapDisplayer implements Runnable {
+		Bitmap bitmap;
+		ImageLoader.PhotoToLoad photoToLoad;
+
+		public BitmapDisplayer(Bitmap b, ImageLoader.PhotoToLoad p) {
+			this.bitmap = b;
+			this.photoToLoad = p;
+		}
+
+		public void run() {
+			if (ImageLoader.this.imageViewReused(this.photoToLoad))
+				return;
+			if (this.bitmap != null) {
+				this.photoToLoad.imageView.setBackgroundDrawable(new BitmapDrawable(this.bitmap));
+			}
+		}
+	}
+
+	private class PhotoToLoad {
+		public String url;
+		public ImageView imageView;
+		public boolean isCut;
+		public int X;
+		public int Y;
+		public float R;
+
+		public PhotoToLoad(String u, ImageView i, boolean isC, int x, int y, float r) {
+			this.url = u;
+			this.imageView = i;
+			this.isCut = isC;
+			this.X = x;
+			this.Y = y;
+			this.R = r;
+		}
+	}
+
+	class PhotosLoader implements Runnable {
+		ImageLoader.PhotoToLoad photoToLoad;
+
+		PhotosLoader(ImageLoader.PhotoToLoad photoToLoad) {
+			this.photoToLoad = photoToLoad;
+		}
+
+		public void run() {
+			if (ImageLoader.this.imageViewReused(this.photoToLoad))
+				return;
+			Bitmap bmp = ImageLoader.this.getBitmap(this.photoToLoad.url, this.photoToLoad.isCut, this.photoToLoad.X,
+					this.photoToLoad.Y, this.photoToLoad.R);
+			ImageLoader.this.memoryCache.put(this.photoToLoad.url, bmp);
+			if (ImageLoader.this.imageViewReused(this.photoToLoad))
+				return;
+			ImageLoader.BitmapDisplayer bd = new ImageLoader.BitmapDisplayer(bmp, this.photoToLoad);
+//			ImageLoader.BitmapDisplayer bd = new ImageLoader.BitmapDisplayer(ImageLoader.this, bmp, this.photoToLoad);
+
+			Activity a = (Activity) this.photoToLoad.imageView.getContext();
+			a.runOnUiThread(bd);
+		}
+	}
+}

+ 840 - 0
app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/MBitmapService.java

@@ -0,0 +1,840 @@
+package cn.net.communal.cpzshandset.common.bitmap;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.widget.ImageView;
+import cn.net.communal.cpzshandset.common.bitmap.core.BitmapCache;
+import cn.net.communal.cpzshandset.common.bitmap.core.BitmapDisplayConfig;
+import cn.net.communal.cpzshandset.common.bitmap.core.BitmapProcess;
+import cn.net.communal.cpzshandset.common.bitmap.display.Displayer;
+import cn.net.communal.cpzshandset.common.bitmap.display.SimpleDisplayer;
+import cn.net.communal.cpzshandset.common.bitmap.display.Utils;
+import cn.net.communal.cpzshandset.common.bitmap.download.Downloader;
+import cn.net.communal.cpzshandset.common.bitmap.download.SimpleDownloader;
+import cn.net.communal.cpzshandset.common.config.TConfig;
+import cn.net.communal.cpzshandset.common.util.LogUtil;
+
+public class MBitmapService {
+	private AWonderBitmapConfig mConfig;
+	private BitmapCache mImageCache;
+	private BitmapProcess mBitmapProcess;
+	private boolean mExitTasksEarly = false;
+	private boolean mPauseWork = false;
+	private final Object mPauseWorkLock = new Object();
+	private Context mContext;
+	private boolean mInit = false;
+	private ExecutorService bitmapLoadAndDisplayExecutor;
+	private static MBitmapService mBitmapService;
+	private HashMap<String, BitmapDisplayConfig> configMap = new HashMap();
+	private static AssetManager am;
+
+	private MBitmapService(Context context) {
+		this.mContext = context;
+		this.mConfig = new AWonderBitmapConfig(context);
+		configDiskCachePath(Utils.getDiskCacheDir(context, "afinalCache").getAbsolutePath());
+		configDisplayer(new SimpleDisplayer());
+		configDownlader(new SimpleDownloader());
+	}
+	
+	public static MBitmapService getInstance(Context context){
+		if (mBitmapService == null ) {
+			//$$$$$ 10-13
+			mBitmapService = new MBitmapService(context);
+		}
+		return mBitmapService;
+	}
+
+	public static synchronized MBitmapService create(MBitmapService mAWonderBitmap11,Context ctx) {
+		am = ctx.getResources().getAssets(); 
+		return mAWonderBitmap11;
+	}
+
+	public static MBitmapService create(MBitmapService mAWonderBitmap11,Context ctx, String diskCachePath) {
+		am = ctx.getResources().getAssets(); 
+		mAWonderBitmap11.configDiskCachePath(diskCachePath);
+		mAWonderBitmap11.init();
+		return mAWonderBitmap11;
+	}
+
+	public static MBitmapService create(MBitmapService mAWonderBitmap1,Context ctx, String diskCachePath, float memoryCacheSizePercent) {
+		am = ctx.getResources().getAssets(); 
+		mAWonderBitmap1.configDiskCachePath(diskCachePath);
+		mAWonderBitmap1.configMemoryCachePercent(memoryCacheSizePercent);
+		mAWonderBitmap1.init();
+
+		return mAWonderBitmap1;
+	}
+
+	public static MBitmapService create(MBitmapService mAWonderBitmap1,Context ctx, String diskCachePath, int memoryCacheSize) {
+		am = ctx.getResources().getAssets(); 
+		mAWonderBitmap1.configDiskCachePath(diskCachePath);
+		mAWonderBitmap1.configMemoryCacheSize(memoryCacheSize);
+		mAWonderBitmap1.init();
+		
+		return mAWonderBitmap1;
+	}
+
+	public static MBitmapService create(MBitmapService mAWonderBitmap1,Context ctx, String diskCachePath, float memoryCacheSizePercent,
+			int threadSize) {
+		am = ctx.getResources().getAssets(); 
+		mAWonderBitmap1.configDiskCachePath(diskCachePath);
+		mAWonderBitmap1.configBitmapLoadThreadSize(threadSize);
+		mAWonderBitmap1.configMemoryCachePercent(memoryCacheSizePercent);
+		mAWonderBitmap1.init();
+		
+		return mAWonderBitmap1;
+	}
+
+	public static MBitmapService create(MBitmapService mAWonderBitmap1,Context ctx, String diskCachePath, int memoryCacheSize, int threadSize) {
+		am = ctx.getResources().getAssets(); 
+		mAWonderBitmap1.configDiskCachePath(diskCachePath);
+		mAWonderBitmap1.configBitmapLoadThreadSize(threadSize);
+		mAWonderBitmap1.configMemoryCacheSize(memoryCacheSize);
+		mAWonderBitmap1.init();
+		return mAWonderBitmap1;
+	}
+
+	public static MBitmapService create(MBitmapService mAWonderBitmap1,Context ctx, String diskCachePath, float memoryCacheSizePercent,
+			int diskCacheSize, int threadSize) {
+		am = ctx.getResources().getAssets(); 
+		mAWonderBitmap1.configDiskCachePath(diskCachePath);
+		mAWonderBitmap1.configBitmapLoadThreadSize(threadSize);
+		mAWonderBitmap1.configMemoryCachePercent(memoryCacheSizePercent);
+		mAWonderBitmap1.configDiskCacheSize(diskCacheSize);
+		mAWonderBitmap1.init();
+
+		return mAWonderBitmap1;
+	}
+
+	public static MBitmapService create(MBitmapService mAWonderBitmap1,Context ctx, String diskCachePath, int memoryCacheSize, int diskCacheSize,
+			int threadSize) {
+		am = ctx.getResources().getAssets(); 
+		mAWonderBitmap1.configDiskCachePath(diskCachePath);
+		mAWonderBitmap1.configBitmapLoadThreadSize(threadSize);
+		mAWonderBitmap1.configMemoryCacheSize(memoryCacheSize);
+		mAWonderBitmap1.configDiskCacheSize(diskCacheSize);
+		mAWonderBitmap1.init();
+
+		return mAWonderBitmap1;
+	}
+	
+
+	public MBitmapService configLoadingImage(Bitmap bitmap) {
+		this.mConfig.defaultDisplayConfig.setLoadingBitmap(bitmap);
+		return this;
+	}
+
+	public MBitmapService configLoadingImage(int resId) {
+		this.mConfig.defaultDisplayConfig
+				.setLoadingBitmap(BitmapFactory.decodeResource(this.mContext.getResources(), resId));
+		return this;
+	}
+
+	public MBitmapService configLoadfailImage(Bitmap bitmap) {
+		this.mConfig.defaultDisplayConfig.setLoadfailBitmap(bitmap);
+		return this;
+	}
+
+	public MBitmapService configLoadfailImage(int resId) {
+		this.mConfig.defaultDisplayConfig
+				.setLoadfailBitmap(BitmapFactory.decodeResource(this.mContext.getResources(), resId));
+		return this;
+	}
+
+	public MBitmapService configBitmapMaxHeight(int bitmapHeight) {
+		this.mConfig.defaultDisplayConfig.setBitmapHeight(bitmapHeight);
+		return this;
+	}
+
+	public MBitmapService configBitmapMaxWidth(int bitmapWidth) {
+		this.mConfig.defaultDisplayConfig.setBitmapWidth(bitmapWidth);
+		return this;
+	}
+
+	public MBitmapService configDownlader(Downloader downlader) {
+		this.mConfig.downloader = downlader;
+		return this;
+	}
+
+	public MBitmapService configDisplayer(Displayer displayer) {
+		this.mConfig.displayer = displayer;
+		return this;
+	}
+
+	public MBitmapService configDiskCachePath(String strPath) {
+		if (!TextUtils.isEmpty(strPath)) {
+			this.mConfig.cachePath = strPath;
+		}
+		return this;
+	}
+
+	public MBitmapService configMemoryCacheSize(int size) {
+		this.mConfig.memCacheSize = size;
+		return this;
+	}
+
+	public MBitmapService configMemoryCachePercent(float percent) {
+		this.mConfig.memCacheSizePercent = percent;
+		return this;
+	}
+
+	public MBitmapService configDiskCacheSize(int size) {
+		this.mConfig.diskCacheSize = size;
+		return this;
+	}
+
+	public MBitmapService configBitmapLoadThreadSize(int size) {
+		if (size >= 1)
+			this.mConfig.poolSize = size;
+		return this;
+	}
+
+	public MBitmapService configRecycleImmediately(boolean recycleImmediately) {
+		this.mConfig.recycleImmediately = recycleImmediately;
+		return this;
+	}
+
+	private MBitmapService init() {
+		if (!this.mInit) {
+			BitmapCache.ImageCacheParams imageCacheParams = new BitmapCache.ImageCacheParams(this.mConfig.cachePath);
+			if ((this.mConfig.memCacheSizePercent > 0.05D) && (this.mConfig.memCacheSizePercent < 0.8D)) {
+				imageCacheParams.setMemCacheSizePercent(this.mContext, this.mConfig.memCacheSizePercent);
+			} else if (this.mConfig.memCacheSize > 2097152) {
+				imageCacheParams.setMemCacheSize(this.mConfig.memCacheSize);
+			} else {
+				imageCacheParams.setMemCacheSizePercent(this.mContext, 0.3F);
+			}
+
+			if (this.mConfig.diskCacheSize > 5242880) {
+				imageCacheParams.setDiskCacheSize(this.mConfig.diskCacheSize);
+			}
+			imageCacheParams.setRecycleImmediately(this.mConfig.recycleImmediately);
+
+			this.mImageCache = new BitmapCache(imageCacheParams);
+
+			this.bitmapLoadAndDisplayExecutor = Executors.newFixedThreadPool(this.mConfig.poolSize,
+					new ThreadFactory() {
+						public Thread newThread(Runnable r) {
+							Thread t = new Thread(r);
+
+							t.setPriority(4);
+							return t;
+						}
+					});
+			this.mBitmapProcess = new BitmapProcess(this.mConfig.downloader, this.mImageCache);
+
+			this.mInit = true;
+		}
+
+		return this;
+	}
+
+	public void display(View imageView, String url) {
+		doDisplay(imageView, url, null, false);
+	}
+	
+public Bitmap justDownloadImage( String url) {
+		
+		if (!this.mInit) {
+			init();
+		}
+
+		if ((TextUtils.isEmpty(url))) {
+			return null;
+		}
+
+		Bitmap bitmap = null;
+
+		if (this.mImageCache != null) {
+			bitmap = this.mImageCache.getBitmapFromMemoryCache(url);
+		}
+
+		if (bitmap != null) {
+			//本地已经存在的图片
+			LogUtil.e(TConfig.Echo, "本地已存在的图片:" + url);
+		} else{
+			//本地不存在,去服务器下载图片到本地
+//			SimpleDownloader downloader = new SimpleDownloader();
+//			downloader.download(url);
+			//
+			bitmap = MBitmapService.this.processBitmap(url, this.mConfig.defaultDisplayConfig);
+			LogUtil.i(TConfig.Echo, "bitmap:"+bitmap + "  从SD卡中获取图片:" + url);
+		}
+		return bitmap;
+	}
+//	public void displayCirImage(View imageView, String url) {
+//		doDisplay(imageView, url, null,true);
+//	}
+	public void displayCirImage(final  View imageView, final String url, Bitmap loadingBitmap, Bitmap loadfailBitmap) {
+		BitmapDisplayConfig displayConfig = (BitmapDisplayConfig) this.configMap
+				.get(String.valueOf(loadingBitmap) + "_" + String.valueOf(loadfailBitmap));
+		if (displayConfig == null) {
+			displayConfig = getDisplayConfig();
+			displayConfig.setLoadingBitmap(loadingBitmap);
+			displayConfig.setLoadfailBitmap(loadfailBitmap);
+			this.configMap.put(String.valueOf(loadingBitmap) + "_" + String.valueOf(loadfailBitmap), displayConfig);
+		}
+		doDisplay(imageView, url, displayConfig,true);
+	}
+	//加载Asset目录下的图片
+	public void displayLocalImage(View imageView, String url) {
+		if (!TextUtils.isEmpty(url)) {
+			loadImageSync(imageView, url);
+		}
+	}
+	
+	private void loadImageSync(View view, String background) {
+		WeakReference<View> imageViewReference = new WeakReference<View>(view);
+		View imageView = imageViewReference.get();
+			Bitmap aBitmap = loadImageBitmap(background);
+			if (aBitmap != null) {
+				imageView.setBackgroundDrawable(new BitmapDrawable(aBitmap));
+			}
+	}
+	
+	public Bitmap loadImageBitmap(String background) {
+		// TODO Auto-generated method stub
+		try {
+			background = background.substring(9, background.length());
+			InputStream is = am.open(background); 
+
+			BitmapFactory.Options o = new BitmapFactory.Options();
+			o.inJustDecodeBounds = true;
+			BitmapFactory.decodeStream(is, null, o);
+
+			int REQUIRED_SIZE = 100;
+			int width_tmp = o.outWidth;
+			int height_tmp = o.outHeight;
+			int scale = 1;
+
+			while ((width_tmp / 2 >= REQUIRED_SIZE) && (height_tmp / 2 >= REQUIRED_SIZE)) {
+				width_tmp /= 2;
+				height_tmp /= 2;
+				scale *= 2;
+			}
+
+			BitmapFactory.Options o2 = new BitmapFactory.Options();
+			o2.inSampleSize = scale;
+			InputStream is2 = am.open(background); 
+			Bitmap bitmap2 = BitmapFactory.decodeStream(is2, null, o2);
+			
+			return bitmap2;
+		} catch (IOException e) {
+			// TODO: handle exception
+			return null;
+		}
+	}
+
+	public void display(View imageView, String url, int imageWidth, int imageHeight) {
+		BitmapDisplayConfig displayConfig = (BitmapDisplayConfig) this.configMap.get(imageWidth + "_" + imageHeight);
+		if (displayConfig == null) {
+			displayConfig = getDisplayConfig();
+			displayConfig.setBitmapHeight(imageHeight);
+			displayConfig.setBitmapWidth(imageWidth);
+			this.configMap.put(imageWidth + "_" + imageHeight, displayConfig);
+		}
+
+		doDisplay(imageView, url, displayConfig,false);
+	}
+
+	public void display(View imageView, String url, Bitmap loadingBitmap) {
+		BitmapDisplayConfig displayConfig = (BitmapDisplayConfig) this.configMap.get(String.valueOf(loadingBitmap));
+		if (displayConfig == null) {
+			displayConfig = getDisplayConfig();
+			displayConfig.setLoadingBitmap(loadingBitmap);
+			this.configMap.put(String.valueOf(loadingBitmap), displayConfig);
+		}
+
+		doDisplay(imageView, url, displayConfig,false);
+	}
+
+	public void display(View imageView, String url, Bitmap loadingBitmap, Bitmap loadfailBitmap) {
+		BitmapDisplayConfig displayConfig = (BitmapDisplayConfig) this.configMap
+				.get(String.valueOf(loadingBitmap) + "_" + String.valueOf(loadfailBitmap));
+		if (displayConfig == null) {
+			displayConfig = getDisplayConfig();
+			displayConfig.setLoadingBitmap(loadingBitmap);
+			displayConfig.setLoadfailBitmap(loadfailBitmap);
+			this.configMap.put(String.valueOf(loadingBitmap) + "_" + String.valueOf(loadfailBitmap), displayConfig);
+		}
+
+		doDisplay(imageView, url, displayConfig,false);
+	}
+	public void displayNotCompress(View imageView, String url, Bitmap loadingBitmap, Bitmap loadfailBitmap) {
+		BitmapDisplayConfig displayConfig = (BitmapDisplayConfig) this.configMap
+				.get(String.valueOf(loadingBitmap) + "_" + String.valueOf(loadfailBitmap));
+//		LogUtil.d(TConfig.ECHO_LOGIN_TAG, " displayConfig: "+displayConfig);
+		if (displayConfig == null) {
+			displayConfig = getDisplayConfig();
+			displayConfig.setLoadingBitmap(loadingBitmap);
+			displayConfig.setLoadfailBitmap(loadfailBitmap);
+			displayConfig.setBitmapWidth(0);
+			displayConfig.setBitmapHeight(0);
+//			displayConfig
+//			LogUtil.d(TConfig.ECHO_LOGIN_TAG, "ScreenHeight:"+displayConfig.getScreenHeight() +"  screenWidth:" + displayConfig.getScreenWidth());
+			this.configMap.put(String.valueOf(loadingBitmap) + "_" + String.valueOf(loadfailBitmap), displayConfig);
+		}
+
+		doDisplay(imageView, url, displayConfig,false);
+	}
+
+	public void display(View imageView, String url, int imageWidth, int imageHeight, Bitmap loadingBitmap,
+			Bitmap laodfailBitmap) {
+		BitmapDisplayConfig displayConfig = (BitmapDisplayConfig) this.configMap.get(imageWidth + "_" + imageHeight
+				+ "_" + String.valueOf(loadingBitmap) + "_" + String.valueOf(laodfailBitmap));
+		if (displayConfig == null) {
+			displayConfig = getDisplayConfig();
+			displayConfig.setBitmapHeight(imageHeight);
+			displayConfig.setBitmapWidth(imageWidth);
+			displayConfig.setLoadingBitmap(loadingBitmap);
+			displayConfig.setLoadfailBitmap(laodfailBitmap);
+			this.configMap.put(imageWidth + "_" + imageHeight + "_" + String.valueOf(loadingBitmap) + "_"
+					+ String.valueOf(laodfailBitmap), displayConfig);
+		}
+
+		doDisplay(imageView, url, displayConfig,false);
+	}
+
+	public void display(View imageView, String url, BitmapDisplayConfig config) {
+		doDisplay(imageView, url, config,false);
+	}
+
+	private void doDisplay(View imageView, String url, BitmapDisplayConfig displayConfig,boolean b) {
+		if (!this.mInit) {
+			init();
+		}
+
+		if ((TextUtils.isEmpty(url)) || (imageView == null)) {
+			return;
+		}
+
+		if (displayConfig == null) {
+			displayConfig = this.mConfig.defaultDisplayConfig;
+		}
+		Bitmap bitmap = null;
+
+		if (this.mImageCache != null) {
+			bitmap = this.mImageCache.getBitmapFromMemoryCache(url);
+		}
+
+		if (bitmap != null) {
+			if ((imageView instanceof ImageView))
+				((ImageView) imageView).setImageBitmap(bitmap);
+			else {
+				imageView.setBackgroundDrawable(new BitmapDrawable(bitmap));
+			}
+
+		} else if (checkImageTask(url, imageView)) {
+			BitmapLoadAndDisplayTask task = new BitmapLoadAndDisplayTask(imageView, displayConfig,b);
+
+			AsyncDrawable asyncDrawable = new AsyncDrawable(this.mContext.getResources(),
+					displayConfig.getLoadingBitmap(), task);
+
+			if ((imageView instanceof ImageView)) {
+				((ImageView) imageView).setImageDrawable(asyncDrawable);
+			} else {
+				imageView.setBackgroundDrawable(asyncDrawable);
+			}
+
+			task.executeOnExecutor(this.bitmapLoadAndDisplayExecutor, new Object[] { url });
+		}
+	}
+
+	private BitmapDisplayConfig getDisplayConfig() {
+		BitmapDisplayConfig config = new BitmapDisplayConfig();
+		config.setAnimation(this.mConfig.defaultDisplayConfig.getAnimation());
+		config.setAnimationType(this.mConfig.defaultDisplayConfig.getAnimationType());
+		config.setBitmapHeight(this.mConfig.defaultDisplayConfig.getBitmapHeight());
+		config.setBitmapWidth(this.mConfig.defaultDisplayConfig.getBitmapWidth());
+		config.setLoadfailBitmap(this.mConfig.defaultDisplayConfig.getLoadfailBitmap());
+		config.setLoadingBitmap(this.mConfig.defaultDisplayConfig.getLoadingBitmap());
+		return config;
+	}
+
+	private void clearCacheInternalInBackgroud() {
+		if (this.mImageCache != null)
+			this.mImageCache.clearCache();
+	}
+
+	private void clearDiskCacheInBackgroud() {
+//		MyLog.d(SplashScreen.testClear, "---clearDiskCacheInBackgroud----" + (this.mImageCache != null));
+		if (this.mImageCache != null)
+			this.mImageCache.clearDiskCache();
+	}
+
+	private void clearCacheInBackgroud(String key) {
+		if (this.mImageCache != null)
+			this.mImageCache.clearCache(key);
+	}
+
+	private void clearDiskCacheInBackgroud(String key) {
+		if (this.mImageCache != null)
+			this.mImageCache.clearDiskCache(key);
+	}
+
+	private void closeCacheInternalInBackgroud() {
+		if (this.mImageCache != null) {
+			this.mImageCache.close();
+			this.mImageCache = null;
+			mBitmapService = null;
+		}
+	}
+
+	private Bitmap processBitmap(String uri, BitmapDisplayConfig config) {
+		if (this.mBitmapProcess != null) {
+			return this.mBitmapProcess.getBitmap(uri, config);
+		}
+		return null;
+	}
+
+	public Bitmap getBitmapFromCache(String key) {
+		Bitmap bitmap = getBitmapFromMemoryCache(key);
+		if (bitmap == null) {
+			bitmap = getBitmapFromDiskCache(key);
+		}
+		return bitmap;
+	}
+
+	public Bitmap getBitmapFromMemoryCache(String key) {
+		return this.mImageCache.getBitmapFromMemoryCache(key);
+	}
+
+	public Bitmap getBitmapFromDiskCache(String key) {
+		return getBitmapFromDiskCache(key, null);
+	}
+
+	public Bitmap getBitmapFromDiskCache(String key, BitmapDisplayConfig config) {
+		return this.mBitmapProcess.getFromDisk(key, config);
+	}
+
+	public void setExitTasksEarly(boolean exitTasksEarly) {
+		this.mExitTasksEarly = exitTasksEarly;
+	}
+
+	public void onResume() {
+		setExitTasksEarly(false);
+	}
+
+	public void onPause() {
+		setExitTasksEarly(true);
+	}
+
+	public void onDestroy() {
+		closeCache();
+	}
+
+	public void clearCache() {
+		// new CacheExecutecTask(null).execute(new Object[] { Integer.valueOf(1)
+		// });
+		// --我修改的
+		new CacheExecutecTask().execute(new Object[] { CacheExecutecTask.MESSAGE_CLEAR });
+	}
+
+	public void clearCache(String key) {
+		// --我修改的
+		// new CacheExecutecTask().execute(new Object[] { Integer.valueOf(4),
+		// key });
+		new CacheExecutecTask().execute(new Object[] { CacheExecutecTask.MESSAGE_CLEAR_KEY, key });
+
+	}
+
+	public void clearMemoryCache() {
+//		MyLog.d(SplashScreen.testClear, "--clearMemoryCache----" + (this.mImageCache != null));
+		if (this.mImageCache != null)
+			this.mImageCache.clearMemoryCache();
+	}
+
+	public void clearMemoryCache(String key) {
+		if (this.mImageCache != null)
+			this.mImageCache.clearMemoryCache(key);
+	}
+
+	public void clearDiskCache() {
+		// --我修改的
+		// new CacheExecutecTask().execute(new Object[] { Integer.valueOf(3) });
+//		MyLog.d(SplashScreen.testClear, "--clearDiskCache---disk-" + (this.mImageCache != null));
+		new CacheExecutecTask().execute(new Object[] { CacheExecutecTask.MESSAGE_CLEAR_DISK });
+	}
+
+	public void clearDiskCache(String key) {
+		// --我修改的
+		// new CacheExecutecTask().execute(new Object[] { Integer.valueOf(5),
+		// key });
+		new CacheExecutecTask().execute(new Object[] { CacheExecutecTask.MESSAGE_CLEAR_KEY_IN_DISK, key });
+	}
+
+	public void closeCache() {
+		// --我修改的
+		// new CacheExecutecTask().execute(new Object[] { Integer.valueOf(2) });
+		new CacheExecutecTask().execute(new Object[] { CacheExecutecTask.MESSAGE_CLOSE });
+	}
+
+	public void exitTasksEarly(boolean exitTasksEarly) {
+		this.mExitTasksEarly = exitTasksEarly;
+		if (exitTasksEarly)
+			pauseWork(false);
+	}
+
+	public void pauseWork(boolean pauseWork) {
+		synchronized (this.mPauseWorkLock) {
+			this.mPauseWork = pauseWork;
+			if (!this.mPauseWork)
+				this.mPauseWorkLock.notifyAll();
+		}
+	}
+
+	private static BitmapLoadAndDisplayTask getBitmapTaskFromImageView(View imageView) {
+		if (imageView != null) {
+			Drawable drawable = null;
+			if ((imageView instanceof ImageView))
+				drawable = ((ImageView) imageView).getDrawable();
+			else {
+				drawable = imageView.getBackground();
+			}
+
+			if ((drawable instanceof AsyncDrawable)) {
+				AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+				return asyncDrawable.getBitmapWorkerTask();
+			}
+		}
+		return null;
+	}
+
+	public static boolean checkImageTask(Object data, View imageView) {
+		BitmapLoadAndDisplayTask bitmapWorkerTask = getBitmapTaskFromImageView(imageView);
+
+		if (bitmapWorkerTask != null) {
+			Object bitmapData = bitmapWorkerTask.data;
+			if ((bitmapData == null) || (!bitmapData.equals(data))) {
+				bitmapWorkerTask.cancel(true);
+			} else {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	private class AWonderBitmapConfig {
+		public String cachePath;
+		public Displayer displayer;
+		public Downloader downloader;
+		public BitmapDisplayConfig defaultDisplayConfig;
+		public float memCacheSizePercent;
+		public int memCacheSize;
+		public int diskCacheSize;
+		public int poolSize = 3;
+		public boolean recycleImmediately = true;
+
+		public AWonderBitmapConfig(Context context) {
+			this.defaultDisplayConfig = new BitmapDisplayConfig();
+
+			this.defaultDisplayConfig.setAnimation(null);
+			this.defaultDisplayConfig.setAnimationType(1);
+
+			DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
+			this.defaultDisplayConfig.setScreenWidth(displayMetrics.widthPixels);
+			this.defaultDisplayConfig.setScreenHeight(displayMetrics.heightPixels);
+
+			int defaultWidth = (int) Math.floor(displayMetrics.widthPixels / 2);
+			this.defaultDisplayConfig.setBitmapHeight(defaultWidth);
+			this.defaultDisplayConfig.setBitmapWidth(defaultWidth);
+		}
+	}
+
+	private static class AsyncDrawable extends BitmapDrawable {
+		private final WeakReference<MBitmapService.BitmapLoadAndDisplayTask> bitmapWorkerTaskReference;
+
+		public AsyncDrawable(Resources res, Bitmap bitmap, MBitmapService.BitmapLoadAndDisplayTask bitmapWorkerTask) {
+			super(bitmap);
+//			bitmap
+//			if (bitmap != null)
+			this.bitmapWorkerTaskReference = new WeakReference(bitmapWorkerTask);
+		}
+
+		public MBitmapService.BitmapLoadAndDisplayTask getBitmapWorkerTask() {
+			return (MBitmapService.BitmapLoadAndDisplayTask) this.bitmapWorkerTaskReference.get();
+		}
+	}
+
+	// 我修改的10-9 Object
+	private class BitmapLoadAndDisplayTask extends AsyncTask<Object, Void, Bitmap> {
+		private Object data;
+		private boolean flagBitmap = false;
+		private final WeakReference<View> imageViewReference;
+		private final BitmapDisplayConfig displayConfig;
+
+		public BitmapLoadAndDisplayTask(final  View imageView, BitmapDisplayConfig config,boolean flagBitmap) {
+			this.imageViewReference = new WeakReference(imageView);
+			this.displayConfig = config;
+
+			this.flagBitmap = flagBitmap;
+		}
+
+		protected void onPostExecute(Bitmap bitmap) {
+			if ((isCancelled()) || (MBitmapService.this.mExitTasksEarly)) {
+				bitmap = null;
+			}
+
+			View imageView = getAttachedImageView();
+			if (!flagBitmap) {
+				if ((bitmap != null) && (imageView != null)) {
+
+					MBitmapService.this.mConfig.displayer.loadCompletedisplay(imageView, bitmap, this.displayConfig);
+
+				} else if ((bitmap == null) && (imageView != null)) {
+					MBitmapService.this.mConfig.displayer.loadFailDisplay(imageView,
+						this.displayConfig.getLoadfailBitmap());
+			}
+		} else {
+			if ((imageView instanceof ImageView)){
+				if (bitmap != null){
+					((ImageView) imageView).setImageBitmap(bitmap);
+				} else if (this.displayConfig.getLoadfailBitmap() != null){
+					MBitmapService.this.mConfig.displayer.loadFailDisplay(imageView,
+							this.displayConfig.getLoadfailBitmap());
+				}
+			}
+		}
+
+	}
+
+	@SuppressLint({ "NewApi" })
+	protected void onCancelled(Bitmap bitmap) {
+		super.onCancelled(bitmap);
+		synchronized (MBitmapService.this.mPauseWorkLock) {
+			MBitmapService.this.mPauseWorkLock.notifyAll();
+		}
+	}
+
+	private View getAttachedImageView() {
+		View imageView = (View) this.imageViewReference.get();
+		// BitmapLoadAndDisplayTask bitmapWorkerTask =
+		// AWonderBitmap.access$11(imageView);
+		// --我修改的
+		BitmapLoadAndDisplayTask bitmapWorkerTask = MBitmapService.getBitmapTaskFromImageView(imageView);
+
+		if (this == bitmapWorkerTask) {
+			return imageView;
+		}
+
+		return null;
+	}
+
+	@Override
+	protected Bitmap doInBackground(Object... params) {
+		// TODO Auto-generated method stub
+
+		this.data = params[0];
+		String dataString = String.valueOf(this.data);
+		Bitmap bitmap = null;
+
+		// 我修改的10-8
+
+//			synchronized (MBitmapService.this.mPauseWorkLock) {
+//				// -------------------------------疑问-----------
+//				do {
+//					try {
+//						MBitmapService.this.mPauseWorkLock.wait();
+//
+//					} catch (InterruptedException localInterruptedException) {
+//						// sys注释
+//						System.out.println("----" + localInterruptedException.getLocalizedMessage());
+//					}
+//					if (!MBitmapService.this.mPauseWork)
+//						break;
+//				} while (!isCancelled());
+//				}
+
+		synchronized (MBitmapService.this.mPauseWorkLock)
+
+		{
+			while (mPauseWork && !isCancelled()) {
+				try {
+					MBitmapService.this.mPauseWorkLock.wait();
+
+				} catch (InterruptedException localInterruptedException) {
+				}
+			}
+		}
+
+		if ((bitmap == null) && (!isCancelled()) && (getAttachedImageView() != null) && (!MBitmapService.this.mExitTasksEarly)) {
+			bitmap = MBitmapService.this.processBitmap(dataString, this.displayConfig);
+			}
+
+			if (bitmap != null) {
+				MBitmapService.this.mImageCache.addToMemoryCache(dataString, bitmap);
+			}
+
+			return bitmap;
+
+		}
+	}
+
+	private class CacheExecutecTask extends AsyncTask<Object, Void, Void> {
+		public static final int MESSAGE_CLEAR = 1;
+		public static final int MESSAGE_CLOSE = 2;
+		public static final int MESSAGE_CLEAR_DISK = 3;
+		public static final int MESSAGE_CLEAR_KEY = 4;
+		public static final int MESSAGE_CLEAR_KEY_IN_DISK = 5;
+
+		private CacheExecutecTask() {
+			super();
+		}
+
+		@Override
+		protected Void doInBackground(Object... params) {
+			// TODO Auto-generated method stub
+			switch (((Integer) params[0]).intValue()) {
+			case 1:
+				// 清除所有的缓存信息
+//				LogUtil.e(TConfig.Echo, 1+"clearCacheInternalInBackgroud");
+				MBitmapService.this.clearCacheInternalInBackgroud();
+				break;
+			case 2:
+//				LogUtil.e(TConfig.Echo, 2+"closeCacheInternalInBackgroud");
+				MBitmapService.this.closeCacheInternalInBackgroud();
+				break;
+			case 3:
+				// 清除所有的SD卡的缓存信息
+//				LogUtil.e(TConfig.Echo, 3+"clearDiskCacheInBackgroud");
+				MBitmapService.this.clearDiskCacheInBackgroud();
+				break;
+			case 4:
+				// 根据图片的Key值,清除对应Key值的缓存信息
+//				LogUtil.e(TConfig.Echo, 4+"clearCacheInBackgroud");
+				MBitmapService.this.clearCacheInBackgroud(String.valueOf(params[1]));
+				break;
+			case 5:
+				// 根据图片的Key值,清除SD卡中对应Key值的缓存信息
+//				LogUtil.e(TConfig.Echo, 5+"clearDiskCacheInBackgroud");
+				MBitmapService.this.clearDiskCacheInBackgroud(String.valueOf(params[1]));
+			}
+
+			return null;
+		}
+
+		/*
+		 * protected Void doInBackground(Object[] params) {
+		 * 
+		 * }
+		 */
+	}
+}

+ 83 - 0
app/src/main/java/cn/net/communal/cpzshandset/common/bitmap/MemoryCache.java

@@ -0,0 +1,83 @@
+package cn.net.communal.cpzshandset.common.bitmap;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import android.graphics.Bitmap;
+
+public class MemoryCache
+{
+  private Map<String, Bitmap> cache = Collections.synchronizedMap(new LinkedHashMap(10, 1.5F, true));
+
+  private long size = 0L;
+
+  private long limit = 2097152L;
+
+  public MemoryCache()
+  {
+    if (Runtime.getRuntime().maxMemory() / 10L > this.limit)
+    {
+      setLimit(2097152L);
+    }
+    else
+    {
+      setLimit(Runtime.getRuntime().maxMemory() * 2L / 25L);
+    }
+  }
+
+  public void setLimit(long new_limit) {
+    this.limit = new_limit;
+  }
+
+  public Bitmap get(String id) {
+    try {
+      if (!this.cache.containsKey(id))
+        return null;
+      return (Bitmap)this.cache.get(id); } catch (NullPointerException ex) {
+    }
+    return null;
+  }
+
+  public void put(String id, Bitmap bitmap)
+  {
+    try {
+      if (!this.cache.containsKey(id))
+      {
+        checkSize();
+
+        this.cache.put(id, bitmap);
+        this.size += getSizeInBytes(bitmap);
+      }
+    } catch (Throwable th) {
+      th.printStackTrace();
+    }
+  }
+
+  private void checkSize()
+  {
+    if (this.size > this.limit * 0.65D)
+    {
+      Iterator iter = this.cache.entrySet().iterator();
+      while (iter.hasNext()) {
+        Map.Entry entry = (Map.Entry)iter.next();
+        this.size -= getSizeInBytes((Bitmap)entry.getValue());
+        iter.remove();
+        if (this.size <= this.limit * 0.65D)
+          break;
+      }
+    }
+  }
+
+  public void clear() {
+    this.cache.clear();
+  }
+
+  long getSizeInBytes(Bitmap bitmap)
+  {
+    if (bitmap == null)
+      return 0L;
+    return bitmap.getRowBytes() * bitmap.getHeight();
+  }
+}

Неке датотеке нису приказане због велике количине промена