Explorar o código

goods manage prj.

renevy %!s(int64=5) %!d(string=hai) anos
pai
achega
1ba35e326e
Modificáronse 96 ficheiros con 5294 adicións e 0 borrados
  1. 1 0
      DialogLibrary/.gitignore
  2. 29 0
      DialogLibrary/build.gradle
  3. 25 0
      DialogLibrary/proguard-rules.pro
  4. 10 0
      DialogLibrary/src/main/AndroidManifest.xml
  5. 683 0
      DialogLibrary/src/main/java/com/fingerth/supdialogutils/SYSDiaLogUtils.java
  6. 219 0
      DialogLibrary/src/main/java/com/fingerth/supdialogutils/progressbar/horizontal/HorizontalWithNumberProgressBar.java
  7. 119 0
      DialogLibrary/src/main/java/com/fingerth/supdialogutils/progressbar/round/RoundWidthNumberProgressBar.java
  8. 66 0
      DialogLibrary/src/main/java/com/fingerth/supdialogutils/utils/SupDialogStaticUtils.java
  9. BIN=BIN
      DialogLibrary/src/main/res/drawable-hdpi/dialog_error.png
  10. BIN=BIN
      DialogLibrary/src/main/res/drawable-hdpi/dialog_success.png
  11. BIN=BIN
      DialogLibrary/src/main/res/drawable-hdpi/dialog_tip.png
  12. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_error_red.xml
  13. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_error_red_dark.xml
  14. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_gray.xml
  15. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_gray_dark.xml
  16. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_green.xml
  17. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_green_dark.xml
  18. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_tip.xml
  19. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_tip_dark.xml
  20. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_white.xml
  21. 22 0
      DialogLibrary/src/main/res/drawable/drawable_round_white_dd.xml
  22. 6 0
      DialogLibrary/src/main/res/drawable/selector_error_red.xml
  23. 6 0
      DialogLibrary/src/main/res/drawable/selector_gray.xml
  24. 6 0
      DialogLibrary/src/main/res/drawable/selector_green.xml
  25. 6 0
      DialogLibrary/src/main/res/drawable/selector_tip_color.xml
  26. 69 0
      DialogLibrary/src/main/res/layout/dialog_alert_view.xml
  27. 109 0
      DialogLibrary/src/main/res/layout/dialog_confirm_alert_view.xml
  28. 69 0
      DialogLibrary/src/main/res/layout/dialog_horizontal_progressbar_view.xml
  29. 51 0
      DialogLibrary/src/main/res/layout/dialog_progress_view.xml
  30. 61 0
      DialogLibrary/src/main/res/layout/dialog_round_progressbar_view.xml
  31. 24 0
      DialogLibrary/src/main/res/values/attr_progressbar.xml
  32. 30 0
      DialogLibrary/src/main/res/values/colors.xml
  33. 3 0
      DialogLibrary/src/main/res/values/strings.xml
  34. 22 0
      DialogLibrary/src/main/res/values/styles.xml
  35. 3 0
      app/.gitignore
  36. 58 0
      app/build.gradle
  37. BIN=BIN
      app/libs/arm64-v8a/libserial.so
  38. BIN=BIN
      app/libs/armeabi-v7a/libserial.so
  39. BIN=BIN
      app/libs/serialibrary.jar
  40. BIN=BIN
      app/libs/serialport-1.0.1.aar
  41. 21 0
      app/proguard-rules.pro
  42. 1 0
      app/release/output.json
  43. 26 0
      app/src/androidTest/java/com/ifastore/goodsmanage/ExampleInstrumentedTest.java
  44. 21 0
      app/src/main/AndroidManifest.xml
  45. 538 0
      app/src/main/java/com/ifastore/goodsmanage/MainActivity.java
  46. 61 0
      app/src/main/java/com/ifastore/goodsmanage/SpAdapter.java
  47. 14 0
      app/src/main/java/com/ifastore/goodsmanage/common/Constants.java
  48. 58 0
      app/src/main/java/com/ifastore/goodsmanage/models/ObjectBean.java
  49. 539 0
      app/src/main/java/com/ifastore/goodsmanage/serialport/CommSerial.java
  50. 164 0
      app/src/main/java/com/ifastore/goodsmanage/serialport/CommTask.java
  51. 20 0
      app/src/main/java/com/ifastore/goodsmanage/serialport/protocol/Constant.java
  52. 11 0
      app/src/main/java/com/ifastore/goodsmanage/serialport/protocol/Frame.java
  53. 274 0
      app/src/main/java/com/ifastore/goodsmanage/serialport/protocol/Protocol.java
  54. 131 0
      app/src/main/java/com/ifastore/goodsmanage/utils/Logger.java
  55. 146 0
      app/src/main/java/com/ifastore/goodsmanage/utils/TypeConverter.java
  56. 14 0
      app/src/main/res/anim/alpha.xml
  57. 30 0
      app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  58. 13 0
      app/src/main/res/drawable/bg_account_shape.xml
  59. 5 0
      app/src/main/res/drawable/bg_btn_button.xml
  60. 8 0
      app/src/main/res/drawable/bg_btn_normal.xml
  61. 8 0
      app/src/main/res/drawable/bg_btn_press.xml
  62. 8 0
      app/src/main/res/drawable/bg_spin_goods.xml
  63. 8 0
      app/src/main/res/drawable/bg_spin_normal.xml
  64. 8 0
      app/src/main/res/drawable/bg_spin_press.xml
  65. 5 0
      app/src/main/res/drawable/bg_spinner.xml
  66. 170 0
      app/src/main/res/drawable/ic_launcher_background.xml
  67. 175 0
      app/src/main/res/layout-land/activity_main.xml
  68. 8 0
      app/src/main/res/layout-land/item_layout.xml
  69. 62 0
      app/src/main/res/layout-land/scrollviewtest.xml
  70. 168 0
      app/src/main/res/layout-port/activity_main.xml
  71. 169 0
      app/src/main/res/layout/activity_main.xml
  72. 9 0
      app/src/main/res/layout/item_layout.xml
  73. 9 0
      app/src/main/res/layout/log_item_layout.xml
  74. 5 0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  75. 5 0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  76. BIN=BIN
      app/src/main/res/mipmap-hdpi/ic_launcher.png
  77. BIN=BIN
      app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  78. BIN=BIN
      app/src/main/res/mipmap-mdpi/ic_launcher.png
  79. BIN=BIN
      app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  80. BIN=BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher.png
  81. BIN=BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  82. BIN=BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  83. BIN=BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  84. BIN=BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  85. BIN=BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  86. 107 0
      app/src/main/res/values/colors.xml
  87. 18 0
      app/src/main/res/values/strings.xml
  88. 32 0
      app/src/main/res/values/styles.xml
  89. 17 0
      app/src/test/java/com/ifastore/goodsmanage/ExampleUnitTest.java
  90. 30 0
      build.gradle
  91. 18 0
      gradle.properties
  92. BIN=BIN
      gradle/wrapper/gradle-wrapper.jar
  93. 6 0
      gradle/wrapper/gradle-wrapper.properties
  94. 172 0
      gradlew
  95. 84 0
      gradlew.bat
  96. 3 0
      settings.gradle

+ 1 - 0
DialogLibrary/.gitignore

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

+ 29 - 0
DialogLibrary/build.gradle

@@ -0,0 +1,29 @@
+apply plugin: 'com.android.library'
+
+apply plugin: 'com.github.dcendents.android-maven'
+group='com.github.fingerth'
+
+android {
+    compileSdkVersion 28
+
+    defaultConfig {
+        minSdkVersion 14
+        targetSdkVersion 28
+        versionCode 1
+        versionName "1.0"
+
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    implementation 'com.android.support:appcompat-v7:28.0.0'
+}

+ 25 - 0
DialogLibrary/proguard-rules.pro

@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\AndroidStudio\sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# 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

+ 10 - 0
DialogLibrary/src/main/AndroidManifest.xml

@@ -0,0 +1,10 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+
+    package="com.fingerth.supdialogutils">
+
+    <application android:allowBackup="true" android:label="@string/app_name"
+        android:supportsRtl="true">
+
+    </application>
+
+</manifest>

+ 683 - 0
DialogLibrary/src/main/java/com/fingerth/supdialogutils/SYSDiaLogUtils.java

@@ -0,0 +1,683 @@
+package com.fingerth.supdialogutils;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+
+
+import com.fingerth.supdialogutils.progressbar.horizontal.HorizontalWithNumberProgressBar;
+import com.fingerth.supdialogutils.utils.SupDialogStaticUtils;
+
+
+
+/**
+ * ======================================================
+ * Created by Administrator able_fingerth on 2016/10/28.
+ * <p/>
+ * 版权所有,违者必究!
+ * <详情描述/>
+ */
+public class SYSDiaLogUtils {
+
+
+    ////1.成功  2.提示   3.錯誤  確認
+    private static String loadingStr = "正在加載...";
+    private static String successStr = "成功";
+    private static String tipStr = "提示";
+    private static String errorStr = "錯誤";
+    private static String confirmStr = "確認";
+    private static String cancelStr = "取消";
+    private static ProgressDialog progressDialog;
+    private static AlertDialog progressAlertDialog;
+    private static HorizontalWithNumberProgressBar horizontalProgressBar;
+
+    //4 取消 確認 對話框
+    private static AlertDialog confirmDialog;
+
+    public enum SYSDiaLogType {
+        DefaultTpye,//默認的樣式,系統樣式
+        IosType,//ios風格的
+        HorizontalWithNumberProgressBar,  // 進度條
+        RoundWidthNumberProgressBar,     // 圓形進度條
+        ;
+    }
+
+    public enum SYSConfirmType {
+        Success,//成功 綠色
+        Tip,//提示  黃黃的
+        Warning //警告 紅色
+    }
+
+
+    /**
+     * 語言適配
+     */
+    public static void setLangStr(String loadingStr, String successStr, String tipStr, String errorStr, String confirmStr, String cancelStr) {
+        SYSDiaLogUtils.loadingStr = loadingStr;
+        SYSDiaLogUtils.successStr = successStr;
+        SYSDiaLogUtils.tipStr = tipStr;
+        SYSDiaLogUtils.errorStr = errorStr;
+        SYSDiaLogUtils.confirmStr = confirmStr;
+        SYSDiaLogUtils.cancelStr = cancelStr;
+    }
+
+    /**
+     * 1.加載對話框部分
+     */
+    private static ProgressDialog pDialog;
+    private static AlertDialog pAlertDialog;
+
+    /**
+     * @param context
+     * @param canceledOnTouchOutside 遮罩下面控件点击是否可以點擊
+     */
+    private static void showDefaultProgressDialog(Activity context, SYSDiaLogType type, String title, String msg,
+                                                  boolean canceledOnTouchOutside, boolean cancelable, DialogInterface.OnCancelListener listener) {
+        if (context == null || context.isFinishing()) {
+            return;
+        }
+        closeKeyboardHidden(context);
+        initDialog();
+
+        if (TextUtils.isEmpty(title)) {
+            title = "";
+        }
+        switch (type) {
+            case IosType:
+                AlertDialog.Builder progressBuilder = new AlertDialog.Builder(context, R.style.AlertDialog_Styles);
+                View dialogView = View.inflate(context, R.layout.dialog_progress_view, null);
+                LinearLayout dialog_progress_layout = (LinearLayout) dialogView.findViewById(R.id.dialog_progress_layout);
+                FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) dialog_progress_layout.getLayoutParams();
+                params.width = SupDialogStaticUtils.getScreenWidth(context) * 4 / 9;
+                params.height = SupDialogStaticUtils.getScreenWidth(context) * 4 / 9;
+                dialog_progress_layout.setLayoutParams(params);
+                TextView message_tv = (TextView) dialogView.findViewById(R.id.message_tv);
+                if (TextUtils.isEmpty(msg)) {
+                    message_tv.setVisibility(View.GONE);
+                } else {
+                    message_tv.setText(msg);
+                }
+                progressBuilder.setView(dialogView);
+                pAlertDialog = progressBuilder.create();
+                pAlertDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
+                pAlertDialog.setCancelable(cancelable);
+                if (listener != null && cancelable) {
+                    pAlertDialog.setOnCancelListener(listener);
+                }
+                pAlertDialog.show();
+                break;
+            case DefaultTpye:
+            default:
+                if (TextUtils.isEmpty(msg)) {
+                    msg = loadingStr;
+                }
+                pDialog = ProgressDialog.show(context, title, msg);
+                pDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
+                pDialog.setCancelable(cancelable);
+                if (listener != null && cancelable) {
+                    pDialog.setOnCancelListener(listener);
+                }
+                break;
+        }
+
+
+    }
+
+    public static void dismissProgress() {
+        initDialog();
+    }
+
+    public static void showSystemProgressDialog(Activity context, String title, String msg, boolean canceledOnTouchOutside, DialogInterface.OnCancelListener listener) {
+        showDefaultProgressDialog(context, SYSDiaLogType.DefaultTpye, title, msg, canceledOnTouchOutside, true, listener);
+    }
+
+    public static void showSystemProgressDialog(Activity context, String title, String msg, boolean canceledOnTouchOutside, boolean cancelable) {
+        showDefaultProgressDialog(context, SYSDiaLogType.DefaultTpye, title, msg, canceledOnTouchOutside, cancelable, null);
+    }
+
+    public static void showSystemProgressDialog(Activity context, String title, String msg) {
+        showDefaultProgressDialog(context, SYSDiaLogType.DefaultTpye, title, msg, false, true, null);
+    }
+
+    public static void showSystemProgressDialog(Activity context, String msg) {
+        showDefaultProgressDialog(context, SYSDiaLogType.DefaultTpye, "", msg, false, true, null);
+    }
+
+    public static void showSystemProgressDialog(Activity context) {
+        showDefaultProgressDialog(context, SYSDiaLogType.DefaultTpye, "", "", false, true, null);
+    }
+
+    public static void showProgressDialog(Activity context, SYSDiaLogType type, String msg, boolean canceledOnTouchOutside, DialogInterface.OnCancelListener listener) {
+        showDefaultProgressDialog(context, type, "", msg, canceledOnTouchOutside, true, listener);
+    }
+
+    public static void showProgressDialog(Activity context, SYSDiaLogType type, String msg, boolean canceledOnTouchOutside, boolean cancelable) {
+        showDefaultProgressDialog(context, type, "", msg, canceledOnTouchOutside, cancelable, null);
+    }
+
+    public static void showProgressDialog(Activity context, SYSDiaLogType type, String msg) {
+        showDefaultProgressDialog(context, type, "", msg, false, true, null);
+    }
+
+    public static void showProgressDialog(Activity context, SYSDiaLogType type) {
+        showDefaultProgressDialog(context, type, "", "", false, true, null);
+    }
+
+
+    /**
+     * 隐藏软键盘
+     **/
+    private static void closeKeyboardHidden(Activity context) {
+        View view = context.getWindow().peekDecorView();
+        if (view != null) {
+            InputMethodManager inputmanger = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+            inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
+        }
+    }
+
+    /**
+     * 新的對話框彈出之前,先把舊的清除掉
+     */
+    private static void initDialog() {
+        if (pDialog != null && pDialog.isShowing()) {
+            pDialog.dismiss();
+            pDialog = null;
+        }
+        if (tDialog != null && tDialog.isShowing()) {
+            tDialog.dismiss();
+            tDialog = null;
+        }
+        if (pAlertDialog != null && pAlertDialog.isShowing()) {
+            pAlertDialog.dismiss();
+            pAlertDialog = null;
+        }
+        if (progressDialog != null && progressDialog.isShowing()) {
+            progressDialog.dismiss();
+            progressDialog = null;
+        }
+        if (progressAlertDialog != null && progressAlertDialog.isShowing()) {
+            progressAlertDialog.dismiss();
+            progressAlertDialog = null;
+        }
+        if (confirmDialog != null && confirmDialog.isShowing()) {
+            confirmDialog.dismiss();
+            confirmDialog = null;
+        }
+    }
+
+    /**
+     * 2.提示對話框部分
+     */
+    private static AlertDialog tDialog;
+
+    private static void showAlertDialog(Activity context, String title, String msg, String confirmStr, int type, boolean canceledOnTouchOutside) {
+        if (context == null || context.isFinishing()) {
+            return;
+        }
+        closeKeyboardHidden(context);
+        initDialog();
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AlertDialog_Styles);
+        View dialogView = View.inflate(context, R.layout.dialog_alert_view, null);
+        LinearLayout dialog_view_layout = (LinearLayout) dialogView.findViewById(R.id.dialog_view_layout);
+        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) dialog_view_layout.getLayoutParams();
+        params.width = SupDialogStaticUtils.getScreenWidth(context) * 2 / 3;
+        dialog_view_layout.setLayoutParams(params);
+        ImageView dialog_icon = (ImageView) dialogView.findViewById(R.id.dialog_icon);
+
+        TextView confirm = (TextView) dialogView.findViewById(R.id.confirm);
+        if (TextUtils.isEmpty(confirmStr)) {
+            confirmStr = SYSDiaLogUtils.confirmStr;
+        }
+        confirm.setText(confirmStr);
+        confirm.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (tDialog != null && tDialog.isShowing()) {
+                    tDialog.dismiss();
+                }
+            }
+        });
+        //1.成功  2.提示   3.錯誤
+        switch (type) {
+            case 1:
+                if (TextUtils.isEmpty(title)) {
+                    title = SYSDiaLogUtils.successStr;
+                }
+                dialog_icon.setImageDrawable(context.getResources().getDrawable(R.drawable.dialog_success));
+                //selector_green
+                confirm.setBackgroundResource(R.drawable.selector_green);
+                //confirm.setBackground(context.getResources().getDrawable(R.drawable.selector_green));
+                break;
+            case 2:
+                if (TextUtils.isEmpty(title)) {
+                    title = SYSDiaLogUtils.tipStr;
+                }
+                dialog_icon.setImageDrawable(context.getResources().getDrawable(R.drawable.dialog_tip));
+                confirm.setBackgroundResource(R.drawable.selector_tip_color);
+                //confirm.setBackground(context.getResources().getDrawable(R.drawable.selector_tip_color));
+                break;
+            case 3:
+                if (TextUtils.isEmpty(title)) {
+                    title = SYSDiaLogUtils.errorStr;
+                }
+                dialog_icon.setImageDrawable(context.getResources().getDrawable(R.drawable.dialog_error));
+                confirm.setBackgroundResource(R.drawable.selector_error_red);
+                //confirm.setBackground(context.getResources().getDrawable(R.drawable.selector_error_red));
+                break;
+            default:
+                break;
+        }
+        TextView title_tv = (TextView) dialogView.findViewById(R.id.title_tv);
+        title_tv.setText(title);
+        TextView message_tv = (TextView) dialogView.findViewById(R.id.message_tv);
+        if (TextUtils.isEmpty(msg)) {
+            message_tv.setVisibility(View.GONE);
+        } else {
+            message_tv.setText(msg);
+        }
+
+
+        builder.setView(dialogView);
+        tDialog = builder.create();
+        tDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
+        tDialog.show();
+
+        //所需要的文件
+        //<style name="AlertDialog_Styles" parent="Theme.AppCompat.Light.Dialog" />
+    }
+
+    public static void showSuccessDialog(Activity context, String title, String msg, String confirmStr, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, title, msg, confirmStr, 1, canceledOnTouchOutside);
+    }
+
+    public static void showSuccessDialog(Activity context, String title, String confirmStr, boolean canceledOnTouchOutside) {
+        Log.d("TEST", " >>> showSuccessDialog");
+        showAlertDialog(context, title, "", confirmStr, 1, canceledOnTouchOutside);
+    }
+
+    public static void showSuccessDialog(Activity context, String confirmStr, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, "", "", confirmStr, 1, canceledOnTouchOutside);
+    }
+
+    public static void showSuccessDialog(Activity context, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, "", "", "", 1, canceledOnTouchOutside);
+    }
+
+    public static void showInfoDialog(Activity context, String title, String msg, String confirmStr, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, title, msg, confirmStr, 2, canceledOnTouchOutside);
+    }
+
+    public static void showInfoDialog(Activity context, String title, String confirmStr, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, title, "", confirmStr, 2, canceledOnTouchOutside);
+    }
+
+    public static void showInfoDialog(Activity context, String confirmStr, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, "", "", confirmStr, 2, canceledOnTouchOutside);
+    }
+
+    public static void showInfoDialog(Activity context, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, "", "", "", 2, canceledOnTouchOutside);
+    }
+
+    public static void showErrorDialog(Activity context, String title, String msg, String confirmStr, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, title, msg, confirmStr, 3, canceledOnTouchOutside);
+    }
+
+    public static void showErrorDialog(Activity context, String title, String confirmStr, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, title, "", confirmStr, 3, canceledOnTouchOutside);
+    }
+
+    public static void showErrorDialog(Activity context, String confirmStr, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, "", "", confirmStr, 3, canceledOnTouchOutside);
+    }
+
+    public static void showErrorDialog(Activity context, boolean canceledOnTouchOutside) {
+        showAlertDialog(context, "", "", "", 3, canceledOnTouchOutside);
+    }
+
+
+    /**
+     * 3.進度條部分
+     */
+    private static void showDefaultProgressBar(Activity context, SYSDiaLogType type, String title, String msg,
+                                               boolean canceledOnTouchOutside, boolean cancelable, DialogInterface.OnCancelListener listener) {
+        if (context == null || context.isFinishing()) {
+            return;
+        }
+        closeKeyboardHidden(context);
+        initDialog();
+
+        if (TextUtils.isEmpty(title)) {
+            title = "";
+        }
+        switch (type) {
+            case HorizontalWithNumberProgressBar:
+                AlertDialog.Builder progressBarBuilder = new AlertDialog.Builder(context, R.style.AlertDialog_Styles);
+                View dialogView = View.inflate(context, R.layout.dialog_horizontal_progressbar_view, null);
+                LinearLayout dialog_progress_layout = (LinearLayout) dialogView.findViewById(R.id.dialog_progress_layout);
+                FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) dialog_progress_layout.getLayoutParams();
+                params.width = SupDialogStaticUtils.getScreenWidth(context) * 9 / 10;
+                params.height = SupDialogStaticUtils.dp2px(context, 120);
+                dialog_progress_layout.setLayoutParams(params);
+                TextView message_tv = (TextView) dialogView.findViewById(R.id.message_tv);
+                TextView title_tv = (TextView) dialogView.findViewById(R.id.title_tv);
+                horizontalProgressBar = (HorizontalWithNumberProgressBar) dialogView.findViewById(R.id.horizontal_bar);
+                if (TextUtils.isEmpty(title)) {
+                    title_tv.setVisibility(View.GONE);
+                } else {
+                    title_tv.setText(title);
+                }
+                if (TextUtils.isEmpty(msg)) {
+                    message_tv.setVisibility(View.GONE);
+                } else {
+                    message_tv.setText(msg);
+                }
+                progressBarBuilder.setView(dialogView);
+                progressAlertDialog = progressBarBuilder.create();
+                progressAlertDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
+                progressAlertDialog.setCancelable(cancelable);
+                if (listener != null && cancelable) {
+                    progressAlertDialog.setOnCancelListener(listener);
+                }
+                progressAlertDialog.show();
+                break;
+            case RoundWidthNumberProgressBar:
+                AlertDialog.Builder roundProgressBarBuilder = new AlertDialog.Builder(context, R.style.AlertDialog_Styles);
+                View rounddialogView = View.inflate(context, R.layout.dialog_round_progressbar_view, null);
+                LinearLayout dialog_round_progress_layout = (LinearLayout) rounddialogView.findViewById(R.id.dialog_progress_layout);
+                FrameLayout.LayoutParams params1 = (FrameLayout.LayoutParams) dialog_round_progress_layout.getLayoutParams();
+                params1.width = SupDialogStaticUtils.dp2px(context, 140);
+                params1.height = SupDialogStaticUtils.dp2px(context, 140);
+                dialog_round_progress_layout.setLayoutParams(params1);
+                TextView messageTv = (TextView) rounddialogView.findViewById(R.id.message_tv);
+                horizontalProgressBar = (HorizontalWithNumberProgressBar) rounddialogView.findViewById(R.id.round_bar);
+
+                if (TextUtils.isEmpty(msg)) {
+                    if (TextUtils.isEmpty(title)) {
+                        messageTv.setVisibility(View.GONE);
+                    } else {
+                        messageTv.setText(title);
+                    }
+                } else {
+                    messageTv.setText(msg);
+                }
+                roundProgressBarBuilder.setView(rounddialogView);
+                progressAlertDialog = roundProgressBarBuilder.create();
+                progressAlertDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
+                progressAlertDialog.setCancelable(cancelable);
+                if (listener != null && cancelable) {
+                    progressAlertDialog.setOnCancelListener(listener);
+                }
+                progressAlertDialog.show();
+                break;
+            case DefaultTpye:
+            default:
+                if (TextUtils.isEmpty(msg)) {
+                    msg = loadingStr;
+                }
+                progressDialog = new ProgressDialog(context);
+                progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  //设置样式
+                progressDialog.setTitle(title); //设置Title
+                progressDialog.setMessage(msg);
+                progressDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
+                progressDialog.setCancelable(cancelable);
+                if (listener != null && cancelable) {
+                    progressDialog.setOnCancelListener(listener);
+                }
+                progressDialog.show();
+                break;
+        }
+
+    }
+
+    public static void showProgressBar(Activity context, String title, String msg, boolean canceledOnTouchOutside, DialogInterface.OnCancelListener listener) {
+        showDefaultProgressBar(context, SYSDiaLogType.DefaultTpye, title, msg, canceledOnTouchOutside, true, listener);
+    }
+
+    public static void showProgressBar(Activity context, String title, String msg, boolean canceledOnTouchOutside, boolean cancelable) {
+        showDefaultProgressBar(context, SYSDiaLogType.DefaultTpye, title, msg, canceledOnTouchOutside, cancelable, null);
+    }
+
+    public static void showProgressBar(Activity context, String title, String msg) {
+        showDefaultProgressBar(context, SYSDiaLogType.DefaultTpye, title, msg, false, false, null);
+    }
+
+    public static void showProgressBar(Activity context, String msg) {
+        showDefaultProgressBar(context, SYSDiaLogType.DefaultTpye, "", msg, false, false, null);
+    }
+
+    public static void showProgressBar(Activity context) {
+        showDefaultProgressBar(context, SYSDiaLogType.DefaultTpye, "", "", false, false, null);
+    }
+
+    public static void setProgressBar(int progress) {
+        if (progressDialog != null && progressDialog.isShowing()) {
+            progressDialog.setProgress(progress);
+        }
+        //horizontalProgressBar
+        if (progressAlertDialog != null && progressAlertDialog.isShowing() && horizontalProgressBar != null) {
+            horizontalProgressBar.setProgress(progress);
+        }
+    }
+
+    public static int getProgressBar() {
+        if (progressDialog != null && progressDialog.isShowing()) {
+            return progressDialog.getProgress();
+        }
+        //horizontalProgressBar
+        if (progressAlertDialog != null && progressAlertDialog.isShowing() && horizontalProgressBar != null) {
+            return horizontalProgressBar.getProgress();
+        }
+        return 0;
+    }
+
+    public static void showProgressBar(Activity context, SYSDiaLogType type, String title, String msg, boolean canceledOnTouchOutside, DialogInterface.OnCancelListener listener) {
+        showDefaultProgressBar(context, type, title, msg, canceledOnTouchOutside, true, listener);
+    }
+
+    public static void showProgressBar(Activity context, SYSDiaLogType type, String title, String msg, boolean canceledOnTouchOutside, boolean cancelable) {
+        showDefaultProgressBar(context, type, title, msg, canceledOnTouchOutside, cancelable, null);
+    }
+
+    public static void showProgressBar(Activity context, SYSDiaLogType type, String title, String msg) {
+        showDefaultProgressBar(context, type, title, msg, false, false, null);
+    }
+
+    public static void showProgressBar(Activity context, SYSDiaLogType type, String msg) {
+        showDefaultProgressBar(context, type, "", msg, false, false, null);
+    }
+
+    public static void showProgressBar(Activity context, SYSDiaLogType type) {
+        showDefaultProgressBar(context, type, "", "", false, false, null);
+    }
+
+    /**
+     * 4.確認 取消  對話框部分
+     * public enum SYSConfirmType {
+     * Success,//成功 綠色
+     * Tip,//提示  黃黃的
+     * Warning //警告 紅色
+     * }
+     */
+
+    private static void showConfirmAlertDialog(Activity context, boolean isShowPic, SYSConfirmType picType,
+                                               String title, String msg, String confirmStr, String cancelStr,
+                                               boolean canceledOnTouchOutside, boolean cancelable,
+                                               final ConfirmDialogListener confirmDialogListener) {
+        if (context == null || context.isFinishing()) {
+            return;
+        }
+        Log.d("TEST", "showConfirmAlertDialog");
+        closeKeyboardHidden(context);
+        initDialog();
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AlertDialog_Styles);
+        View dialogView = View.inflate(context, R.layout.dialog_confirm_alert_view, null);
+        LinearLayout dialog_view_layout = (LinearLayout) dialogView.findViewById(R.id.dialog_view_layout);
+        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) dialog_view_layout.getLayoutParams();
+        params.width = SupDialogStaticUtils.getScreenWidth(context) * 2 / 3;
+        dialog_view_layout.setLayoutParams(params);
+        ImageView dialog_icon = (ImageView) dialogView.findViewById(R.id.dialog_icon);
+
+        TextView confirm = (TextView) dialogView.findViewById(R.id.confirm);
+        TextView cancel = (TextView) dialogView.findViewById(R.id.cancel);
+        if (TextUtils.isEmpty(confirmStr)) {
+            confirmStr = SYSDiaLogUtils.confirmStr;
+        }
+        if (TextUtils.isEmpty(cancelStr)) {
+            cancelStr = SYSDiaLogUtils.cancelStr;
+        }
+        confirm.setText(confirmStr);
+        cancel.setText(cancelStr);
+        confirm.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Log.d("TEST", ">>> onClick");
+                if (confirmDialogListener != null) {
+                    confirmDialogListener.onClickButton(false, true);
+                }
+                if (confirmDialog != null && confirmDialog.isShowing()) {
+                    confirmDialog.dismiss();
+                }
+            }
+        });
+        cancel.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (confirmDialogListener != null) {
+                    confirmDialogListener.onClickButton(true, false);
+                }
+                if (confirmDialog != null && confirmDialog.isShowing()) {
+                    confirmDialog.dismiss();
+                }
+            }
+        });
+        if (!isShowPic) {
+            dialog_icon.setVisibility(View.GONE);
+        } else {
+            //1.成功  2.提示   3.錯誤
+            switch (picType) {
+                case Success:
+                    if (TextUtils.isEmpty(title) && TextUtils.isEmpty(msg)) {
+                        title = SYSDiaLogUtils.successStr;
+                    }
+                    dialog_icon.setImageDrawable(context.getResources().getDrawable(R.drawable.dialog_success));
+                    //selector_green
+                    confirm.setBackgroundResource(R.drawable.selector_green);
+                    //confirm.setBackground(context.getResources().getDrawable(R.drawable.selector_green));
+                    break;
+                case Tip:
+                    if (TextUtils.isEmpty(title) && TextUtils.isEmpty(msg)) {
+                        title = SYSDiaLogUtils.tipStr;
+                    }
+                    dialog_icon.setImageDrawable(context.getResources().getDrawable(R.drawable.dialog_tip));
+                    confirm.setBackgroundResource(R.drawable.selector_tip_color);
+                    //confirm.setBackground(context.getResources().getDrawable(R.drawable.selector_tip_color));
+                    break;
+                case Warning:
+                    if (TextUtils.isEmpty(title) && TextUtils.isEmpty(msg)) {
+                        title = SYSDiaLogUtils.errorStr;
+                    }
+                    dialog_icon.setImageDrawable(context.getResources().getDrawable(R.drawable.dialog_error));
+                    confirm.setBackgroundResource(R.drawable.selector_error_red);
+                    //confirm.setBackground(context.getResources().getDrawable(R.drawable.selector_error_red));
+                    break;
+                default:
+                    dialog_icon.setVisibility(View.GONE);
+                    break;
+            }
+        }
+        TextView title_tv = (TextView) dialogView.findViewById(R.id.title_tv);
+        if (TextUtils.isEmpty(title)) {
+            title_tv.setVisibility(View.GONE);
+        } else {
+            title_tv.setText(title);
+        }
+
+        TextView message_tv = (TextView) dialogView.findViewById(R.id.message_tv);
+        if (TextUtils.isEmpty(msg)) {
+            message_tv.setVisibility(View.GONE);
+        } else {
+            message_tv.setText(msg);
+        }
+
+        builder.setView(dialogView);
+        confirmDialog = builder.create();
+        confirmDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
+        confirmDialog.setCancelable(cancelable);
+        confirmDialog.show();
+
+        //所需要的文件
+        //<style name="AlertDialog_Styles" parent="Theme.AppCompat.Light.Dialog" />
+    }
+
+    public static void showConfirmDialog(Activity context, boolean isShowPic, SYSConfirmType picType,
+                                         String title, String msg, String confirmStr, String cancelStr,
+                                         boolean canceledOnTouchOutside, boolean cancelable,
+                                         final ConfirmDialogListener confirmDialogListener) {
+        showConfirmAlertDialog(context, isShowPic, picType, title, msg, confirmStr, cancelStr, canceledOnTouchOutside, cancelable, confirmDialogListener);
+    }
+
+    public static void showConfirmDialog(Activity context, boolean isShowPic, SYSConfirmType picType,
+                                         String title, String msg,
+                                         final ConfirmDialogListener confirmDialogListener) {
+        showConfirmAlertDialog(context, isShowPic, picType, title, msg, "", "", false, true, confirmDialogListener);
+    }
+
+    public static void showConfirmDialog(Activity context, String title, String msg, String confirmStr, String cancelStr,
+                                         boolean canceledOnTouchOutside, boolean cancelable,
+                                         final ConfirmDialogListener confirmDialogListener) {
+        showConfirmAlertDialog(context, false, SYSConfirmType.Success, title, msg, confirmStr, cancelStr, canceledOnTouchOutside, cancelable, confirmDialogListener);
+    }
+
+    public static void showConfirmDialog(Activity context, String title, String msg, String confirmStr, String cancelStr, ConfirmDialogListener confirmDialogListener) {
+        showConfirmAlertDialog(context, false, SYSConfirmType.Success, title, msg, confirmStr, cancelStr, false, true, confirmDialogListener);
+    }
+
+    public static void showConfirmDialog(Activity context, String title, String msg, ConfirmDialogListener confirmDialogListener) {
+        showConfirmAlertDialog(context, false, SYSConfirmType.Success, title, msg, "", "", false, true, confirmDialogListener);
+    }
+
+    public static void showConfirmDialog(Activity context, String msg, ConfirmDialogListener confirmDialogListener) {
+        showConfirmAlertDialog(context, false, SYSConfirmType.Success, "", msg, "", "", false, true, confirmDialogListener);
+    }
+
+
+    public interface ConfirmDialogListener {
+        void onClickButton(boolean clickLeft, boolean clickRight);
+    }
+
+//    private static void showCustomizeLoadingProgressDialog(Context context, boolean canceledOnTouchOutside) {
+//        ProgressDialog mCustomizeLoadingProgressDialog = new ProgressDialog(context, ProgressDialog.THEME_HOLO_LIGHT);
+//        mCustomizeLoadingProgressDialog.setMessage(AppConstants.appStrMap.get(AppConstants.loading));
+//        mCustomizeLoadingProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
+//        mCustomizeLoadingProgressDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
+//        mCustomizeLoadingProgressDialog.setCancelable(true);
+//        mCustomizeLoadingProgressDialog.show();
+//        Point size = new Point();
+//        mCustomizeLoadingProgressDialog.getWindow().getWindowManager().getDefaultDisplay().getSize(size);
+//        //记得用mProgressDialog来得到这个界面的大小,实际上不加就是得到当前监听器匿名类对象的界面宽度</span>
+//
+//        int width = size.x;//获取界面的宽度像素
+//        int height = size.y;
+//        WindowManager.LayoutParams params = mCustomizeLoadingProgressDialog.getWindow().getAttributes(); //一定要用mProgressDialog得到当前界面的参数对象,否则就不是设置ProgressDialog的界面了
+//        params.alpha = 1.0f;//设置进度条背景透明度
+//        params.height = height / 9;//设置进度条的高度
+//        params.gravity = Gravity.BOTTOM;//设置ProgressDialog的重心
+//        params.width = 2 * width / 3;//设置进度条的宽度
+//        params.dimAmount = 0f;//设置半透明背景的灰度,范围0~1,系统默认值是0.5,1表示背景完全是黑色的,0表示背景不变暗,和原来的灰度一样
+//        mCustomizeLoadingProgressDialog.getWindow().setAttributes(params);//把参数设置给进度条,注意,一定要先show出来才可以再设置,不然就没效果了,因为只有当界面显示出来后才可以获得它的屏幕尺寸及参数等一些信息
+//    }
+}

+ 219 - 0
DialogLibrary/src/main/java/com/fingerth/supdialogutils/progressbar/horizontal/HorizontalWithNumberProgressBar.java

@@ -0,0 +1,219 @@
+package com.fingerth.supdialogutils.progressbar.horizontal;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.widget.ProgressBar;
+
+import com.fingerth.supdialogutils.R;
+import com.fingerth.supdialogutils.utils.SupDialogStaticUtils;
+
+/**
+ * ======================================================
+ * Created by Administrator able_fingerth on 2017/7/13.
+ * <p/>
+ * 版权所有,违者必究!
+ * <详情描述/>
+ * 參考路徑:
+ * http://blog.csdn.net/lmj623565791/article/details/43371299
+ */
+public class HorizontalWithNumberProgressBar extends ProgressBar {
+
+    private static final int DEFAULT_TEXT_SIZE = 10;
+    private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1;
+    private static final int DEFAULT_COLOR_UNREACHED_COLOR = 0xFFd3d6da;
+    private static final int DEFAULT_HEIGHT_REACHED_PROGRESS_BAR = 2;
+    private static final int DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR = 2;
+    private static final int DEFAULT_SIZE_TEXT_OFFSET = 10;
+
+    /**
+     * painter of all drawing things
+     */
+    protected Paint mPaint = new Paint();
+    /**
+     * color of progress number
+     */
+    protected int mTextColor = DEFAULT_TEXT_COLOR;
+    /**
+     * size of text (sp)
+     */
+    protected int mTextSize = SupDialogStaticUtils.sp2px(getContext(), DEFAULT_TEXT_SIZE);
+
+    /**
+     * offset of draw progress
+     */
+    protected int mTextOffset = SupDialogStaticUtils.dp2px(getContext(), DEFAULT_SIZE_TEXT_OFFSET);
+
+    /**
+     * height of reached progress bar
+     */
+    protected int mReachedProgressBarHeight = SupDialogStaticUtils.dp2px(getContext(), DEFAULT_HEIGHT_REACHED_PROGRESS_BAR);
+
+    /**
+     * color of reached bar
+     */
+    protected int mReachedBarColor = DEFAULT_TEXT_COLOR;
+    /**
+     * color of unreached bar
+     */
+    protected int mUnReachedBarColor = DEFAULT_COLOR_UNREACHED_COLOR;
+    /**
+     * height of unreached progress bar
+     */
+    protected int mUnReachedProgressBarHeight = SupDialogStaticUtils.dp2px(getContext(), DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR);
+    /**
+     * view width except padding
+     */
+    protected int mRealWidth;
+
+    protected boolean mIfDrawText = true;
+
+    protected static final int VISIBLE = 0;
+
+    public HorizontalWithNumberProgressBar(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public HorizontalWithNumberProgressBar(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        setHorizontalScrollBarEnabled(true);
+
+        obtainStyledAttributes(attrs);
+
+        mPaint.setTextSize(mTextSize);
+        mPaint.setColor(mTextColor);
+
+    }
+
+    /**
+     * get the styled attributes
+     *
+     * @param attrs
+     */
+    private void obtainStyledAttributes(AttributeSet attrs) {
+        // init values from custom attributes
+        final TypedArray attributes = getContext().obtainStyledAttributes(
+                attrs, R.styleable.HorizontalWithNumberProgressBar);
+
+        mTextColor = attributes
+                .getColor(R.styleable.HorizontalWithNumberProgressBar_progressbar_text_color,
+                        DEFAULT_TEXT_COLOR);
+        mTextSize = (int) attributes.getDimension(
+                R.styleable.HorizontalWithNumberProgressBar_progressbar_text_size,
+                mTextSize);
+
+        mReachedBarColor = attributes
+                .getColor(
+                        R.styleable.HorizontalWithNumberProgressBar_progressbar_reached_color,
+                        mTextColor);
+        mUnReachedBarColor = attributes
+                .getColor(
+                        R.styleable.HorizontalWithNumberProgressBar_progressbar_unreached_color,
+                        DEFAULT_COLOR_UNREACHED_COLOR);
+        mReachedProgressBarHeight = (int) attributes
+                .getDimension(
+                        R.styleable.HorizontalWithNumberProgressBar_progressbar_reached_height,
+                        mReachedProgressBarHeight);
+        mUnReachedProgressBarHeight = (int) attributes
+                .getDimension(
+                        R.styleable.HorizontalWithNumberProgressBar_progressbar_unreached_height,
+                        mUnReachedProgressBarHeight);
+        mTextOffset = (int) attributes
+                .getDimension(
+                        R.styleable.HorizontalWithNumberProgressBar_progressbar_text_offset,
+                        mTextOffset);
+
+        int textVisible = attributes
+                .getInt(R.styleable.HorizontalWithNumberProgressBar_progressbar_text_visibility,
+                        VISIBLE);
+        if (textVisible != VISIBLE) {
+            mIfDrawText = false;
+        }
+        attributes.recycle();
+    }
+
+    /**
+     * 刚才不是出onDraw里面写写就行了么,为什么要改onMeasure呢,主要是因为我们所有的属性比如进度条宽度让用户自定义了,所以我们的测量也得稍微变下。
+     */
+    @Override
+    protected synchronized void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+
+        if (heightMode != MeasureSpec.EXACTLY) {
+
+            float textHeight = (mPaint.descent() + mPaint.ascent());
+            int exceptHeight = (int) (getPaddingTop() + getPaddingBottom() + Math
+                    .max(Math.max(mReachedProgressBarHeight,
+                            mUnReachedProgressBarHeight), Math.abs(textHeight)));
+
+            heightMeasureSpec = MeasureSpec.makeMeasureSpec(exceptHeight,MeasureSpec.EXACTLY);
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+    }
+
+    /**
+     * 宽度我们不变,所以的自定义属性不涉及宽度,高度呢,只考虑不是EXACTLY的情况(用户明确指定了,我们就不管了),根据padding和进度条宽度算出自己想要的,如果非EXACTLY下,我们进行exceptHeight封装,传入给控件进行测量高度。
+     * 测量完,就到我们的onDraw了~~~
+     * <p>
+     * 其实核心方法就是onDraw了,但是呢,onDraw也很简单,绘制线、绘制文本、绘制线,结束。
+     */
+    @Override
+    protected synchronized void onDraw(Canvas canvas) {
+        canvas.save();
+        //画笔平移到指定paddingLeft, getHeight() / 2位置,注意以后坐标都为以此为0,0
+        canvas.translate(getPaddingLeft(), getHeight() / 2);
+
+        boolean noNeedBg = false;
+        //当前进度和总值的比例
+        float radio = getProgress() * 1.0f / getMax();
+        //已到达的宽度
+        float progressPosX = (int) (mRealWidth * radio);
+        //绘制的文本
+        String text = getProgress() + "%";
+
+        //拿到字体的宽度和高度
+        float textWidth = mPaint.measureText(text);
+        float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;
+
+        //如果到达最后,则未到达的进度条不需要绘制
+        if (progressPosX + textWidth > mRealWidth) {
+            progressPosX = mRealWidth - textWidth;
+            noNeedBg = true;
+        }
+
+        // 绘制已到达的进度
+        float endX = progressPosX - mTextOffset / 2;
+        if (endX > 0) {
+            mPaint.setColor(mReachedBarColor);
+            mPaint.setStrokeWidth(mReachedProgressBarHeight);
+            canvas.drawLine(0, 0, endX, 0, mPaint);
+        }
+
+        // 绘制文本
+        if (mIfDrawText) {
+            mPaint.setColor(mTextColor);
+            canvas.drawText(text, progressPosX, -textHeight, mPaint);
+        }
+
+        // 绘制未到达的进度条
+        if (!noNeedBg) {
+            float start = progressPosX + mTextOffset / 2 + textWidth;
+            mPaint.setColor(mUnReachedBarColor);
+            mPaint.setStrokeWidth(mUnReachedProgressBarHeight);
+            canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
+        }
+
+        canvas.restore();
+
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        mRealWidth = w - getPaddingRight() - getPaddingLeft();
+    }
+}

+ 119 - 0
DialogLibrary/src/main/java/com/fingerth/supdialogutils/progressbar/round/RoundWidthNumberProgressBar.java

@@ -0,0 +1,119 @@
+package com.fingerth.supdialogutils.progressbar.round;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+
+import com.fingerth.supdialogutils.R;
+import com.fingerth.supdialogutils.progressbar.horizontal.HorizontalWithNumberProgressBar;
+import com.fingerth.supdialogutils.utils.SupDialogStaticUtils;
+
+/**
+ * ======================================================
+ * Created by Administrator able_fingerth on 2017/7/13.
+ * <p/>
+ * 版权所有,违者必究!
+ * <详情描述/>
+ * 參考路徑:
+ * http://blog.csdn.net/lmj623565791/article/details/43371299
+ * 我自己有改善。
+ */
+public class RoundWidthNumberProgressBar extends HorizontalWithNumberProgressBar {
+
+//    android:layout_width="90dp"
+//    android:layout_height="90dp"
+//    fingerth:progressbar_reached_color="#0EFF96"
+//    fingerth:progressbar_reached_height="2dp"
+//    fingerth:progressbar_text_color="#0EFF96"
+//    fingerth:progressbar_text_size="16sp"
+//    fingerth:progressbar_unreached_color="#dddddd"
+//    fingerth:progressbar_unreached_height="1.5dp"
+//    fingerth:radius="43dp"
+
+//      <!--注意:當我把長寬寫成90dp時, 為了讓progressbar居中並且全部顯示,這時 radius + progressbar_reached_height 要等于45dp()-->
+
+    /**
+     * mRadius of view
+     */
+    private int mRadius = SupDialogStaticUtils.dp2px(getContext(), 30);
+
+    public RoundWidthNumberProgressBar(Context context) {
+        this(context, null);
+    }
+
+    public RoundWidthNumberProgressBar(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        //mReachedProgressBarHeight = (int) (mUnReachedProgressBarHeight * 2.5f);
+        //這裡我處理下 mReachedProgressBarHeight 要大於 mUnReachedProgressBarHeight
+        if (mUnReachedProgressBarHeight > mReachedProgressBarHeight) {
+            mUnReachedProgressBarHeight = mReachedProgressBarHeight;
+        }
+
+        TypedArray ta = context.obtainStyledAttributes(attrs,
+                R.styleable.RoundWidthNumberBar);
+        mRadius = (int) ta.getDimension(
+                R.styleable.RoundWidthNumberBar_radius, mRadius);
+        ta.recycle();
+
+        mTextSize = SupDialogStaticUtils.sp2px(getContext(), 14);
+
+        mPaint.setStyle(Paint.Style.STROKE);
+        mPaint.setAntiAlias(true);
+        mPaint.setDither(true);
+        mPaint.setStrokeCap(Paint.Cap.ROUND);
+
+    }
+
+    @Override
+    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+
+        int paintWidth = Math.max(mReachedProgressBarHeight, mUnReachedProgressBarHeight);
+
+        if (heightMode != MeasureSpec.EXACTLY) {
+            int exceptHeight = (int) (getPaddingTop() + getPaddingBottom() + mRadius * 2 + paintWidth);
+            heightMeasureSpec = MeasureSpec.makeMeasureSpec(exceptHeight, MeasureSpec.EXACTLY);
+        }
+        if (widthMode != MeasureSpec.EXACTLY) {
+            int exceptWidth = (int) (getPaddingLeft() + getPaddingRight() + mRadius * 2 + paintWidth);
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(exceptWidth, MeasureSpec.EXACTLY);
+        }
+
+        super.onMeasure(heightMeasureSpec, heightMeasureSpec);
+
+    }
+
+    @Override
+    protected synchronized void onDraw(Canvas canvas) {
+
+        String text = getProgress() + "%";
+        // mPaint.getTextBounds(text, 0, text.length(), mTextBound);
+        float textWidth = mPaint.measureText(text);
+        float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;
+
+        canvas.save();
+        canvas.translate(getPaddingLeft(), getPaddingTop());
+        mPaint.setStyle(Paint.Style.STROKE);
+        // draw unreaded bar
+        mPaint.setColor(mUnReachedBarColor);
+        mPaint.setStrokeWidth(mUnReachedProgressBarHeight);
+        canvas.drawCircle(mRadius + mReachedProgressBarHeight / 2, mRadius + mReachedProgressBarHeight / 2, mRadius, mPaint);
+        // draw reached bar
+        mPaint.setColor(mReachedBarColor);
+        mPaint.setStrokeWidth(mReachedProgressBarHeight);
+        float sweepAngle = getProgress() * 1.0f / getMax() * 360;
+        canvas.drawArc(new RectF(mReachedProgressBarHeight / 2, mReachedProgressBarHeight / 2, mRadius * 2 + mReachedProgressBarHeight / 2, mRadius * 2 + mReachedProgressBarHeight / 2),
+                270, sweepAngle, false, mPaint);
+        // draw text
+        mPaint.setStyle(Paint.Style.FILL);
+        canvas.drawText(text, mRadius - textWidth / 2, mRadius - textHeight, mPaint);
+
+        canvas.restore();
+
+    }
+}

+ 66 - 0
DialogLibrary/src/main/java/com/fingerth/supdialogutils/utils/SupDialogStaticUtils.java

@@ -0,0 +1,66 @@
+package com.fingerth.supdialogutils.utils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+
+public class SupDialogStaticUtils {
+
+    public static final String TAG = "SupDialogStaticUtils";
+
+    private static int sysWidth = 0;
+    private static int sysHeight = 0;
+
+    /**
+     * 获取手机的分比率,高和宽
+     */
+    private static void getScreen(Activity activity) {
+        if (SupDialogStaticUtils.sysWidth <= 0 || SupDialogStaticUtils.sysHeight <= 0) {
+            DisplayMetrics dm = new DisplayMetrics();
+            activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
+            SupDialogStaticUtils.sysWidth = dm.widthPixels;
+            SupDialogStaticUtils.sysHeight = dm.heightPixels;
+        }
+    }
+
+    public static int getScreenWidth(Activity activity) {
+        getScreen(activity);
+        return SupDialogStaticUtils.sysWidth;
+    }
+
+    public static int getScreenHeight(Activity activity) {
+        getScreen(activity);
+        return SupDialogStaticUtils.sysHeight;
+    }
+
+    public static int getStatusBarHeight(Context c) {
+        int result = 0;
+        int resourceId = c.getResources().getIdentifier("status_bar_height", "dimen", "android");
+        if (resourceId > 0) {
+            result = c.getResources().getDimensionPixelSize(resourceId);
+        }
+        return result;
+    }
+
+
+    public static int dp2px(Context context, int dp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
+    }
+
+    public static int dp2px(Context context, float dp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
+    }
+
+
+    public static int sp2px(Context context, int sp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());
+
+    }
+
+    public static int px2dip(Context context, float pxValue) {
+        final float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+}

BIN=BIN
DialogLibrary/src/main/res/drawable-hdpi/dialog_error.png


BIN=BIN
DialogLibrary/src/main/res/drawable-hdpi/dialog_success.png


BIN=BIN
DialogLibrary/src/main/res/drawable-hdpi/dialog_tip.png


+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_error_red.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="2dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="#E70012"
+        android:startColor="#E70012" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="#E70012" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="#E70012" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_error_red_dark.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="2dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="#AA0012"
+        android:startColor="#AA0012" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="#AA0012" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="#AA0012" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_gray.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="2dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="@color/gray_a3"
+        android:startColor="@color/gray_a3" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="@color/gray_a3" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="@color/gray_a3" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_gray_dark.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="2dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="@color/gray_63"
+        android:startColor="@color/gray_63" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="@color/gray_63" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="@color/gray_63" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_green.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="2dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="#6BC839"
+        android:startColor="#6BC839" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="#6BC839" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="#6BC839" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_green_dark.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="2dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="#3C7E18"
+        android:startColor="#3C7E18" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="#3C7E18" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="#3C7E18" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_tip.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="2dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="@color/tip_color"
+        android:startColor="@color/tip_color" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="@color/tip_color" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="@color/tip_color" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_tip_dark.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="2dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="@color/tip_dark_color"
+        android:startColor="@color/tip_dark_color" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="@color/tip_dark_color" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="@color/tip_dark_color" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_white.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="10dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="@color/white"
+        android:startColor="@color/white" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="@color/white" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="@color/white" />
+
+</shape>

+ 22 - 0
DialogLibrary/src/main/res/drawable/drawable_round_white_dd.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--圆角的半径,设置圆角半径-->
+    <corners android:radius="5dp" />
+
+    <!-- 渐变 -->
+    <gradient
+        android:angle="270"
+        android:endColor="@color/white_dd"
+        android:startColor="@color/white_dd" />
+
+
+    <!-- 填充,填充的颜色 -->
+    <solid android:color="@color/white_dd" />
+
+    <!-- 描边 -->
+    <stroke
+        android:width="0.5dp"
+        android:color="@color/white_dd" />
+
+</shape>

+ 6 - 0
DialogLibrary/src/main/res/drawable/selector_error_red.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/drawable_round_error_red_dark" android:state_pressed="true" />
+    <item android:drawable="@drawable/drawable_round_error_red" />
+
+</selector>

+ 6 - 0
DialogLibrary/src/main/res/drawable/selector_gray.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/drawable_round_gray_dark" android:state_pressed="true" />
+    <item android:drawable="@drawable/drawable_round_gray" />
+
+</selector>

+ 6 - 0
DialogLibrary/src/main/res/drawable/selector_green.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/drawable_round_green_dark" android:state_pressed="true" />
+    <item android:drawable="@drawable/drawable_round_green" />
+
+</selector>

+ 6 - 0
DialogLibrary/src/main/res/drawable/selector_tip_color.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/drawable_round_tip_dark" android:state_pressed="true" />
+    <item android:drawable="@drawable/drawable_round_tip" />
+
+</selector>

+ 69 - 0
DialogLibrary/src/main/res/layout/dialog_alert_view.xml

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/trans"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/dialog_view_layout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/drawable_round_white"
+        android:orientation="vertical"
+        android:paddingBottom="25dp"
+        android:paddingLeft="10dp"
+        android:paddingRight="10dp"
+        android:paddingTop="10dp">
+
+        <ImageView
+            android:id="@+id/dialog_icon"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginBottom="5dp"
+            android:layout_marginTop="15dp"
+            android:scaleType="fitCenter" />
+
+
+        <TextView
+            android:id="@+id/title_tv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:gravity="center_horizontal"
+            android:padding="10dp"
+            android:singleLine="true"
+            android:textColor="@color/gray_24"
+            android:textSize="23sp"
+            android:textStyle="bold" />
+
+        <TextView
+            android:id="@+id/message_tv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:gravity="center_horizontal"
+            android:padding="5dp"
+            android:textColor="@color/gray_6c"
+            android:textSize="14sp" />
+
+
+        <TextView
+            android:id="@+id/confirm"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="10dp"
+            android:background="@drawable/selector_green"
+            android:gravity="center"
+            android:minWidth="70dp"
+            android:paddingBottom="6dp"
+            android:paddingLeft="10dp"
+            android:paddingRight="10dp"
+            android:paddingTop="6dp"
+            android:textColor="@color/white"
+            android:textSize="16sp" />
+    </LinearLayout>
+
+</FrameLayout>

+ 109 - 0
DialogLibrary/src/main/res/layout/dialog_confirm_alert_view.xml

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/trans"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/dialog_view_layout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/drawable_round_white"
+        android:orientation="vertical"
+        android:paddingBottom="20dp"
+        android:paddingLeft="10dp"
+        android:paddingRight="10dp"
+        android:paddingTop="15dp">
+
+        <ImageView
+            android:id="@+id/dialog_icon"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            android:layout_gravity="center_horizontal"
+            android:paddingBottom="5dp"
+            android:scaleType="fitCenter"
+            android:src="@drawable/dialog_tip" />
+
+
+        <TextView
+            android:id="@+id/title_tv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:gravity="center_horizontal"
+            android:paddingBottom="5dp"
+            android:paddingTop="1dp"
+            android:singleLine="true"
+            android:text="標題"
+            android:textColor="@color/gray_24"
+            android:textSize="23sp"
+            android:textStyle="bold" />
+
+        <TextView
+            android:id="@+id/message_tv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:gravity="center_horizontal"
+            android:paddingBottom="15dp"
+            android:paddingTop="1dp"
+            android:text="你確定要這樣嗎?"
+            android:textColor="@color/gray_6c"
+            android:textSize="14sp" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <View
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_weight="3" />
+
+            <TextView
+                android:id="@+id/cancel"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:background="@drawable/selector_gray"
+                android:gravity="center"
+                android:minWidth="90dp"
+                android:paddingBottom="8dp"
+                android:paddingLeft="10dp"
+                android:paddingRight="10dp"
+                android:paddingTop="8dp"
+                android:textColor="@color/white"
+                android:textSize="16sp" />
+
+            <View
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_weight="1" />
+
+            <TextView
+                android:id="@+id/confirm"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:background="@drawable/selector_tip_color"
+                android:gravity="center"
+                android:minWidth="90dp"
+                android:paddingBottom="8dp"
+                android:paddingLeft="10dp"
+                android:paddingRight="10dp"
+                android:paddingTop="8dp"
+                android:textColor="@color/white"
+                android:textSize="16sp" />
+
+            <View
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_weight="3" />
+        </LinearLayout>
+
+
+    </LinearLayout>
+
+</FrameLayout>

+ 69 - 0
DialogLibrary/src/main/res/layout/dialog_horizontal_progressbar_view.xml

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:fingerth="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@color/trans"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/dialog_progress_layout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/drawable_round_white"
+        android:orientation="vertical"
+        android:paddingBottom="10dp"
+        android:paddingLeft="15dp"
+        android:paddingRight="15dp"
+        android:paddingTop="10dp">
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="3" />
+
+        <TextView
+            android:id="@+id/title_tv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:padding="5dp"
+            android:singleLine="true"
+            android:textColor="@color/gray_24"
+            android:textSize="16sp" />
+
+        <TextView
+            android:id="@+id/message_tv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:padding="5dp"
+            android:singleLine="true"
+            android:textColor="@color/gray_24"
+            android:textSize="14sp" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1" />
+
+        <com.fingerth.supdialogutils.progressbar.horizontal.HorizontalWithNumberProgressBar
+            android:id="@+id/horizontal_bar"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="5dp"
+            android:progress="50"
+            fingerth:progressbar_text_color="#0EFF96"
+            fingerth:progressbar_unreached_color="#dddddd"
+            fingerth:progressbar_reached_color="#0EFF96"
+            />
+
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="4" />
+
+
+    </LinearLayout>
+</FrameLayout>

+ 51 - 0
DialogLibrary/src/main/res/layout/dialog_progress_view.xml

@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/trans"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/dialog_progress_layout"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/drawable_round_white"
+        android:orientation="vertical"
+        android:paddingBottom="25dp"
+        android:paddingLeft="15dp"
+        android:paddingRight="15dp"
+        android:paddingTop="10dp">
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1" />
+
+        <ProgressBar
+            style="@android:style/Widget.Holo.Light.ProgressBar.Large"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginBottom="5dp"
+            android:layout_marginTop="15dp" />
+        
+        <TextView
+            android:id="@+id/message_tv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:gravity="center_horizontal"
+            android:padding="5dp"
+            android:singleLine="true"
+            android:text="加載中..."
+            android:textColor="@color/gray_63"
+            android:textSize="16sp" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1" />
+
+
+    </LinearLayout>
+</FrameLayout>

+ 61 - 0
DialogLibrary/src/main/res/layout/dialog_round_progressbar_view.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:fingerth="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@color/trans"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/dialog_progress_layout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/drawable_round_white"
+        android:orientation="vertical"
+        android:paddingBottom="10dp"
+        android:paddingLeft="15dp"
+        android:paddingRight="15dp"
+        android:paddingTop="10dp">
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1" />
+
+
+        <com.fingerth.supdialogutils.progressbar.round.RoundWidthNumberProgressBar
+            android:id="@+id/round_bar"
+            android:layout_width="80dp"
+            android:layout_height="80dp"
+            android:layout_gravity="center_horizontal"
+            android:progress="50"
+            fingerth:progressbar_reached_color="#0EFF96"
+            fingerth:progressbar_reached_height="2dp"
+            fingerth:progressbar_text_color="#0EFF96"
+            fingerth:progressbar_text_size="14sp"
+            fingerth:progressbar_unreached_color="#dddddd"
+            fingerth:progressbar_unreached_height="1.5dp"
+            fingerth:radius="38dp" />
+
+        <!--注意:當我把長寬寫成80dp時, 為了讓progressbar居中並且全部顯示,這時 radius+progressbar_reached_height 要等于40dp()-->
+
+        <TextView
+            android:id="@+id/message_tv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="1dp"
+            android:gravity="center_horizontal"
+            android:padding="2dp"
+            android:singleLine="true"
+            android:textColor="@color/gray_24"
+            android:textSize="14sp" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1" />
+
+
+    </LinearLayout>
+</FrameLayout>

+ 24 - 0
DialogLibrary/src/main/res/values/attr_progressbar.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <declare-styleable name="HorizontalWithNumberProgressBar">
+        <attr name="progressbar_reached_color" format="color" />
+        <attr name="progressbar_unreached_color" format="color" />
+
+        <attr name="progressbar_reached_height" format="dimension" />
+        <attr name="progressbar_unreached_height" format="dimension" />
+
+
+        <attr name="progressbar_text_size" format="dimension" />
+        <attr name="progressbar_text_color" format="color" />
+        <attr name="progressbar_text_offset" format="dimension" />
+        <attr name="progressbar_text_visibility" format="enum">
+            <enum name="visible" value="0" />
+            <enum name="invisible" value="1" />
+        </attr>
+    </declare-styleable>
+
+
+    <declare-styleable name="RoundWidthNumberBar">
+        <attr name="radius" format="dimension" />
+    </declare-styleable>
+</resources>

+ 30 - 0
DialogLibrary/src/main/res/values/colors.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- 黑色 -->
+    <color name="black">#000000</color>
+    <color name="red">#ff0000</color>
+
+    <color name="trans">#00000000</color>
+
+
+    <color name="white">#FFFFFF</color>
+    <color name="white_f8">#F8F8F8</color>
+    <color name="white_f4">#F4F4F4</color>
+    <color name="white_dd">#DDDDDD</color>
+    <color name="white_ee">#EEEEEE</color>
+
+
+    <color name="gray_24">#24292B</color>
+    <color name="gray_33">#333333</color>
+    <color name="gray_a3">#A3A3A3</color>
+    <color name="gray_6c">#6c6c6c</color>
+    <color name="gray_63">#636363</color>
+    <color name="gray">#808080</color>
+
+
+    <color name="green">#808080</color>
+
+    <color name="tip_color">#FF5252</color>
+    <color name="tip_dark_color">#FF2525</color>
+
+</resources>

+ 3 - 0
DialogLibrary/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">FingerthDialogUtilsLibrary</string>
+</resources>

+ 22 - 0
DialogLibrary/src/main/res/values/styles.xml

@@ -0,0 +1,22 @@
+<resources>
+
+
+    <!--<style name="AlertDialog_Styles" parent="Theme.AppCompat.Light.Dialog" />-->
+
+    <style name="AlertDialog_Styles" parent="android:Theme.Dialog">
+        <!--<item name="android:windowAnimationStyle">@style/AnimAlert</item>-->
+        <!-- 边框 -->
+        <item name="android:windowFrame">@null</item>
+        <!-- 是否浮现在activity之上 -->
+        <item name="android:windowIsFloating">true</item>
+        <!-- 半透明 -->
+        <item name="android:windowIsTranslucent">true</item>
+        <!-- 无标题 -->
+        <item name="android:windowNoTitle">true</item>
+        <!-- 背景透明 -->
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <!-- 模糊 -->
+        <item name="android:backgroundDimEnabled">true</item>
+    </style>
+
+</resources>

+ 3 - 0
app/.gitignore

@@ -0,0 +1,3 @@
+build
+.cxx
+*.iml

+ 58 - 0
app/build.gradle

@@ -0,0 +1,58 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 29
+
+
+    defaultConfig {
+        applicationId "com.ifastore.goodsmanage"
+        minSdkVersion 27
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    android.applicationVariants.all {
+        variant ->
+            variant.outputs.all {
+                outputFileName = variant.getApplicationId()+ "-v${variant.versionName}.apk"
+            }
+    }
+
+    sourceSets {
+        main {
+            jniLibs.srcDirs = ['libs']
+        }
+    }
+    repositories {
+        flatDir {
+            dirs 'libs'
+        }
+    }
+
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+    //noinspection GradleCompatible
+    implementation 'com.android.support:appcompat-v7:28.0.0'
+    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+    testImplementation 'junit:junit:4.13'
+    androidTestImplementation 'com.android.support.test:runner:1.0.2'
+    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+    implementation 'com.jakewharton:butterknife:8.8.1'
+    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
+    implementation(name: 'serialport-1.0.1', ext: 'aar')
+    implementation project(':DialogLibrary')
+    implementation 'com.github.inksnow:popuputils:1.0.9'
+
+}

BIN=BIN
app/libs/arm64-v8a/libserial.so


BIN=BIN
app/libs/armeabi-v7a/libserial.so


BIN=BIN
app/libs/serialibrary.jar


BIN=BIN
app/libs/serialport-1.0.1.aar


+ 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

+ 1 - 0
app/release/output.json

@@ -0,0 +1 @@
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"com.ifastore.goodsmanage-v1.0.apk","fullName":"release","baseName":"release","dirName":""},"path":"com.ifastore.goodsmanage-v1.0.apk","properties":{}}]

+ 26 - 0
app/src/androidTest/java/com/ifastore/goodsmanage/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.ifastore.goodsmanage;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.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.getInstrumentation().getTargetContext();
+
+        assertEquals("com.ifastore.goodsmanage", appContext.getPackageName());
+    }
+}

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

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.ifastore.goodsmanage">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
+        <activity android:name="com.ifastore.goodsmanage.MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>

+ 538 - 0
app/src/main/java/com/ifastore/goodsmanage/MainActivity.java

@@ -0,0 +1,538 @@
+package com.ifastore.goodsmanage;
+
+import android.annotation.SuppressLint;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+import android.widget.Spinner;
+import android.widget.TextClock;
+import android.widget.TextView;
+import android.widget.Toast;
+
+
+import com.ifastore.goodsmanage.models.ObjectBean;
+import com.ifastore.goodsmanage.serialport.CommTask;
+import com.ifastore.goodsmanage.utils.Logger;
+import com.inks.inkslibrary.Popup.PopupPrompt;
+import com.inks.inkslibrary.Popup.PopupSelect;
+import com.inks.inkslibrary.Popup.PopupView;
+import com.inks.inkslibrary.Popup.PromptSettings;
+import com.inks.inkslibrary.Popup.SelectListDataBean;
+import com.inks.inkslibrary.Popup.SelectSettings;
+import com.inks.inkslibrary.Popup.ViewSettings;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import android_serialport_api.SerialPortFinder;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+import static android.widget.Toast.LENGTH_SHORT;
+import static com.ifastore.goodsmanage.common.Constants.REPORT_EVENT_GOODS;
+import static com.ifastore.goodsmanage.common.Constants.REPORT_EVENT_MOTOR;
+import static com.ifastore.goodsmanage.common.Constants.RESULT_CONTROL_LIGHT;
+import static com.ifastore.goodsmanage.common.Constants.RESULT_CONTROL_SALE;
+
+
+public class MainActivity extends AppCompatActivity {
+
+    @BindView(R.id.sale)
+    Button sale;
+    @BindView(R.id.openSerial)
+    Button openSerial;
+    @BindView(R.id.closeSerial)
+    Button closeSerial;
+    @BindView(R.id.clearLog)
+    Button clearLog;
+    @BindView(R.id.controlLight)
+    Button controlLight;
+    @BindView(R.id.serial)
+    Spinner serial;
+    @BindView(R.id.baute)
+    Spinner baute;
+    @BindView(R.id.listLog)
+    ListView logListView;
+    @BindView(R.id.logLayout)
+    RelativeLayout logLayout;
+
+    private Window window;
+    private LayoutInflater inflater;
+    private View linearLayout;
+    private Context context;
+    private PopupView popupView;
+    private PopupPrompt popupPrompt;
+    private PopupSelect popupSelect;
+    public Spinner xSpinGoodsWay;
+    public Spinner ySpinGoodsWay;
+    public Spinner spinGoodsNum;
+    private TextView textView;
+
+    private SerialPortFinder serialPortFinder;
+    private CommTask commTask;
+    private BusinessBroadCastReceiver broadCastReceiver;
+    private List<SelectListDataBean> selectListDataBeans = new ArrayList<>();
+    private List<String> logList = new ArrayList<>();
+    private ArrayAdapter<String> adapter;
+    private BlockingQueue<ObjectBean> queue;
+    private static String serialStr = "";
+    private static int  bauteValue = 0;
+    private static int  xGoosdWay = 0;
+    private static int  yGoosdWay = 0;
+    private static int  goodsNum = 1;
+    private static int  choosedLight = 0;
+    private boolean isFirst = false;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        ButterKnife.bind(this);
+        iniview();
+        initData();
+        initBroadCast();
+    }
+    private Handler handler = new Handler(new Handler.Callback() {
+        @Override
+        public boolean handleMessage(Message message) {
+            String msg = message.obj.toString();
+            switch (message.what){
+                case 0 :
+                    showLog(msg, true);
+                    break;
+                case 1:
+                    showLog(msg, false);
+                    break;
+            }
+            return false;
+        }
+    });
+
+
+    @SuppressLint("ShowToast")
+    @OnClick({R.id.sale, R.id.closeSerial, R.id.openSerial, R.id.clearLog, R.id.controlLight})
+     public void onClick (View view){
+        if(!isFirst){
+            isFirst = true;
+            logLayout.removeView(textView);
+            logListView.setVisibility(View.VISIBLE);
+        }
+        switch (view.getId()){
+            case R.id.openSerial:
+                openSerial();
+                break;
+            case R.id.closeSerial:
+                closeSerial();
+                break;
+            case R.id.clearLog:
+                logList.clear();
+                adapter.notifyDataSetChanged();
+                break;
+            default:
+                serialCmdHandler(view.getId());
+                break;
+        }
+    }
+
+    private void serialCmdHandler(int id){
+        if(commTask == null) {
+            Toast.makeText(this, "请打开串口!", LENGTH_SHORT).show();
+            showLog("请打开串口!");
+            return;
+        }
+        switch (id){
+            case R.id.openSerial:
+                openSerial();
+                break;
+            case R.id.closeSerial:
+                closeSerial();
+                break;
+            case R.id.sale:
+                if(commTask.isopen){
+                    setOutGoodsInfo();
+                }
+                break;
+            case R.id.controlLight:
+                selectLight();
+                break;
+        }
+    }
+
+    private void initBroadCast(){
+        broadCastReceiver = new BusinessBroadCastReceiver();
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(RESULT_CONTROL_SALE);
+        intentFilter.addAction(RESULT_CONTROL_LIGHT);
+        intentFilter.addAction(REPORT_EVENT_GOODS);
+        intentFilter.addAction(REPORT_EVENT_MOTOR);
+        this.registerReceiver(broadCastReceiver, intentFilter);
+    }
+
+
+    private  class BusinessBroadCastReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent != null) {
+                switch (Objects.requireNonNull(intent.getAction())) {
+                    case RESULT_CONTROL_SALE:
+                        int result = intent.getIntExtra(RESULT_CONTROL_SALE, -1);
+                        if(result == 0){
+                            showLog("售卖成功");
+                            pupWindows("售卖成功!");
+                        }else {
+                            showLog("售卖失败!");
+                            pupWindows("售卖失败:"+result);
+                        }
+                        break;
+                    case RESULT_CONTROL_LIGHT:
+                        int lightResult = intent.getIntExtra(RESULT_CONTROL_LIGHT, -1);
+                        Logger.debug("light result::" +lightResult);
+                        if(lightResult == 0){
+                            if(choosedLight == 0){
+                                showLog("关闭光幕成功");
+                                pupWindows("关闭光幕成功");
+                            }else {
+                                showLog("打开光幕成功");
+                                pupWindows("打开光幕成功");
+                            }
+                        }else {
+                            if(choosedLight == 0){
+                                showLog("关闭光幕失败");
+                                pupWindows("关闭光幕失败");
+                            }else {
+                                showLog("打开光幕失败");
+                                pupWindows("打开光幕失败");
+                            }
+                        }
+                        break;
+                    case REPORT_EVENT_MOTOR:
+                        int motorResult = intent.getIntExtra(REPORT_EVENT_MOTOR, -1);
+                        Logger.debug("motor error result:" +motorResult);
+                        showLog("电机异常:"+motorResult);
+                        pupWindows("电机异常:"+motorResult);
+                        break;
+                    case REPORT_EVENT_GOODS:
+                        int outResult = intent.getIntExtra(REPORT_EVENT_GOODS, -1);
+                        Logger.debug("out goods result::" +outResult);
+                        if(outResult == 0){
+                            showLog("出货成功");
+                            pupWindows("出货成功");
+                        }else {
+                            showLog("出货异常:"+outResult);
+                            pupWindows("出货异常:"+outResult);
+
+                        }
+                        break;
+                }
+            }
+        }
+    }
+
+
+    private void openSerial(){
+        commTask = CommTask.openSerialport(this, serialStr, bauteValue);
+        if(!commTask.isopen){
+            pupWindows("打开串口出错,请换可用串口!");
+            showLog("打开串口出错,请换可用串口!");
+            return;
+        }
+        commTask.addListener(new CommTask.ISerialEventListener() {
+            @Override
+            public void transferDataSend(String sendData) {
+                 Message msg = new Message();
+                 msg.what = 0;
+                 msg.obj = sendData;
+                 handler.sendMessage(msg);
+            }
+
+            @Override
+            public void transferDataRecv(String recvData) {
+                 Message msg = new Message();
+                 msg.what = 1;
+                 msg.obj = recvData;
+                 handler.sendMessage(msg);
+                }
+            });
+        openSerial.setVisibility(View.INVISIBLE);
+        closeSerial.setVisibility(View.VISIBLE);
+        pupWindows("打开串口成功");
+        showLog("打开串口成功!");
+    }
+
+    private void closeSerial(){
+        CommTask.closeSerialPort();
+        showLog("关闭串口!");
+        pupWindows("关闭串口");
+        openSerial.setVisibility(View.VISIBLE);
+        closeSerial.setVisibility(View.INVISIBLE);
+    }
+
+    private void initData(){
+        queue = new LinkedBlockingQueue<>();
+        SelectListDataBean selectListDataBean;
+        selectListDataBeans.clear();
+        selectListDataBean = new SelectListDataBean();
+        selectListDataBean.setText("关闭");
+        selectListDataBean.setChoosed(true);
+        selectListDataBeans.add(selectListDataBean);
+        selectListDataBean = new SelectListDataBean();
+        selectListDataBean.setText("打开");
+        selectListDataBean.setChoosed(false);
+        selectListDataBeans.add(selectListDataBean);
+    }
+
+
+    private void iniview() {
+        window = this.getWindow();
+        inflater = this.getLayoutInflater();
+        context = this;
+        popupView = new PopupView();
+        popupPrompt = new PopupPrompt();
+        popupSelect = new PopupSelect();
+        popupView = new PopupView();
+        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        textView = new TextView(this);
+        textView.setTextSize(100);
+        textView.setGravity(Gravity.CENTER);
+        textView.setText("售货机测试");
+        textView.setLayoutParams(layoutParams);
+        logLayout.addView(textView);
+        linearLayout = (LinearLayout) inflater.inflate(R.layout.scrollviewtest, null, false);
+        xSpinGoodsWay = linearLayout.findViewById(R.id.xNum);
+        ySpinGoodsWay = linearLayout.findViewById(R.id.yNum);
+        spinGoodsNum = linearLayout.findViewById(R.id.goodsNum);
+        adapter = new ArrayAdapter<String>(this, R.layout.log_item_layout,logList);
+        logListView.setAdapter(adapter);
+        adapter.notifyDataSetChanged();
+        serialPortFinder = new SerialPortFinder();
+        final String[] ports = serialPortFinder.getAllDevicesPath();
+        final String[] botes = new String[]{"4800", "9600", "19200", "38400", "57600", "115200", "230400", "460800", "500000", "576000", "921600", "1000000", "1152000", "1500000", "2000000", "2500000", "3000000", "3500000", "4000000"};
+
+        SpAdapter spAdapter = new SpAdapter(this);
+        spAdapter.setDatas(ports);
+        serial.setAdapter(spAdapter);
+        serial.setSelection(0,true);
+
+        serial.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                serialStr = ports[position];
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+
+            }
+        });
+
+        SpAdapter spAdapter2 = new SpAdapter(this);
+        spAdapter2.setDatas(botes);
+        baute.setAdapter(spAdapter2);
+        baute.setSelection(0,true);
+
+        baute.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                bauteValue = Integer.parseInt(botes[position]);
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+
+            }
+        });
+        final String[] xyNum = new String[]{"0","1", "2", "3", "4", "5", "6", "7", "8", "9"};
+        final String[] selectGoodsNum = new String[]{"1"};
+        SpAdapter spAdapter3 = new SpAdapter(this);
+        spAdapter3.setDatas(xyNum);
+        if(xSpinGoodsWay == null){
+            Logger.debug("xSpinGoodsWay");
+        }
+        xSpinGoodsWay.setAdapter(spAdapter3);
+        xSpinGoodsWay.setSelection(0,true);
+
+        xSpinGoodsWay.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                xGoosdWay = Integer.parseInt(xyNum[position]);
+                Logger.debug(">>>>>>>position %s  xGoosdWay:%s", position, xGoosdWay);
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+
+            }
+        });
+        SpAdapter spAdapter4 = new SpAdapter(this);
+        spAdapter4.setDatas(xyNum);
+        ySpinGoodsWay.setAdapter(spAdapter4);
+        ySpinGoodsWay.setSelection(0,true);
+
+        ySpinGoodsWay.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                yGoosdWay = Integer.parseInt(xyNum[position]);
+                Logger.debug(">>>>>>>position %s  yGoosdWay:%s", position, yGoosdWay);
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+
+            }
+        });
+
+        SpAdapter spAdapter5 = new SpAdapter(this);
+        spAdapter5.setDatas(selectGoodsNum);
+        spinGoodsNum.setAdapter(spAdapter5);
+        spinGoodsNum.setSelection(0,true);
+
+        spinGoodsNum.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                goodsNum = Integer.parseInt(selectGoodsNum[position]);
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+
+            }
+        });
+    }
+
+    private void pupWindows(String mgs){
+        popupPrompt.miss();
+        PromptSettings.Builder builder = new PromptSettings.Builder();
+        PromptSettings promptSettings = builder
+                .text(mgs)
+                .clippingEnabled(true)
+                .textPaddings(new int[]{50,0,0,0})
+                .location(Gravity.TOP)
+                .width(500)
+                .textSize(24)
+                .popupAnim(R.style.popup_top_down)
+                .bgAlpha(0.6f)
+                .build();
+        popupPrompt.popupPrompt(window,context,inflater,promptSettings,0);
+    }
+    private void selectLight(){
+        SelectSettings.Builder builder = new SelectSettings.Builder();
+        SelectSettings promptSettings =
+                        builder.selectListDataBean(selectListDataBeans)
+                                .clickListener(selectBackListener)
+                                .titleTextStr("光幕控制")
+                                .titleTextPaddings(new int[]{10,20,0,20})
+                                .showTitleIcon(true)
+                                .popupWidth(500)
+                                .popupHeight(300)
+                                .multipleSelection(false)
+                                .showListIcon(true)
+                                .build();
+        popupSelect.popupSelect(window,context,inflater,promptSettings,0);
+    }
+
+    private void setOutGoodsInfo(){
+        ViewSettings.Builder builder = new ViewSettings.Builder();
+        ViewSettings promptSettings =
+                builder .clickListener(popupBackListener)
+                        .titleTextStr("设置出货信息")
+                        .titleTextPaddings(new int[]{10,20,0,20})
+                        .showTitleIcon(true)
+                        .popupWidth(500)
+                        .popupHeight(300)
+                        .build();
+        if(linearLayout.getParent()!=null){
+            ((ViewGroup) linearLayout.getParent()).removeView(linearLayout);
+        }
+        popupView.popupView(window,context,inflater,linearLayout,promptSettings,3);
+    }
+
+    PopupView.onClickListener popupBackListener = new PopupView.onClickListener() {
+
+        @Override
+        public void onYesBack(int what) {
+            pupWindows("X货道:"+xGoosdWay +" Y货道:"+yGoosdWay +" 数量:"+goodsNum);
+            showLog("X货道:"+xGoosdWay +" Y货道:"+yGoosdWay +""+" 数量:"+goodsNum);
+            if(commTask != null){
+                commTask.saleGoods((byte) xGoosdWay,  (byte) yGoosdWay, (byte) 1);
+            }else {
+                pupWindows("请打开串口!");
+            }
+
+        }
+
+        @Override
+        public void onCancelBack(int what) {
+            pupWindows("pupWindows"+what+"取消按钮");
+        }
+    };
+
+    PopupSelect.onClickListener selectBackListener = new PopupSelect.onClickListener() {
+        @Override
+        public void onChooseBack(List<SelectListDataBean> selectListDataBeans, int what) {
+            int choosed = -1;
+            for(int i = 0;i<selectListDataBeans.size();i++){
+                if(selectListDataBeans.get(i).isChoosed()){
+                    choosedLight = i;
+                    Logger.debug("choosed:"+choosedLight);
+                }
+            }
+            Logger.debug("what:"+what);
+            if(what == 0){
+                if(choosedLight >= 0) {
+                    if(commTask == null){
+                        pupWindows("请打开串口!");
+                    }else {
+                        if (commTask.isopen) {
+                            commTask.controlLight((byte) choosedLight);
+                        }
+                    }
+                }
+            }
+
+        }
+
+        @Override
+        public void onCancelBack(List<SelectListDataBean> selectListDataBeans, int what) {
+
+        }
+    };
+
+    synchronized private void showLog(String log, boolean send){
+        String info;
+        if(send) info = "> "+log;else info = "< "+log;
+        logList.add(info);
+        adapter.notifyDataSetChanged();
+    }
+
+    synchronized private void showLog(String log){
+        logList.add(log);
+        adapter.notifyDataSetChanged();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        this.unregisterReceiver(broadCastReceiver);
+    }
+}

+ 61 - 0
app/src/main/java/com/ifastore/goodsmanage/SpAdapter.java

@@ -0,0 +1,61 @@
+package com.ifastore.goodsmanage;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import com.ifastore.goodsmanage.R;
+
+public class SpAdapter extends BaseAdapter {
+
+    String[] datas;
+    Context mContext;
+
+    public SpAdapter(Context context) {
+        this.mContext = context;
+    }
+
+    public void setDatas(String[] datas) {
+        this.datas = datas;
+        notifyDataSetChanged();
+    }
+
+    @Override
+    public int getCount() {
+        return datas == null ? 0 : datas.length;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return datas == null ? null : datas[position];
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ViewHodler hodler = null;
+        if (convertView == null) {
+            hodler = new ViewHodler();
+            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_layout, null);
+            hodler.mTextView = (TextView) convertView;
+            convertView.setTag(hodler);
+        } else {
+            hodler = (ViewHodler) convertView.getTag();
+        }
+
+        hodler.mTextView.setText(datas[position]);
+
+        return convertView;
+    }
+
+    private static class ViewHodler {
+        TextView mTextView;
+    }
+}

+ 14 - 0
app/src/main/java/com/ifastore/goodsmanage/common/Constants.java

@@ -0,0 +1,14 @@
+package com.ifastore.goodsmanage.common;
+
+public class Constants {
+
+    //result
+    public static final String RESULT_CONTROL_SALE = "result_sale";
+    public static final String RESULT_CONTROL_LIGHT= "result_light";
+
+    //auto report
+    public static final String REPORT_EVENT_GOODS = "out_goods";
+    public static final String REPORT_EVENT_MOTOR = "motor_error";
+
+
+}

+ 58 - 0
app/src/main/java/com/ifastore/goodsmanage/models/ObjectBean.java

@@ -0,0 +1,58 @@
+package com.ifastore.goodsmanage.models;
+
+public class ObjectBean {
+    private int what;
+    private int arg1;
+    private int arg2;
+    private int arg3;
+    private String value;
+    private String result;
+
+    public int getArg1() {
+        return arg1;
+    }
+
+    public void setArg1(int arg1) {
+        this.arg1 = arg1;
+    }
+
+    public int getArg2() {
+        return arg2;
+    }
+
+    public void setArg2(int arg2) {
+        this.arg2 = arg2;
+    }
+
+    public int getArg3() {
+        return arg3;
+    }
+
+    public void setArg3(int arg3) {
+        this.arg3 = arg3;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public int getWhat() {
+        return what;
+    }
+
+    public void setWhat(int what) {
+        this.what = what;
+    }
+}

+ 539 - 0
app/src/main/java/com/ifastore/goodsmanage/serialport/CommSerial.java

@@ -0,0 +1,539 @@
+package com.ifastore.goodsmanage.serialport;
+
+import com.ifastore.goodsmanage.serialport.protocol.Constant;
+import com.ifastore.goodsmanage.serialport.protocol.Frame;
+import com.ifastore.goodsmanage.serialport.protocol.Protocol;
+import com.ifastore.goodsmanage.utils.Logger;
+import com.ifastore.goodsmanage.utils.TypeConverter;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.HashSet;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+
+public class CommSerial {
+    private final String TAG = "CommSerial";
+
+
+    private InputStream m_InStream = null;
+    private OutputStream m_OutStream = null;
+    private ReadThread m_ReadThread = null;
+    private volatile boolean m_bStopReadThread = true;
+    private Collection<ICommSerialEventListener> m_ListenerCollection;
+
+    private Integer m_ID = 1;
+    private Protocol m_Protocol;
+    private BlockingQueue<Frame> m_BlockQueueSendFrames;
+    private BlockingQueue<Frame> m_BlockQueueRecvFrames;
+    private SendFrameThread m_SendFrameThread = null;
+    private RecvFrameThread m_RecvFrameThread = null;
+    private volatile boolean m_bStopSendFrameThread = true;
+    private volatile boolean m_bStopRecvFrameThread = true;
+
+    public CommSerial(InputStream in, OutputStream out) {
+        m_ListenerCollection = new HashSet<>();
+        m_InStream = in;
+        m_OutStream = out;
+        initProtocol();
+        startReadThread();
+    }
+
+    public void Release() {
+        stopReadThread();
+
+        m_InStream = null;
+        m_OutStream = null;
+
+        if (m_Protocol != null) stopFrameThread();
+        m_ListenerCollection.clear();
+    }
+
+    public void SendData(byte[] btArySendData) {
+
+        try {
+            synchronized (m_OutStream) {
+                m_OutStream.write(btArySendData);
+                Logger.debug("S: " + TypeConverter.byteArray2HexStr(btArySendData));
+                notifyDataTransferEvent(btArySendData, CommSerial.TransferDataDirectionEnum.Send);
+                //test();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private byte[] RecvData() {
+        byte[] btAryBuffer = new byte[4096];
+        byte[] btAryReceiveData = null;
+
+        try {
+            int nLenRead = m_InStream.read(btAryBuffer);
+            //Logger.debug( "ReadLen: " + String.valueOf(nLenRead));
+            if (nLenRead > 0) {
+                btAryReceiveData = new byte[nLenRead];
+                System.arraycopy(btAryBuffer, 0, btAryReceiveData, 0, nLenRead);
+                Logger.debug( "R: " + TypeConverter.byteArray2HexStr(btAryReceiveData));
+                notifyDataTransferEvent(btAryReceiveData, CommSerial.TransferDataDirectionEnum.Receive);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return btAryReceiveData;
+    }
+
+//    public void SendProtocolMessage(int id, int type, String cmd, byte[] data) {
+//        if (m_Protocol != null) SendData(m_Protocol.encode(id, type, cmd, data));
+//    }
+
+    private class ReadThread extends Thread {
+        @Override
+        public void run() {
+            super.run();
+
+            while ((!isInterrupted()) && (!m_bStopReadThread)) {
+                byte[] btAryReceiveData = RecvData();
+                if (m_Protocol != null && btAryReceiveData != null) m_Protocol.collect(btAryReceiveData);
+            }
+        }
+    }
+
+    private void startReadThread() {
+        m_bStopReadThread = false;
+        if (m_ReadThread == null) {
+            m_ReadThread = new ReadThread();
+            m_ReadThread.start();
+        }
+    }
+
+    private void stopReadThread() {
+        m_bStopReadThread = true;
+        if (m_ReadThread != null) {
+            m_ReadThread.interrupt();
+            try {
+                m_ReadThread.join();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public void AddListenner(ICommSerialEventListener listener) {
+        m_ListenerCollection.add(listener);
+    }
+
+    public void RemoveListener(ICommSerialEventListener listener) {
+        m_ListenerCollection.remove(listener);
+    }
+
+    public interface ICommSerialEventListener {
+        void onTransferDataEvent(byte[] transferData, CommSerial.TransferDataDirectionEnum direction, Date time);
+        void onResponseEvent(byte[] result, ProtocolCMDEnum cmd);
+        void onReportEvent(byte[] value, ProtocolCMDEnum cmd);
+    }
+
+    private static enum EventTypeEnum {
+        TransferData,
+        ResponseData,
+        ReportData
+    }
+
+    private void notifyListener(Object event, EventTypeEnum eventType) {
+        synchronized (m_ListenerCollection) {
+            for (ICommSerialEventListener lis : m_ListenerCollection) {
+                if (eventType == EventTypeEnum.TransferData) {
+                    CommSerialdDataTransferEventObject eventObject = (CommSerialdDataTransferEventObject)event;
+                    lis.onTransferDataEvent(eventObject.getTransferData(), eventObject.getDirection(), eventObject.getTime());
+                } else if (eventType == EventTypeEnum.ResponseData) {
+                    CommSerialCMDControlEventObject eventObject = (CommSerialCMDControlEventObject)event;
+                    lis.onResponseEvent(eventObject.getResult(), eventObject.getProtocolCMD());
+                } else if (eventType == EventTypeEnum.ReportData) {
+                    CommSerialProtocolReportEventObject eventObject = (CommSerialProtocolReportEventObject)event;
+                    lis.onReportEvent(eventObject.getValue(), eventObject.getProtocolCMD());
+                }
+            }
+        }
+    }
+
+    private void notifyDataTransferEvent(byte[] transferData, CommSerial.TransferDataDirectionEnum direction) {
+        notifyListener(new CommSerialdDataTransferEventObject(this, transferData, direction, new Date()), EventTypeEnum.TransferData);
+    }
+
+    private void notifyCMDControlProtocolEvent(byte[] result, ProtocolCMDEnum protocolCMD) {
+        notifyListener(new CommSerialCMDControlEventObject(this, result, protocolCMD), EventTypeEnum.ResponseData);
+    }
+
+    private void notifyCMDReportProtocolEvent(byte[] value, ProtocolCMDEnum protocolCMD) {
+        notifyListener(new CommSerialProtocolReportEventObject(this, value, protocolCMD), EventTypeEnum.ReportData);
+    }
+
+    public static enum TransferDataDirectionEnum {
+        Send,
+        Receive
+    }
+
+    public class CommSerialdDataTransferEventObject extends EventObject {
+        private byte[] transferData = null;
+        private CommSerial.TransferDataDirectionEnum direction;
+        private Date time;
+
+        public CommSerialdDataTransferEventObject(Object source,
+                                                  byte[] transferData,
+                                                  CommSerial.TransferDataDirectionEnum direction,
+                                                  Date time) {
+            super(source);
+
+            this.transferData = transferData;
+            this.direction = direction;
+            this.time = time;
+        }
+
+        public byte[] getTransferData() {
+            return this.transferData;
+        }
+
+        public CommSerial.TransferDataDirectionEnum getDirection() {
+            return this.direction;
+        }
+
+        public Date getTime() {
+            return this.time;
+        }
+    }
+
+    public static enum ProtocolCMDEnum {
+        //cmd controll
+        ControlSale,
+        ControlLight,
+        // auto report
+        EventOutGoods,
+        EventMotor,
+    }
+
+    public class CommSerialProtocolDataEventObject extends EventObject {
+        private byte[] protocolData = null;
+        private int type;
+        private String cmd;
+
+        public CommSerialProtocolDataEventObject(Object source,
+                                                 byte[] protocolData,
+                                                 int type,
+                                                 String cmd) {
+            super(source);
+
+            this.protocolData = protocolData;
+            this.type = type;
+            this.cmd = cmd;
+        }
+
+        public byte[] getProtocolData() {
+            return protocolData;
+        }
+
+        public int getType() {
+            return type;
+        }
+
+        public String getCmd() {
+            return cmd;
+        }
+    }
+
+    public class CommSerialProtocolDataMultiEventObject extends EventObject {
+        private byte[] protocolData = null;
+        int mapping;
+
+        public CommSerialProtocolDataMultiEventObject(Object source,
+                                                      byte[] protocolData,
+                                                      int mapping) {
+            super(source);
+
+            this.protocolData = protocolData;
+            this.mapping = mapping;
+        }
+
+        public byte[] getProtocolData() {
+            return protocolData;
+        }
+
+        public int getMapping() {
+            return mapping;
+        }
+    }
+
+    public class CommSerialCMDControlEventObject extends EventObject {
+        private byte[] result;
+        private ProtocolCMDEnum protocolCMD;
+
+        public CommSerialCMDControlEventObject(Object source,
+                                               byte[] result,
+                                               ProtocolCMDEnum protocolCMD) {
+            super(source);
+
+            this.result = result;
+            this.protocolCMD = protocolCMD;
+        }
+
+        public byte[] getResult() {
+            return result;
+        }
+
+        public ProtocolCMDEnum getProtocolCMD() {
+            return protocolCMD;
+        }
+    }
+
+    public class CommSerialProtocolReportEventObject extends EventObject {
+        private byte[] value;
+        private ProtocolCMDEnum protocolCMD;
+
+        public CommSerialProtocolReportEventObject(Object source,
+                                                   byte[] value,
+                                                   ProtocolCMDEnum protocolCMD) {
+            super(source);
+
+            this.value = value;
+            this.protocolCMD = protocolCMD;
+        }
+
+        public byte[] getValue() {
+            return value;
+        }
+
+        public ProtocolCMDEnum getProtocolCMD() {
+            return protocolCMD;
+        }
+    }
+
+    /**
+     * Protocol
+     */
+    private void initProtocol() {
+        int _capacity = 100;
+        ProtocolCMDEnum _cmd;
+        m_ID = new Integer(1);
+
+        m_BlockQueueSendFrames = new ArrayBlockingQueue<>(_capacity);
+        m_BlockQueueRecvFrames = new ArrayBlockingQueue<>(_capacity);
+
+        m_Protocol = new Protocol(new Protocol.IProtocolListener() {
+            @Override
+            public void OnFrameData(Frame frame) {
+                //put 如果队列满,则阻塞; offer 如果队列满,则返回false
+                try {
+                    m_BlockQueueRecvFrames.put(frame);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+
+        startFrameThread();
+    }
+
+    private void startFrameThread() {
+        m_bStopSendFrameThread = false;
+        m_bStopRecvFrameThread = false;
+        m_SendFrameThread = new SendFrameThread();
+        m_RecvFrameThread = new RecvFrameThread();
+        m_SendFrameThread.start();
+        m_RecvFrameThread.start();
+    }
+
+    private void stopFrameThread() {
+        m_bStopSendFrameThread = true;
+        m_bStopRecvFrameThread = true;
+        if (m_SendFrameThread != null) {
+            m_SendFrameThread.interrupt();
+            try {
+                m_SendFrameThread.join();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        if (m_RecvFrameThread != null) {
+            m_RecvFrameThread.interrupt();
+            try {
+                m_RecvFrameThread.join();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private ProtocolCMDEnum frameCMD2ProtocolDataCMD(String cmd) {
+        ProtocolCMDEnum _cmd = null;
+
+        switch (cmd) {
+            case Constant.CMD_CONTROL_SALE:
+                _cmd = ProtocolCMDEnum.ControlSale;
+                break;
+            case Constant.CMD_CONTROL_LIGHT:
+                _cmd = ProtocolCMDEnum.ControlLight;
+                break;
+            case Constant.CMD_EVENT_SALE:
+                _cmd = ProtocolCMDEnum.EventOutGoods;
+                break;
+            case Constant.CMD_EVENT_MOTOR:
+                _cmd = ProtocolCMDEnum.EventMotor;
+                break;
+            default:
+                break;
+        }
+
+        return _cmd;
+    }
+
+    private int getID() {
+        int _id;
+        synchronized (m_ID) {
+            _id = m_ID.intValue();
+        }
+
+        return _id;
+    }
+
+    private void setID(int id) {
+        synchronized (m_ID) {
+            m_ID = id + 1;
+        }
+    }
+
+    private void sendFrame(int type, String cmd, byte[] data) {
+        Frame _frame = new Frame();
+        _frame.ID = getID();
+        _frame.Type = type;
+        _frame.CMD = cmd;
+        _frame.Data = data;
+
+        //put 如果队列满,则阻塞; offer 如果队列满,则返回false
+        try {
+            m_BlockQueueSendFrames.put(_frame);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+    private void test(){
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                String cmd = Constant.CMD_CONTROL_SALE;
+                byte[]data = new byte[]{0x1, 0x02, 0x03};
+               /*testRecvFrame(1, cmd, data);
+                try {
+                    Thread.sleep(2000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+                cmd = Constant.CMD_EVENT_MOTOR;
+                data = new byte[]{0x1};
+                testRecvFrame(0, cmd, data);
+                try {
+                    Thread.sleep(2000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+                cmd = Constant.CMD_EVENT_SALE;
+                data = new byte[]{0x00};
+                testRecvFrame(0, cmd, data);
+                try {
+                    Thread.sleep(2000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }*/
+                cmd = Constant.CMD_CONTROL_LIGHT;
+                data = new byte[]{0x00};
+                testRecvFrame(1, cmd, data);
+            }
+        }).start();
+    }
+
+    private void testRecvFrame(int id, String cmd, byte[] data) {
+        Frame _frame = new Frame();
+        _frame.ID = id;
+        _frame.Type = Constant.TYPE_DATA;
+        _frame.CMD = cmd;
+        _frame.Data = data;
+        byte[] datas = m_Protocol.encode(_frame);
+        byte[] btAryReceiveData = testRecvData(datas);
+        if (m_Protocol != null && btAryReceiveData != null) m_Protocol.collect(btAryReceiveData);
+    }
+
+    private byte[] testRecvData(byte[] btAryReceiveData) {
+        byte[] btAryBuffer = new byte[4096];
+        int nLenRead = btAryReceiveData.length;
+        Logger.debug( "ReadLen: " + nLenRead);
+        if (nLenRead > 0) {
+            //System.arraycopy(btAryReceiveData, 0, btAryBuffer, 0, nLenRead);
+            Logger.debug( "R: " + TypeConverter.byteArray2HexStr(btAryReceiveData));
+            notifyDataTransferEvent(btAryReceiveData, CommSerial.TransferDataDirectionEnum.Receive);
+        }
+        return btAryReceiveData;
+    }
+
+
+
+    private void recvFrame(Frame frame) {
+        ProtocolCMDEnum cmd = frameCMD2ProtocolDataCMD(frame.CMD);
+        if(frame.ID != 0){
+            notifyCMDControlProtocolEvent(frame.Data, cmd);
+        }else {
+            notifyCMDReportProtocolEvent(frame.Data, cmd);
+        }
+    }
+
+    private class SendFrameThread extends Thread {
+        @Override
+        public void run() {
+            super.run();
+
+            while ((!isInterrupted()) && (!m_bStopSendFrameThread)) {
+                try {
+                    //poll 如果队列为空,则返回null; take 如果队列为空,则阻塞
+                    SendData(m_Protocol.encode(m_BlockQueueSendFrames.take()));
+                    //Log.d(TAG, "SendData");
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private class RecvFrameThread extends Thread {
+        @Override
+        public void run() {
+            super.run();
+
+            while ((!isInterrupted()) && (!m_bStopRecvFrameThread)) {
+                try {
+                    //poll 如果队列为空,则返回null; take 如果队列为空,则阻塞
+                    recvFrame(m_BlockQueueRecvFrames.take());
+                    //Log.d(TAG, "recvFrame");
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
+    public void controlsale(byte x, byte y, byte num) {
+        byte[]data = new byte[3];
+        data[0] = x;
+        data[1] = y;
+        data[2] = num;
+        sendFrame(Constant.TYPE_DATA, Constant.CMD_CONTROL_SALE, data);
+    }
+
+    public void controlLight(byte controlCmd) {
+        byte[] data = {controlCmd};
+        sendFrame(Constant.TYPE_DATA, Constant.CMD_CONTROL_LIGHT, data);
+    }
+
+}
+

+ 164 - 0
app/src/main/java/com/ifastore/goodsmanage/serialport/CommTask.java

@@ -0,0 +1,164 @@
+package com.ifastore.goodsmanage.serialport;
+
+
+import android.content.Context;
+import android.content.Intent;
+import android.icu.text.SimpleDateFormat;
+import com.ifastore.goodsmanage.utils.Logger;
+import com.ifastore.goodsmanage.utils.TypeConverter;
+import com.reduxsolutions.serialport.drivers.SerialPort;
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import static com.ifastore.goodsmanage.common.Constants.REPORT_EVENT_GOODS;
+import static com.ifastore.goodsmanage.common.Constants.REPORT_EVENT_MOTOR;
+import static com.ifastore.goodsmanage.common.Constants.RESULT_CONTROL_LIGHT;
+import static com.ifastore.goodsmanage.common.Constants.RESULT_CONTROL_SALE;
+
+
+public class CommTask{
+    private static final String TAG = CommTask.class.getSimpleName();
+
+    private SerialPort serialPort = null;
+    private CommSerial commSerial = null;
+    private ISerialEventListener listener;
+    private static CommTask commTask;
+    private Context context;
+    public boolean isopen = true;
+
+    private CommTask(Context ctx, String serial, int baute) {
+        try {
+            context = ctx;
+            serialPort = new SerialPort(new File(serial),baute, 0);
+            Logger.debug("serialport:"+serial +" " +"baute:"+baute);
+        } catch (IOException e) {
+            e.printStackTrace();
+            isopen = false;
+            return;
+        }
+        isopen = true;
+        commSerial = new CommSerial(serialPort.getInputStream(), serialPort.getOutputStream());
+        commSerial.AddListenner(new CommSerial.ICommSerialEventListener() {
+
+            @Override
+            public void onTransferDataEvent(byte[] transferData, CommSerial.TransferDataDirectionEnum direction, Date time) {
+                String data = TypeConverter.byteArray2HexStr(transferData);
+                SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd hh:mm:ss");
+                Logger.debug(time.toString());
+                String dataTime = format.format(time);
+                if(CommSerial.TransferDataDirectionEnum.Receive == direction){
+                    listener.transferDataRecv(dataTime+" "+data);
+                    Logger.debug("recv:"+data);
+                }else {
+                    listener.transferDataSend(dataTime+" "+data);
+                    Logger.debug("send:"+data);
+                }
+            }
+
+            @Override
+            public void onResponseEvent(byte[] value, CommSerial.ProtocolCMDEnum cmd) {
+                switch (cmd){
+                    case ControlSale:
+                        resultSaleGoods(RESULT_CONTROL_SALE, value);
+                        break;
+                    case ControlLight:
+                        resultLight(RESULT_CONTROL_LIGHT, value);
+                        break;
+                }
+            }
+
+            @Override
+            public void onReportEvent(byte[] value, CommSerial.ProtocolCMDEnum cmd) {
+                switch (cmd){
+                    case EventOutGoods:
+                        resultOutGoods(REPORT_EVENT_GOODS, value);
+                        break;
+                    case EventMotor:
+                        resultLight(REPORT_EVENT_MOTOR, value);
+                        break;
+                }
+            }
+        });
+    }
+
+    public void addListener(ISerialEventListener listener){
+        if(listener != null){
+            this.listener = listener;
+        }
+    }
+
+    public void saleGoods(byte x, byte y, byte num) {
+        if(commTask.isopen){
+            commSerial.controlsale(x, y , num);
+        }
+        //byte[] test = {0,    0x1,   1, 1, 0, 0,  0x2,  1, 0, 1, 0,      0x3,   1, 0, 0, 1,     0x4,   1, 0, 0, 1};
+        //byte[] test = {1,    0x1,   2, 1, 3, 0,  4,  1, 5, 1,6,     1,  7,   1, 8, 0,9,     0x4,   0xA, 0, 0xB, 1};
+    }
+    public void controlLight(byte cmd) {
+        if(commTask.isopen){
+            commSerial.controlLight(cmd);
+        }
+        //byte[] test = {0,    0x1,   1, 1, 0, 0,  0x2,  1, 0, 1, 0,      0x3,   1, 0, 0, 1,     0x4,   1, 0, 0, 1};
+        //byte[] test = {1,    0x1,   2, 1, 3, 0,  4,  1, 5, 1,6,     1,  7,   1, 8, 0,9,     0x4,   0xA, 0, 0xB, 1};
+    }
+
+    public static CommTask openSerialport(Context ctx, String serial, int baute){
+        if(commTask != null){
+            if(!commTask.isopen){
+                commTask = new CommTask(ctx, serial, baute);
+            }
+        }else {
+            commTask = new CommTask(ctx, serial, baute);
+        }
+        return commTask;
+    }
+
+    public static  void closeSerialPort(){
+        if(commTask !=null){
+            if(commTask.commSerial != null){
+                commTask.commSerial.Release();
+            }
+            if(commTask.serialPort!=null){
+                commTask.serialPort.Close();
+            }
+            commTask.commSerial = null;
+            commTask.serialPort = null;
+            commTask = null;
+        }
+    }
+    /*
+    * 1. open door result contatin status
+    * 2. close door result without status
+    * 3. weight real time report  without status
+    * 4. auto  get real weight  result without status
+    * */
+    private void resultSaleGoods(String action,  byte[] result){
+        int res = -1;
+        if(result.length>0) res = result[0];
+        Intent intent = new Intent(action);
+        intent.putExtra(action, res);
+        context.sendBroadcast(intent);
+    }
+
+
+    private void resultLight(String action, byte[] result){
+        int res = -1;
+        if(result.length>0) res = result[0];
+        Intent intent = new Intent(action);
+        intent.putExtra(action, res);
+        context.sendBroadcast(intent);
+    }
+
+    private void resultOutGoods(String action, byte[] result){
+        int res = -1;
+        if(result.length>0) res = result[0];
+        Intent intent = new Intent(action);
+        intent.putExtra(action, res);
+        context.sendBroadcast(intent);
+    }
+
+    public interface ISerialEventListener {
+        void transferDataSend(String data);
+        void transferDataRecv(String data);
+    }
+}

+ 20 - 0
app/src/main/java/com/ifastore/goodsmanage/serialport/protocol/Constant.java

@@ -0,0 +1,20 @@
+package com.ifastore.goodsmanage.serialport.protocol;
+
+public class Constant {
+    public static final int TYPE_DATA =                 (byte) 0x01;
+    public static final int TYPE_DATA_FOLLOW =          (byte) 0x81;
+    public static final int TYPE_ACK =                  (byte) 0x06;
+    public static final int TYPE_NAK =                  (byte) 0x13;
+    public static final int TYPE_DATA_MULTI =           (byte) 0xF1;
+    //control
+    public static final String CMD_CONTROL_SALE =      "SA";
+    public static final String CMD_CONTROL_LIGHT=      "UL";
+
+    //event upload
+    public static final String CMD_EVENT_SALE   =      "SE";
+    public static final String CMD_EVENT_MOTOR  =      "MA";
+
+
+
+
+}

+ 11 - 0
app/src/main/java/com/ifastore/goodsmanage/serialport/protocol/Frame.java

@@ -0,0 +1,11 @@
+package com.ifastore.goodsmanage.serialport.protocol;
+
+public class Frame {
+    /** ID1 TYPE1 (LEN2) CMD2 DATAn CRC162*/
+    public int ID;
+    public int Type;
+    //private int Len;
+    public String CMD;
+    public byte[] Data = new byte[0];
+    public int CRC16;
+}

+ 274 - 0
app/src/main/java/com/ifastore/goodsmanage/serialport/protocol/Protocol.java

@@ -0,0 +1,274 @@
+package com.ifastore.goodsmanage.serialport.protocol;
+
+
+import com.ifastore.goodsmanage.utils.Logger;
+
+public class Protocol {
+
+    private static final byte B_SOF =       (byte) 0xC0;
+    private static final byte B_EOF =       (byte) 0xC1;
+    private static final byte B_TRANSFER =  (byte) 0x7D;
+    private static final byte B_XOR =       (byte) 0x20;
+
+    /** 0xC0 ID:1 TYPE:1 CMD:2 DATA:n CRC16:2 0xC1 */
+    private static final int BUFFER_LENGTH_MIN = 8;
+
+    private static final int OFFSET_SOF = 0;
+    private static final int OFFSET_R_EOF = -1;
+    private static final int OFFSET_ID = 1;
+    private static final int OFFSET_TYPE = 2;
+    private static final int OFFSET_CMD_H = 3;
+    private static final int OFFSET_CMD_L = 4;
+    private static final int OFFSET_DATA = 5;
+    private static final int OFFSET_R_CRC16_H = -2;
+    private static final int OFFSET_R_CRC16_L = -3;
+
+    // private Frame mEncodeFrame;
+    // private Frame mDecodeFrame = new Frame();
+
+    private byte[] mDecodedBuffer = new byte[0];
+    private byte[] mEncodedBuffer = new byte[0];
+    private int mDecodedBufferLength = 0;
+    private int mEncodedBufferLength = 0;
+    private boolean isStart = false;
+    private boolean isEnd = true;
+    private boolean isTransfer = false;
+
+    private IProtocolListener mProtocolListener;
+
+
+//    private static final int MODE_1Q1A = 1;
+//    private static final int MODE_1QNA = 2;
+//    private static final int MODE_RT_SCAN = 3;
+
+//    private int mID = 1;
+//    private int mMode = MODE_1Q1A;
+
+    public boolean mDebug = false;
+
+
+    /** byte[] to hex String  */
+    private String byte2hex(byte[] buffer) {
+        String hexStr = "";
+
+        for (byte aBuffer : buffer) {
+            String tmp = Integer.toHexString((aBuffer & 0xFF));
+            if (tmp.length() == 1) tmp = "0" + tmp;
+
+            hexStr = hexStr + " " + tmp;
+        }
+
+        return hexStr;
+    }
+
+    /** CRC16 */
+    public int CalculateCRC16(byte[] buffer, int start, int end) {
+        int crc16_preset = 0xFFFF;
+        int RFCRC16_POLYNOM = 0x8408;
+
+        int CRC16 = crc16_preset;
+        for (int m = start; m < end; m++) {
+            CRC16 ^= (buffer[m] & 0xff);
+
+            for (int n = 0; n < 8; n++) {
+                if ((CRC16 & 0x0001) > 0)
+                    CRC16 = ((CRC16 >> 1) ^ RFCRC16_POLYNOM);
+                else
+                    CRC16 = (CRC16 >> 1);
+            }
+        }
+
+        return CRC16;
+    }
+
+    /** initialize */
+    public void initialize() {
+//        mDecodedBuffer = new byte[0];
+//        mEncodedBuffer = new byte[0];
+        mDecodedBufferLength = 0;
+        mEncodedBufferLength = 0;
+//        isStart = false;
+//        isEnd = true;
+//        isTransfer = false;
+    }
+
+    public byte[] encode(Frame frame) {
+        return encode(frame.ID, frame.Type, frame.CMD, frame.Data);
+    }
+
+    /** Frame encoding process */
+    public byte[] encode(int id, int type, String cmd, byte[] data) {
+
+        int _Length = BUFFER_LENGTH_MIN;
+
+        // 0.create buffer
+        if (data != null && data.length > 0) _Length += data.length;
+        byte[] _buffer = new byte[_Length];
+
+        // set SOF ID TYPE EOF
+        _buffer[OFFSET_SOF] = B_SOF;
+        _buffer[OFFSET_ID] = (byte) id;
+        _buffer[OFFSET_TYPE] = (byte) type;
+        _buffer[_Length + OFFSET_R_EOF] = B_EOF;
+
+        // 1.set CMD
+        byte[] _cmd = cmd.getBytes();
+        System.arraycopy(_cmd, 0, _buffer, OFFSET_CMD_H, 2);
+        if (mDebug) Logger.debug( String.format("cmd: [%x][%x] %d", (int)_cmd[0], (int)_cmd[1], _cmd.length));
+        // 2.set DATA
+        if (data != null && data.length > 0) System.arraycopy(data, 0, _buffer, OFFSET_DATA, data.length);
+
+        // 3.set CRC16
+        int _crc16 = CalculateCRC16(_buffer, OFFSET_ID, (_Length + OFFSET_R_CRC16_L));
+        _buffer[_Length + OFFSET_R_CRC16_L] =  (byte) _crc16;
+        _buffer[_Length + OFFSET_R_CRC16_H] =  (byte) (_crc16 >> 8);
+
+        if (mDebug) Logger.debug( byte2hex(_buffer) + String.format("[crc16: %x]", _crc16));
+
+        // 4.encode
+        mEncodedBufferLength = 0;
+        for (int i = 1; i <_Length - 1; i++) {
+            // count escape bytes
+            if (_buffer[i] == B_SOF || _buffer[i] == B_EOF || _buffer[i] == B_TRANSFER) mEncodedBufferLength++;
+        }
+
+        mEncodedBufferLength += _Length;
+        mEncodedBuffer = new byte[mEncodedBufferLength];
+        if (mEncodedBufferLength != _Length) {
+
+            mEncodedBuffer[OFFSET_SOF] = B_SOF;
+            mEncodedBuffer[mEncodedBufferLength + OFFSET_R_EOF] = B_EOF;
+
+            int j = 1;
+            for (int i = j; i <_Length - 1; i++) {
+                if (_buffer[i] == B_SOF || _buffer[i] == B_EOF || _buffer[i] == B_TRANSFER) {
+                    mEncodedBuffer[j++] = B_TRANSFER;
+                    mEncodedBuffer[j++] = (byte) (_buffer[i] ^ B_XOR);
+                } else {
+                    mEncodedBuffer[j++] = _buffer[i];
+                }
+            }
+
+        } else {
+            System.arraycopy(_buffer, 0, mEncodedBuffer, 0, mEncodedBufferLength);
+        }
+
+        if (mDebug) Logger.debug( byte2hex(mEncodedBuffer));
+
+        return mEncodedBuffer;
+    }
+
+    /** Stream collecting process */
+    public int collect(byte[] buffer) {
+        Frame _frame;
+
+        // 0.stream mode: create new buffer
+        if (buffer.length > (mDecodedBuffer.length - mDecodedBufferLength)) {
+            byte [] _bufferBK = mDecodedBuffer;
+            mDecodedBuffer = new byte[buffer.length + mDecodedBufferLength];
+            System.arraycopy(_bufferBK, 0, mDecodedBuffer, 0, _bufferBK.length);
+        }
+
+        if (mDebug) Logger.debug( String.format("srcLen=%d, decodeBufLen=%d, decodeLen=%d",
+                buffer.length, mDecodedBuffer.length, mDecodedBufferLength));
+
+        // 1.scanning buffer: check SOF & EOF
+        for (byte aBuffer : buffer) {
+            // 1.1 start Frame
+            if (aBuffer == B_SOF && !isStart) {
+                isStart = true;
+                mDecodedBufferLength = 0;
+                int _size = buffer.length > BUFFER_LENGTH_MIN ? buffer.length : BUFFER_LENGTH_MIN;
+                mDecodedBuffer = new byte[_size];
+            }
+
+            if (isStart) {
+                if (!isTransfer) {
+                    // need escape
+                    if (aBuffer == B_TRANSFER) {
+                        isTransfer = true;
+                        continue;
+                    }
+
+                    mDecodedBuffer[mDecodedBufferLength++] = aBuffer;
+
+                    // end Frame
+                    if (aBuffer == B_EOF) {
+                        isEnd = true;
+                        isStart = false;
+
+                        // decoding
+                        if (mDebug) Logger.debug( byte2hex(mDecodedBuffer));
+                        _frame = decode(mDecodedBuffer, mDecodedBufferLength);
+
+                        if (_frame != null) mProtocolListener.OnFrameData(_frame);
+                    }
+
+                } else {
+                    isTransfer = false;
+                    mDecodedBuffer[mDecodedBufferLength++] = (byte) (aBuffer ^ B_XOR);
+                }
+            }
+        }
+
+        if (!isEnd)
+            return -1;
+        return 0;
+    }
+
+    /** Frame decode process */
+    private Frame decode(byte[] buffer, int len) {
+        Frame _frame = new Frame();
+
+        // 1.buffer to Frame
+        if (len < BUFFER_LENGTH_MIN) {
+            Logger.error( String.format("Illegal length => %d", len));
+            return null;    //非法长度
+        }
+        _frame.ID = buffer[OFFSET_ID] & 0xFF;
+        _frame.Type = buffer[OFFSET_TYPE] & 0xFF;
+        byte[] _cmd = new byte[2];
+        _cmd[0] = buffer[OFFSET_CMD_H];
+        _cmd[1] = buffer[OFFSET_CMD_L];
+        _frame.CMD = new String(_cmd);
+        if (len > BUFFER_LENGTH_MIN) {
+            byte[] _data = new byte[len - BUFFER_LENGTH_MIN];
+            System.arraycopy(buffer, OFFSET_DATA, _data, 0, _data.length);
+            _frame.Data = _data;
+        }
+        _frame.CRC16 = (buffer[len + OFFSET_R_CRC16_L] & 0xFF);
+        _frame.CRC16 += ((buffer[len + OFFSET_R_CRC16_H] << 8) & 0xFF00);
+
+        // 2.check id
+//        if (mDecodeFrame.ID != 0) {
+//
+//            //if (mID + 1 > 255)
+//
+//            if (mDecodeFrame.ID != (mID + 1)) {
+//                Log.e(TAG, String.format("ID is not continuous => %d(%d + 1)", mDecodeFrame.ID, mID));
+//                //return 2; //ID号不连续
+//            }
+//        } else {
+//            //Mode3 ID=0
+//        }
+
+        // 3.check crc
+        int _crc16 = CalculateCRC16(buffer, OFFSET_ID, (len + OFFSET_R_CRC16_L));
+        if (_frame.CRC16 != _crc16) {
+            Logger.error(String.format("CRC16 check error => %x(%x)", _frame.CRC16, _crc16));
+            //return 3; //CRC错误
+        }
+
+        return _frame; //正常一帧
+    }
+
+    public Protocol(IProtocolListener listener) {
+        if (mProtocolListener == null) {
+            mProtocolListener = listener;
+        }
+    }
+
+    public interface IProtocolListener {
+        void OnFrameData(Frame frame);
+    }
+}

+ 131 - 0
app/src/main/java/com/ifastore/goodsmanage/utils/Logger.java

@@ -0,0 +1,131 @@
+package com.ifastore.goodsmanage.utils;
+
+import android.util.Log;
+
+/**
+ * Created by zxd on 17-7-18.<br/>
+ */
+
+public class Logger {
+
+    public static int level = Log.DEBUG;
+
+    public static boolean isDebug() {
+        return level <= Log.DEBUG;
+    }
+
+    public static void setLevel(int level) {
+        Logger.level = level;
+    }
+
+    public static void debug(String msg) {
+
+        if (level <= Log.DEBUG) {
+            Log.d(createTag(), msg);
+        }
+    }
+
+    public static void debug(String msg, Throwable tr) {
+
+        if (level <= Log.DEBUG) {
+            Log.d(createTag(), msg, tr);
+        }
+    }
+
+    public static void debug(String msg, Object... args) {
+
+        if (level <= Log.DEBUG) {
+            Log.d(createTag(), String.format(msg, args));
+        }
+    }
+
+    public static void info(String msg) {
+
+        if (level <= Log.INFO) {
+            Log.i(createTag(), msg);
+        }
+    }
+
+    public static void info(String msg, Throwable tr) {
+
+        if (level <= Log.INFO) {
+            Log.i(createTag(), msg, tr);
+        }
+    }
+
+    public static void info(String msg, Object... args) {
+
+        if (level <= Log.INFO) {
+            Log.i(createTag(), String.format(msg, args));
+        }
+    }
+
+    public static void warn(String msg) {
+
+        if (level <= Log.WARN) {
+            Log.w(createTag(), msg);
+        }
+    }
+
+    public static void warn(String msg, Throwable tr) {
+
+        if (level <= Log.WARN) {
+            Log.w(createTag(), msg, tr);
+        }
+    }
+
+    public static void warn(String msg, Object... args) {
+
+        if (level <= Log.WARN) {
+            Log.w(createTag(), String.format(msg, args));
+        }
+    }
+
+    public static void error(String msg) {
+
+        if (level <= Log.ERROR) {
+            Log.e(createTag(), msg);
+        }
+    }
+
+    public static void error(String msg, Throwable tr) {
+
+        if (level <= Log.ERROR) {
+            Log.e(createTag(), msg, tr);
+        }
+    }
+
+    public static void exception(Throwable tr) {
+        if (level <= Log.ERROR) {
+            Log.e(createTag(), tr.getClass().getSimpleName(), tr);
+        }
+    }
+
+    public static void error(String msg, Object... args) {
+
+        if (level <= Log.ERROR) {
+            Log.e(createTag(), String.format(msg, args));
+        }
+    }
+
+    private static String createTag() {
+
+        StackTraceElement[] sts = Thread.currentThread().getStackTrace();
+        if (sts == null) {
+            return null;
+        }
+        for (StackTraceElement st : sts) {
+            if (st.isNativeMethod()) {
+                continue;
+            }
+            if (st.getClassName().equals(Thread.class.getName())) {
+                continue;
+            }
+            if (st.getClassName().equals(Logger.class.getName())) {
+                continue;
+            }
+            return st.getLineNumber() + ":" + st.getFileName();
+        }
+        return "";
+    }
+}

+ 146 - 0
app/src/main/java/com/ifastore/goodsmanage/utils/TypeConverter.java

@@ -0,0 +1,146 @@
+package com.ifastore.goodsmanage.utils;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class TypeConverter {
+    private static final char[] mChars = "0123456789ABCDEF".toCharArray();
+
+    public static List<Byte> byteArray2ByteList(byte[] byteArray) {
+        if (byteArray == null) {
+            return null;
+        } else {
+            List<Byte> retList = new ArrayList();
+            byte[] btArray = byteArray;
+            int len = byteArray.length;
+
+            for(int i = 0; i < len; ++i) {
+                byte b = btArray[i];
+                retList.add(new Byte(b));
+            }
+
+            return retList;
+        }
+    }
+
+    public static byte[] ByteList2byteArray(List<Byte> ByteList) {
+        if (ByteList == null) {
+            return null;
+        } else if (ByteList.size() == 0) {
+            return null;
+        } else {
+            byte[] retArray = new byte[ByteList.size()];
+            int i = 0;
+
+            for(Iterator it = ByteList.iterator(); it.hasNext(); ++i) {
+                Byte B = (Byte)it.next();
+                retArray[i] = B;
+            }
+
+            return retArray;
+        }
+    }
+
+    public static byte[] ByteList2byteArray(List<Byte> ByteList, int Start, int Len) {
+        if (ByteList == null) {
+            return null;
+        } else if (ByteList.size() == 0) {
+            return null;
+        } else {
+            byte[] retArray = new byte[Len];
+
+            for(int i = Start; i < Start + Len; ++i) {
+                retArray[i - Start] = (Byte)ByteList.get(i);
+            }
+
+            return retArray;
+        }
+    }
+
+    public static String byteArray2HexStr(byte[] byteArray, int iStart, int iLen) {
+        if (byteArray == null) {
+            return "";
+        } else {
+            StringBuilder sb = new StringBuilder();
+
+            for(int n = iStart; n < iLen; ++n) {
+                sb.append(mChars[(byteArray[n] & 255) >> 4]);
+                sb.append(mChars[byteArray[n] & 15]);
+            }
+
+            return sb.toString().trim().toUpperCase();
+        }
+    }
+
+    public static String byteArray2HexStr(byte[] byteArray) {
+        return byteArray == null ? "" : byteArray2HexStr(byteArray, 0, byteArray.length);
+    }
+
+    public static byte[] HexStr2byteArray(String strHex) {
+        if (strHex.length() == 0) {
+            return null;
+        } else {
+            try {
+                strHex = strHex.toLowerCase().replace(" ", "");
+                byte[] byteArray = new byte[strHex.length() / 2];
+                int k = 0;
+
+                for(int i = 0; i < byteArray.length; ++i) {
+                    byte high = (byte)(Character.digit(strHex.charAt(k), 16) & 255);
+                    byte low = (byte)(Character.digit(strHex.charAt(k + 1), 16) & 255);
+                    byteArray[i] = (byte)(high << 4 | low);
+                    k += 2;
+                }
+
+                return byteArray;
+            } catch (Exception e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
+    }
+
+    public static byte[] DecStr2BCDByteArray(String strDec) {
+        int len = strDec.length();
+        int mod = len % 2;
+        if (mod != 0) {
+            strDec = "0" + strDec;
+            len = strDec.length();
+        }
+
+        byte[] abt = new byte[len];
+        if (len >= 2) {
+            len /= 2;
+        }
+
+        byte[] bbt = new byte[len];
+        abt = strDec.getBytes();
+
+        for(int p = 0; p < strDec.length() / 2; ++p) {
+            int j;
+            if (abt[2 * p] >= 48 && abt[2 * p] <= 57) {
+                j = abt[2 * p] - 48;
+            } else if (abt[2 * p] >= 97 && abt[2 * p] <= 122) {
+                j = abt[2 * p] - 97 + 10;
+            } else {
+                j = abt[2 * p] - 65 + 10;
+            }
+
+            int k;
+            if (abt[2 * p + 1] >= 48 && abt[2 * p + 1] <= 57) {
+                k = abt[2 * p + 1] - 48;
+            } else if (abt[2 * p + 1] >= 97 && abt[2 * p + 1] <= 122) {
+                k = abt[2 * p + 1] - 97 + 10;
+            } else {
+                k = abt[2 * p + 1] - 65 + 10;
+            }
+
+            int a = (j << 4) + k;
+            byte b = (byte)a;
+            bbt[p] = b;
+        }
+
+        return bbt;
+    }
+}

+ 14 - 0
app/src/main/res/anim/alpha.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator"
+    android:shareInterpolator="true">
+
+    <alpha
+        android:fromAlpha="0.3"
+        android:toAlpha="1.0"
+        android:duration="200"
+        android:repeatCount="infinite"
+        >
+    </alpha>
+
+</set>

+ 30 - 0
app/src/main/res/drawable-v24/ic_launcher_foreground.xml

@@ -0,0 +1,30 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="85.84757"
+                android:endY="92.4963"
+                android:startX="42.9492"
+                android:startY="49.59793"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+</vector>

+ 13 - 0
app/src/main/res/drawable/bg_account_shape.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+	>
+    <corners android:radius="10dp"/>
+	<stroke android:width="5dp" android:color="@color/theme_secondary_text_inverted"/>
+	<solid android:color="@color/white"/>
+	<padding
+		android:right="5dp"
+		android:left="5dp"
+		android:top="5dp"
+		android:bottom="5dp">
+	</padding>
+</shape>

+ 5 - 0
app/src/main/res/drawable/bg_btn_button.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/bg_btn_press" />
+    <item android:drawable="@drawable/bg_btn_normal"/>
+</selector>

+ 8 - 0
app/src/main/res/drawable/bg_btn_normal.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/holo_blue_light"/>
+    <corners android:topLeftRadius="10dp"
+        android:topRightRadius="10dp"
+        android:bottomRightRadius="10dp"
+        android:bottomLeftRadius="10dp"/>
+</shape>

+ 8 - 0
app/src/main/res/drawable/bg_btn_press.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#cc303F9F" />
+    <corners android:topLeftRadius="10dp"
+        android:topRightRadius="10dp"
+        android:bottomRightRadius="10dp"
+        android:bottomLeftRadius="10dp"/>
+</shape>

+ 8 - 0
app/src/main/res/drawable/bg_spin_goods.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/github_con_1"/>
+    <corners android:topLeftRadius="10dp"
+        android:topRightRadius="10dp"
+        android:bottomRightRadius="10dp"
+        android:bottomLeftRadius="10dp"/>
+</shape>

+ 8 - 0
app/src/main/res/drawable/bg_spin_normal.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/github_con_2"/>
+    <corners android:topLeftRadius="10dp"
+        android:topRightRadius="10dp"
+        android:bottomRightRadius="10dp"
+        android:bottomLeftRadius="10dp"/>
+</shape>

+ 8 - 0
app/src/main/res/drawable/bg_spin_press.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/tab_checked" />
+    <corners android:topLeftRadius="10dp"
+        android:topRightRadius="10dp"
+        android:bottomRightRadius="10dp"
+        android:bottomLeftRadius="10dp"/>
+</shape>

+ 5 - 0
app/src/main/res/drawable/bg_spinner.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/bg_spin_normal" />
+    <item android:drawable="@drawable/bg_spin_press"/>
+</selector>

+ 170 - 0
app/src/main/res/drawable/ic_launcher_background.xml

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillColor="#3DDC84"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+</vector>

+ 175 - 0
app/src/main/res/layout-land/activity_main.xml

@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".MainActivity">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="2"
+        android:background="@color/holo_blue_light"
+        >
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:textColor="@color/github_con_0"
+            android:layout_marginStart="1dp"
+            android:textSize="30sp"
+            android:text="日志">
+
+        </TextView>
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center"
+            >
+            <RelativeLayout
+                android:id="@+id/logLayout"
+                android:layout_width="1000dp"
+                android:layout_height="400dp"
+                android:fadeScrollbars="false"
+                android:scrollbars="vertical"
+                android:gravity="center"
+                android:textColor="#000000"
+                android:textSize="80sp"
+                android:background="@drawable/bg_account_shape">
+                <ListView
+                    android:id="@+id/listLog"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:stackFromBottom="false"
+                    android:transcriptMode="alwaysScroll"
+                    android:visibility="invisible"
+                    >
+
+                </ListView>
+
+            </RelativeLayout>
+        </RelativeLayout>
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:background="@color/holo_blue_light"
+        android:layout_weight="1"
+        android:layout_height="0dp"
+
+        >
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:layout_marginStart="1dp"
+            android:textSize="30sp"
+            android:textColor="@color/github_con_0"
+            android:text="控制"
+            android:layout_alignParentTop="true"
+            >
+        </TextView>
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center"
+            >
+            <RelativeLayout
+                android:id="@+id/operate"
+                android:layout_width="800dp"
+                android:background="@drawable/bg_account_shape"
+                android:layout_height="match_parent"
+                android:gravity="center"
+                android:layout_centerVertical="true">
+                <Spinner
+                    android:id="@+id/serial"
+                    android:layout_width="150dp"
+                    android:layout_marginTop="0dp"
+                    android:layout_height="70dp"
+                    style="@style/Spinner"
+                    android:gravity="center"
+                    android:background="@drawable/bg_spin_normal"
+                    />
+                <Spinner
+                    android:id="@+id/baute"
+                    android:gravity="center"
+                    android:layout_width="150dp"
+                    android:layout_height="70dp"
+                    android:layout_marginTop="0dp"
+                    android:layout_toEndOf="@id/serial"
+                    android:background="@drawable/bg_spin_normal"
+                    style="@style/Spinner"
+                    android:layout_marginStart="60dp" />
+
+                <Button
+                    android:id="@+id/openSerial"
+                    android:background="@drawable/bg_btn_button"
+                    android:text="@string/openserial"
+                    android:layout_marginTop="0dp"
+                    android:layout_width="150dp"
+                    android:layout_height="70dp"
+                    android:layout_toEndOf="@id/baute"
+                    android:layout_marginStart="60dp"
+                    android:textSize="20sp"
+                    />
+
+                <Button
+                    android:id="@+id/closeSerial"
+                    android:background="@drawable/bg_btn_button"
+                    android:text="@string/closeSerial"
+                    android:layout_marginTop="0dp"
+                    android:layout_width="150dp"
+                    android:layout_height="70dp"
+                    android:layout_toEndOf="@id/baute"
+                    android:layout_marginStart="60dp"
+                    android:visibility="invisible"
+                    android:textSize="20sp"
+                    />
+
+                <Button
+                    android:id="@+id/controlLight"
+                    android:background="@drawable/bg_btn_button"
+                    android:text="光幕开关"
+                    android:layout_marginTop="40dp"
+                    android:layout_width="150dp"
+                    android:layout_height="70dp"
+                    android:layout_toEndOf="@+id/clearLog"
+                    android:layout_below="@id/baute"
+                    android:textSize="20sp"
+                    android:layout_marginStart="60dp"/>
+
+                <Button
+                    android:id="@+id/sale"
+                    android:background="@drawable/bg_btn_button"
+                    android:text="@string/sale"
+                    android:layout_marginTop="40dp"
+                    android:layout_below="@+id/baute"
+                    android:layout_toEndOf="@+id/controlLight"
+                    android:layout_marginStart="60dp"
+                    android:layout_width="150dp"
+                    android:layout_height="70dp"
+                    android:textSize="20sp"
+                    />
+
+
+                <Button
+                    android:id="@+id/clearLog"
+                    android:text="@string/clearLog"
+                    android:layout_width="150dp"
+                    android:layout_height="70dp"
+                    android:layout_below="@id/serial"
+                    android:textSize="20sp"
+                    android:layout_marginTop="40dp"
+                    android:background="@drawable/bg_btn_button"
+                    >
+                </Button>
+
+
+
+            </RelativeLayout>
+        </RelativeLayout>
+    </RelativeLayout>
+
+
+</LinearLayout>

+ 8 - 0
app/src/main/res/layout-land/item_layout.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:id="@+id/textView"
+    android:padding="5dp"
+    android:layout_height="wrap_content">
+
+</TextView>

+ 62 - 0
app/src/main/res/layout-land/scrollviewtest.xml

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/text_linear"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    tools:ignore="MissingDefaultResource">
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="24sp"
+                android:text="X货道:"
+                >
+            </TextView>
+            <Spinner
+                android:id="@+id/xNum"
+                android:layout_width="80dp"
+                android:layout_height="40dp"
+                android:layout_gravity="center"
+                android:background="@drawable/bg_spin_goods" />
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="24sp"
+                android:text="Y货道:"
+                >
+            </TextView>
+            <Spinner
+                android:id="@+id/yNum"
+                android:layout_width="80dp"
+                android:layout_height="40dp"
+                android:layout_gravity="center"
+                android:background="@drawable/bg_spin_goods" />
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="24sp"
+                android:text="数量:"
+                >
+            </TextView>
+            <Spinner
+                android:id="@+id/goodsNum"
+                android:layout_width="80dp"
+                android:layout_height="40dp"
+                android:layout_gravity="center"
+                android:background="@drawable/bg_spin_goods" />
+        </LinearLayout>
+
+    </ScrollView>
+
+
+</LinearLayout>

+ 168 - 0
app/src/main/res/layout-port/activity_main.xml

@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity"
+    tools:ignore="MissingDefaultResource">
+
+    <TextView
+        android:id="@+id/recvView"
+        android:layout_width="match_parent"
+        android:background="@color/colorAccent"
+        android:layout_height="300dp"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true" />
+    <Button
+        android:id="@+id/sale"
+        android:background="#009688"
+        android:text="@string/sale"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/recvView"
+        android:layout_marginStart="50dp"
+        android:layout_marginTop="30dp"
+        />
+
+    <Button
+        android:id="@+id/getVersion"
+        android:background="#009688"
+        android:text="@string/version"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/recvView"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@+id/sale"
+        android:layout_marginStart="20dp"/>
+
+    <Button
+        android:id="@+id/getTemp"
+        android:background="#009688"
+        android:text="@string/gettemp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/sale"
+        android:layout_marginStart="50dp"
+        android:layout_marginTop="30dp"
+         />
+    <Button
+        android:id="@+id/reboot"
+        android:background="#009688"
+        android:text="@string/reboot"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/getVersion"
+        android:layout_toEndOf="@id/getTemp"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="30dp"/>
+
+    <Button
+        android:id="@+id/setTemp"
+        android:background="#009688"
+        android:text="@string/settemp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/getTemp"
+        android:layout_marginTop="30dp"
+        android:layout_marginStart="50dp" />
+
+    <EditText
+        android:id="@+id/editTemp"
+        android:layout_width="88dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="20dp"
+        android:layout_toEndOf="@id/setTemp"
+        android:layout_below="@id/reboot"
+        android:layout_marginTop="30dp"
+        />
+
+    <Button
+        android:id="@+id/startDownload"
+        android:background="#009688"
+        android:text="@string/startdownload"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/recvView"
+        android:layout_marginStart="20dp"
+        android:layout_toEndOf="@id/reboot"
+        android:layout_marginTop="30dp"/>
+
+    <Button
+        android:id="@+id/firmwareTransfer"
+        android:background="#009688"
+        android:text="@string/content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="30dp"
+        android:layout_below="@id/startDownload"
+        android:layout_toEndOf="@id/reboot"
+        android:layout_marginStart="20dp"/>
+
+    <Button
+        android:id="@+id/stopDownload"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#009688"
+        android:text="@string/stopdownload"
+        android:layout_below="@id/firmwareTransfer"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@id/editTemp"
+        android:layout_marginStart="20dp"
+        />
+
+    <Button
+        android:id="@+id/getRealWeight"
+        android:background="#009688"
+        android:text="@string/getRealWeight"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="50dp"
+        android:layout_below="@id/setTemp"
+        android:layout_marginTop="30dp" />
+
+    <Button
+        android:id="@+id/clearStandard"
+        android:background="#009688"
+        android:text="@string/clearStandard"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/editTemp"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@id/getRealWeight"
+        />
+
+    <Button
+        android:id="@+id/setZero"
+        android:background="#009688"
+        android:text="@string/setZero"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/stopDownload"
+        android:layout_centerVertical="true"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@id/clearStandard"
+        />
+
+    <Button
+        android:id="@+id/setThreshold"
+        android:background="#009688"
+        android:text="@string/setThreshold"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="50dp"
+        android:layout_below="@id/getRealWeight"
+        android:layout_marginTop="30dp" />
+    <EditText
+        android:id="@+id/editThreshold"
+        android:layout_width="88dp"
+        android:inputType="numberDecimal"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/getRealWeight"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@id/setTemp" />
+
+
+</RelativeLayout>

+ 169 - 0
app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/mainLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity"
+    tools:ignore="MissingDefaultResource">
+
+    <TextView
+        android:id="@+id/recvView"
+        android:layout_width="match_parent"
+        android:background="@color/colorAccent"
+        android:layout_height="300dp"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true" />
+    <Button
+        android:id="@+id/sale"
+        android:background="#009688"
+        android:text="@string/sale"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/recvView"
+        android:layout_marginStart="50dp"
+        android:layout_marginTop="30dp"
+        />
+
+    <Button
+        android:id="@+id/getVersion"
+        android:background="#009688"
+        android:text="@string/version"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/recvView"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@+id/sale"
+        android:layout_marginStart="20dp"/>
+
+    <Button
+        android:id="@+id/getTemp"
+        android:background="#009688"
+        android:text="@string/gettemp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/sale"
+        android:layout_marginStart="50dp"
+        android:layout_marginTop="30dp"
+        />
+    <Button
+        android:id="@+id/reboot"
+        android:background="#009688"
+        android:text="@string/reboot"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/getVersion"
+        android:layout_toEndOf="@id/getTemp"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="30dp"/>
+
+    <Button
+        android:id="@+id/setTemp"
+        android:background="#009688"
+        android:text="@string/settemp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/getTemp"
+        android:layout_marginTop="30dp"
+        android:layout_marginStart="50dp" />
+
+    <EditText
+        android:id="@+id/editTemp"
+        android:layout_width="88dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="20dp"
+        android:layout_toEndOf="@id/setTemp"
+        android:layout_below="@id/reboot"
+        android:layout_marginTop="30dp"
+        />
+
+    <Button
+        android:id="@+id/startDownload"
+        android:background="#009688"
+        android:text="@string/startdownload"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/recvView"
+        android:layout_marginStart="20dp"
+        android:layout_toEndOf="@id/reboot"
+        android:layout_marginTop="30dp"/>
+
+    <Button
+        android:id="@+id/firmwareTransfer"
+        android:background="#009688"
+        android:text="@string/content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="30dp"
+        android:layout_below="@id/startDownload"
+        android:layout_toEndOf="@id/reboot"
+        android:layout_marginStart="20dp"/>
+
+    <Button
+        android:id="@+id/stopDownload"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#009688"
+        android:text="@string/stopdownload"
+        android:layout_below="@id/firmwareTransfer"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@id/editTemp"
+        android:layout_marginStart="20dp"
+        />
+
+    <Button
+        android:id="@+id/getRealWeight"
+        android:background="#009688"
+        android:text="@string/getRealWeight"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="50dp"
+        android:layout_below="@id/setTemp"
+        android:layout_marginTop="30dp" />
+
+    <Button
+        android:id="@+id/clearStandard"
+        android:background="#009688"
+        android:text="@string/clearStandard"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/editTemp"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@id/getRealWeight"
+        />
+
+    <Button
+        android:id="@+id/setZero"
+        android:background="#009688"
+        android:text="@string/setZero"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/stopDownload"
+        android:layout_centerVertical="true"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@id/clearStandard"
+        />
+
+    <Button
+        android:id="@+id/setThreshold"
+        android:background="#009688"
+        android:text="@string/setThreshold"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="50dp"
+        android:layout_below="@id/getRealWeight"
+        android:layout_marginTop="30dp" />
+    <EditText
+        android:id="@+id/editThreshold"
+        android:inputType="numberDecimal"
+        android:layout_width="88dp"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/getRealWeight"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="30dp"
+        android:layout_toEndOf="@id/setTemp" />
+
+
+</RelativeLayout>

+ 9 - 0
app/src/main/res/layout/item_layout.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:id="@+id/textView"
+    android:background="@color/colorPrimaryDark"
+    android:padding="5dp"
+    android:layout_height="wrap_content">
+
+</TextView>

+ 9 - 0
app/src/main/res/layout/log_item_layout.xml

@@ -0,0 +1,9 @@
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:textColor="#000000"
+    android:gravity="left"
+    android:paddingLeft="20dp"
+    android:textSize="20sp"
+    android:singleLine="true"
+    />

+ 5 - 0
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

+ 5 - 0
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

BIN=BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN=BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png


BIN=BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png


BIN=BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png


BIN=BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN=BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png


BIN=BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN=BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png


BIN=BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


BIN=BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png


+ 107 - 0
app/src/main/res/values/colors.xml

@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+    <color name="zhihu_lay_click">#81CFEB</color>
+    <color name="zhihu_button_confirm_unclick">#B2B2B2</color>
+    <color name="black">#000000</color>
+    <color name="white">#FFFFFF</color>
+    <color name="qq_login_normal">#1FBAF3</color>
+    <color name="qq_login_press">#1BA7DA</color>
+    <color name="wx_top_left_normal">#ff22292c</color>
+    <color name="wx_top_left_press">#181D1F</color>
+    <color name="wx_login_cantpress">#A2E08D</color>
+    <color name="wx_login_normal">#45C01A</color>
+    <color name="wx_login_press">#298409</color>
+    <color name="bg_viewpager_title">#cc303F9F</color>
+    <color name="tab_unchecked">#757575</color>
+    <color name="status_bar_color">@color/colorPrimaryDark</color>
+    <color name="colorBackGround">#FBF7ED</color>
+    <color name="colorPrimaryLight">#C5CAE9</color>
+    <color name="colorPrimaryText">#212121</color>
+
+
+
+    <color name="color3A3A3A">#1E282D</color><!--实际的颜色采用:知乎的颜色-->
+    <color name="color3F3F3F">#263238</color><!--实际的颜色采用:知乎的颜色-->
+    <color name="color8A9599">#8A9599</color>
+    <color name="color868686">#868686</color>
+
+
+    <!--<color name="primary_light">#C5CAE9</color>-->
+    <!--<color name="primary_text">#212121</color>-->
+
+    <color name="secondary_text">#757575</color>
+    <color name="icons">#FFFFFF</color>
+    <color name="divider">#BDBDBD</color>
+
+    <color name="black_overlay">#66000000</color>
+    <color name="white_overlay">#66ffffff</color>
+    <color name="white_ccffffff">#77ffffff</color>
+
+    <color name="theme_primary_text_inverted">#ffffff</color>
+    <color name="theme_secondary_text_inverted">#8affffff</color>
+
+    <!-- A light Holo shade of blue -->
+    <color name="holo_blue_light">#ff33b5e5</color>
+    <!-- A light Holo shade of gray -->
+    <color name="holo_gray_light">#33999999</color>
+    <!-- A light Holo shade of green -->
+    <color name="holo_green_light">#ff99cc00</color>
+    <!-- A light Holo shade of red -->
+    <color name="holo_red_light">#ffff4444</color>
+    <!-- A dark Holo shade of blue -->
+    <color name="holo_blue_dark">#ff0099cc</color>
+    <!-- A dark Holo shade of green -->
+    <color name="holo_green_dark">#ff669900</color>
+    <!-- A dark Holo shade of red -->
+    <color name="holo_red_dark">#ffcc0000</color>
+    <!-- A Holo shade of purple -->
+    <color name="holo_purple">#ffaa66cc</color>
+    <!-- A light Holo shade of orange -->
+    <color name="holo_orange_light">#ffffbb33</color>
+    <!-- A dark Holo shade of orange -->
+    <color name="holo_orange_dark">#ffff8800</color>
+    <!-- A really bright Holo shade of blue -->
+    <color name="holo_blue_bright">#ff00ddff</color>
+    <!-- A really bright Holo shade of gray -->
+    <color name="holo_gray_bright">#33CCCCCC</color>
+    <!-- A really lighter Holo shade of gray -->
+    <color name="holo_lighter_gray">#ffefefef</color>
+    <!-- A really darker Holo shade of gray -->
+    <color name="holo_darker_gray">#ffaaaaaa</color>
+
+    <color name="tab_checked">#3F51B5</color>
+
+    <color name="github_con_0">#ebedf0</color>
+    <color name="github_con_1">#c6e48b</color>
+    <color name="github_con_2">#7bc96f</color>
+    <color name="github_con_3">#239a3b</color>
+    <color name="github_con_4">#196127</color>
+    <color name="seat_y_bg">#80000000</color>
+    <color name="text_color">#999999</color>
+
+    <color name="root_bg">#1c1a28</color>
+    <color name="main_cicre_line_color">#95949b</color>
+    <color name="alpha_half_main_cicre_line_color">#8895949b</color>
+    <color name="alpha_root_bg">#661c1a28</color>
+    <color name="main_linearlayout_bg_color">#32303c</color>
+    <color name="main_relative_bg_color">#504e59</color>
+
+    <!--function  implement activity 使用的颜色-->
+    <color name="function_implement_titlebar_bg_color">#2d2b57</color>
+    <!--function  implement activity 使用的颜色-->
+
+    <color name="commom_divider_color">#515c64</color>
+
+    <color name="sub_text_color">#a1a1a1</color>
+    <color name="_d1d1d1">#d1d1d1</color>
+
+
+    <color name="chat_room_bottom_linearlayout_divider">#e0e0e2</color>
+
+    <color name="chat_room_bottom_linearlayout_more_fuction_bg">#f5f5f7</color>
+    <color name="main_function_linerlayout_bg_color">#bb2d2b57</color>
+    <color name="login_button">#2d2b57</color>
+</resources>

+ 18 - 0
app/src/main/res/values/strings.xml

@@ -0,0 +1,18 @@
+<resources>
+    <string name="app_name">货品管理</string>
+    <string name="gettemp">获取温度</string>
+    <string name="sale">售卖</string>
+    <string name="settemp">温度设置</string>
+    <string name="version">查询版本</string>
+    <string name="startdownload">开始下载</string>
+    <string name="content">固件传输</string>
+    <string name="stopdownload">下载结束</string>
+    <string name="reboot">重启设备</string>
+    <string name="getRealWeight">获取重量</string>
+    <string name="clearStandard">去标</string>
+    <string name="setZero">置零</string>
+    <string name="setThreshold">设置阈值</string>
+    <string name="clearLog">清除日志</string>
+    <string name="openserial">打开串口</string>
+    <string name="closeSerial">关闭串口</string>
+</resources>

+ 32 - 0
app/src/main/res/values/styles.xml

@@ -0,0 +1,32 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+    <style name="Spinner">
+
+        <!--
+            android:layout_width="140dp"
+            android:layout_height="wrap_content"
+            android:textColor="@android:color/black"
+            android:textSize="22dp"
+            android:background="@color/colorAccent"
+            android:gravity="center"
+            android:layout_marginTop="20dp"
+        -->
+
+        <!--      <item name="android:layout_width">140dp</item>
+              <item name="android:layout_height">wrap_content</item>
+              <item name="android:textColor">@android:color/black</item>-->
+        <item name="android:textSize">20sp</item>
+        <!-- <item name="android:background">@color/colorAccent</item>
+         <item name="android:gravity">center</item>
+         <item name="android:layout_marginTop">20dp</item>-->
+
+    </style>
+
+</resources>

+ 17 - 0
app/src/test/java/com/ifastore/goodsmanage/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.ifastore.goodsmanage;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 30 - 0
build.gradle

@@ -0,0 +1,30 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    
+    repositories {
+        google()
+        jcenter()
+        
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.6.3'
+        classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
+        
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+        maven { url 'https://jitpack.io' }
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 18 - 0
gradle.properties

@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+#android.useAndroidX=true
+## Automatically convert third-party libraries to use AndroidX
+#android.enableJetifier=true
+
+

BIN=BIN
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Wed Jul 29 11:52:55 CST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

+ 172 - 0
gradlew

@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"

+ 84 - 0
gradlew.bat

@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 3 - 0
settings.gradle

@@ -0,0 +1,3 @@
+rootProject.name='GoodsManage'
+include ':app'
+include ':DialogLibrary'