Browse Source

/*

修改偶现bug:
步骤如下:
1. 点击开始测试按钮,数据上报正常;
2. 点击结束检测按钮,弹出保存数据对话框;
3. 点击取消按钮。
4. 再次从过程1开始测试,出现无法识别的ID;

原因:
经过分析日志发现,再次点击测试的时候串口上报的数据没有正确处理,问题出现在串口适配层。
当2、3、4三个动作中间没有任何停留世间操作非常快的时候,这个问题成为必现问题,即使第3个
步骤点击保存按钮,再迅速操作第4个步骤也会出现问题。由这个现象进行分析,确定是由于操作
太快,此时串口并没有正常的关闭,就开始了下一个测试流程。
修改:
该问题有好几种修改方法,经过各方面权衡,采用一种最稳妥对于当前流程逻辑影响最小的方法:
1. 在保存数据对话框点击取消以后弹出一个“正在取消”的模态框,时间为8秒。
2. 延长“正在保存”对话框的时间为8秒。
*/
master
htjcAdmin 11 months ago
commit
692caf43ce
298 changed files with 16423 additions and 0 deletions
  1. +18
    -0
      .gitignore
  2. +5
    -0
      README.md
  3. BIN
      app-release.apk
  4. +1
    -0
      app/.gitignore
  5. +74
    -0
      app/build.gradle
  6. +21
    -0
      app/proguard-rules.pro
  7. BIN
      app/release/app-release.apk
  8. +1
    -0
      app/release/output.json
  9. +62
    -0
      app/src/main/AndroidManifest.xml
  10. +44
    -0
      app/src/main/java/com/handset/serialportsensor/App.java
  11. +24
    -0
      app/src/main/java/com/handset/serialportsensor/BootReceiver.java
  12. +11
    -0
      app/src/main/java/com/handset/serialportsensor/account/Account.java
  13. +169
    -0
      app/src/main/java/com/handset/serialportsensor/account/AccountManager.java
  14. +13
    -0
      app/src/main/java/com/handset/serialportsensor/account/AccountStatusCallback.java
  15. +124
    -0
      app/src/main/java/com/handset/serialportsensor/activity/BaseActivity.java
  16. +265
    -0
      app/src/main/java/com/handset/serialportsensor/activity/BaudRateSettingActivity.java
  17. +192
    -0
      app/src/main/java/com/handset/serialportsensor/activity/ChangeSensorIdSettingsActivity.java
  18. +258
    -0
      app/src/main/java/com/handset/serialportsensor/activity/ConeSettingActivity.java
  19. +238
    -0
      app/src/main/java/com/handset/serialportsensor/activity/DataRecoverActivity.java
  20. +284
    -0
      app/src/main/java/com/handset/serialportsensor/activity/HistoryActivity.java
  21. +482
    -0
      app/src/main/java/com/handset/serialportsensor/activity/HistoryDetailActivity.java
  22. +253
    -0
      app/src/main/java/com/handset/serialportsensor/activity/LoginActivity.java
  23. +624
    -0
      app/src/main/java/com/handset/serialportsensor/activity/Main2Activity.java
  24. +77
    -0
      app/src/main/java/com/handset/serialportsensor/activity/PasswordResetActivity.java
  25. +21
    -0
      app/src/main/java/com/handset/serialportsensor/activity/SPKey.java
  26. +441
    -0
      app/src/main/java/com/handset/serialportsensor/activity/SensorSettingsActivity.java
  27. +40
    -0
      app/src/main/java/com/handset/serialportsensor/activity/SplashActivity.java
  28. +41
    -0
      app/src/main/java/com/handset/serialportsensor/activity/ThirdSensorSettingsActivity.java
  29. +264
    -0
      app/src/main/java/com/handset/serialportsensor/activity/ThresholdActivity.java
  30. +70
    -0
      app/src/main/java/com/handset/serialportsensor/activity/ViewLogActivity.java
  31. +136
    -0
      app/src/main/java/com/handset/serialportsensor/activity/ViewOperateLogListActivity.java
  32. +19
    -0
      app/src/main/java/com/handset/serialportsensor/adapter/HistoryAdapter.java
  33. +86
    -0
      app/src/main/java/com/handset/serialportsensor/adapter/LeftAdapter.java
  34. +46
    -0
      app/src/main/java/com/handset/serialportsensor/adapter/MsgAdapter.java
  35. +98
    -0
      app/src/main/java/com/handset/serialportsensor/adapter/SettingsAdapter.java
  36. +31
    -0
      app/src/main/java/com/handset/serialportsensor/bean/LeftDetailBean.java
  37. +36
    -0
      app/src/main/java/com/handset/serialportsensor/bean/LeftHeadBean.java
  38. +187
    -0
      app/src/main/java/com/handset/serialportsensor/bean/MetaData.java
  39. +34
    -0
      app/src/main/java/com/handset/serialportsensor/bean/RawData.java
  40. +29
    -0
      app/src/main/java/com/handset/serialportsensor/bean/Sensor.java
  41. +37
    -0
      app/src/main/java/com/handset/serialportsensor/bean/SettingsItem.java
  42. +80
    -0
      app/src/main/java/com/handset/serialportsensor/bean/TestData.java
  43. +49
    -0
      app/src/main/java/com/handset/serialportsensor/bean/TestRecordsTotal.java
  44. +28
    -0
      app/src/main/java/com/handset/serialportsensor/bean/TestRecordsitems.java
  45. +23
    -0
      app/src/main/java/com/handset/serialportsensor/bean/ThresholdBean.java
  46. +74
    -0
      app/src/main/java/com/handset/serialportsensor/constant/Constant.java
  47. +55
    -0
      app/src/main/java/com/handset/serialportsensor/db/DBUpdateHelperMY.java
  48. +15
    -0
      app/src/main/java/com/handset/serialportsensor/presenter/SurfaceContract.java
  49. +315
    -0
      app/src/main/java/com/handset/serialportsensor/presenter/SurfacePresenter.java
  50. +78
    -0
      app/src/main/java/com/handset/serialportsensor/utils/CRC16Utils.java
  51. +245
    -0
      app/src/main/java/com/handset/serialportsensor/utils/CrashHandler.java
  52. +49
    -0
      app/src/main/java/com/handset/serialportsensor/utils/DateStyle.java
  53. +322
    -0
      app/src/main/java/com/handset/serialportsensor/utils/DateUtils.java
  54. +144
    -0
      app/src/main/java/com/handset/serialportsensor/utils/EmulatorUtils.java
  55. +368
    -0
      app/src/main/java/com/handset/serialportsensor/utils/ExcelMa.java
  56. +364
    -0
      app/src/main/java/com/handset/serialportsensor/utils/ExcelUtils.java
  57. +377
    -0
      app/src/main/java/com/handset/serialportsensor/utils/PersistHelper.java
  58. +25
    -0
      app/src/main/java/com/handset/serialportsensor/utils/PixelUtils.java
  59. +105
    -0
      app/src/main/java/com/handset/serialportsensor/utils/ProtoUtils.java
  60. +303
    -0
      app/src/main/java/com/handset/serialportsensor/utils/SPUtils.java
  61. +323
    -0
      app/src/main/java/com/handset/serialportsensor/utils/Slog.java
  62. +159
    -0
      app/src/main/java/com/handset/serialportsensor/utils/SpUtil.java
  63. +30
    -0
      app/src/main/java/com/handset/serialportsensor/utils/SplitUtils.java
  64. +36
    -0
      app/src/main/java/com/handset/serialportsensor/utils/StatusBarUtils.java
  65. +169
    -0
      app/src/main/java/com/handset/serialportsensor/utils/ToastHelper.java
  66. +203
    -0
      app/src/main/java/com/handset/serialportsensor/utils/Utils.java
  67. +169
    -0
      app/src/main/java/com/handset/serialportsensor/view/AutoLoadMoreListView.java
  68. +9
    -0
      app/src/main/java/com/handset/serialportsensor/view/AutoLoadMoreListener.java
  69. +61
    -0
      app/src/main/java/com/handset/serialportsensor/view/ExportProgressDialog.java
  70. +26
    -0
      app/src/main/java/com/handset/serialportsensor/view/LinearLayoutManagerCus.java
  71. +379
    -0
      app/src/main/java/com/handset/serialportsensor/widget/DashBoard.java
  72. +12
    -0
      app/src/main/res/anim/rotate_anim.xml
  73. +34
    -0
      app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  74. BIN
      app/src/main/res/drawable-xxhdpi/ic_launcher_c.png
  75. BIN
      app/src/main/res/drawable-xxhdpi/icon.png
  76. BIN
      app/src/main/res/drawable-xxhdpi/loading.png
  77. +7
    -0
      app/src/main/res/drawable/background_red.xml
  78. +23
    -0
      app/src/main/res/drawable/background_sharp.xml
  79. +23
    -0
      app/src/main/res/drawable/background_sharp_circle.xml
  80. +18
    -0
      app/src/main/res/drawable/background_toast.xml
  81. +5
    -0
      app/src/main/res/drawable/bg_loading_dialog.xml
  82. BIN
      app/src/main/res/drawable/bg_my_send.9.png
  83. +19
    -0
      app/src/main/res/drawable/bg_read_btn_starting.xml
  84. +23
    -0
      app/src/main/res/drawable/bg_start_btn.xml
  85. +19
    -0
      app/src/main/res/drawable/bg_start_btn_new.xml
  86. +23
    -0
      app/src/main/res/drawable/bg_stop_btn.xml
  87. +19
    -0
      app/src/main/res/drawable/bg_stop_btn_new.xml
  88. +6
    -0
      app/src/main/res/drawable/checkbox_style_abnormal.xml
  89. +6
    -0
      app/src/main/res/drawable/checkbox_style_normal.xml
  90. +23
    -0
      app/src/main/res/drawable/chuanganqistate_background.xml
  91. +171
    -0
      app/src/main/res/drawable/ic_launcher_background.xml
  92. BIN
      app/src/main/res/drawable/ic_msg_left.9.png
  93. BIN
      app/src/main/res/drawable/ic_msg_right.9.png
  94. +12
    -0
      app/src/main/res/drawable/login_btn_bg.xml
  95. +9
    -0
      app/src/main/res/drawable/login_btn_bg_rc.xml
  96. +12
    -0
      app/src/main/res/drawable/login_edittext_bg.xml
  97. +12
    -0
      app/src/main/res/drawable/logout_btn_bg.xml
  98. +33
    -0
      app/src/main/res/drawable/progressloading.xml
  99. +14
    -0
      app/src/main/res/drawable/seekbar_custom.xml
  100. +14
    -0
      app/src/main/res/drawable/seekbar_custom_blue.xml

+ 18
- 0
.gitignore View File

@ -0,0 +1,18 @@
*.iml
.gradle
/local.properties
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild
.idea
.idea/
app/libs/
serialportlib/libs/
serialportlib/src/main/res/drawable/
!app-release.apk

+ 5
- 0
README.md View File

@ -0,0 +1,5 @@
## HANDSET-JE002-EX
### 说明
传感器通过串口上报响应的检测数据:温度、湿度、内压、外压

BIN
app-release.apk View File


+ 1
- 0
app/.gitignore View File

@ -0,0 +1 @@
/build

+ 74
- 0
app/build.gradle View File

@ -0,0 +1,74 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.handset.serialportsensor"
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "2.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
//--.apk
def fileName = "检测仪_JE002_EX_V${versionName}_${releaseTime()}.apk"
outputFileName = fileName
}
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation rootProject.ext.deps.appcompatV7
implementation rootProject.ext.deps.recyclerviewV7
implementation rootProject.ext.deps.constraintLayout
implementation rootProject.ext.deps.rvAdapterHelper
implementation rootProject.ext.deps.rvDivider
implementation rootProject.ext.deps.stickyDecoration
implementation rootProject.ext.deps.utils
implementation rootProject.ext.deps.jodaTime
implementation rootProject.ext.deps.rxJava
implementation rootProject.ext.deps.rxAndroid
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'org.projectlombok:lombok:1.16.16'
annotationProcessor "org.projectlombok:lombok:1.16.16"
compileOnly 'org.glassfish:javax.annotation:10.0-b28'
implementation 'com.squareup.retrofit2:converter-gson:2.2.0'
implementation project(':serialportlib')
implementation 'com.github.suntiago:dblib:v1.0-beta'
implementation 'com.android.support:multidex:1.0.3'
implementation 'cn.jingzhuan.lib:chart:0.10.17@aar'
implementation 'com.google.guava:guava:22.0-android'
}
def static releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+8"))
}

+ 21
- 0
app/proguard-rules.pro View File

@ -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

BIN
app/release/app-release.apk View File


+ 1
- 0
app/release/output.json View File

@ -0,0 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

+ 62
- 0
app/src/main/AndroidManifest.xml View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.handset.serialportsensor">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--开机自启动权限-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name="com.handset.serialportsensor.App"
android:allowBackup="true"
android:icon="@drawable/ic_launcher_c"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/DefAppTheme">
<activity
android:name="com.handset.serialportsensor.activity.SplashActivity"
android:screenOrientation="portrait"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.handset.serialportsensor.activity.Main2Activity"
android:label="@string/title_activity_main"
android:screenOrientation="portrait"
android:theme="@style/DefAppTheme" />
<activity android:name="com.handset.serialportsensor.activity.HistoryActivity" />
<activity android:name="com.handset.serialportsensor.activity.HistoryDetailActivity" />
<activity
android:name="com.handset.serialportsensor.activity.LoginActivity"
android:launchMode="singleTask" />
<activity android:name="com.handset.serialportsensor.activity.SensorSettingsActivity" />
<activity android:name="com.handset.serialportsensor.activity.BaudRateSettingActivity" />
<activity android:name="com.handset.serialportsensor.activity.ThresholdActivity" />
<activity android:name="com.handset.serialportsensor.activity.ConeSettingActivity" />
<activity android:name="com.handset.serialportsensor.activity.DataRecoverActivity" />
<activity android:name="com.handset.serialportsensor.activity.PasswordResetActivity" />
<activity android:name="com.handset.serialportsensor.activity.ThirdSensorSettingsActivity" />
<activity android:name="com.handset.serialportsensor.activity.ChangeSensorIdSettingsActivity" />
<activity android:name="com.handset.serialportsensor.activity.ViewOperateLogListActivity" />
<activity android:name="com.handset.serialportsensor.activity.ViewLogActivity" />
<receiver
android:name="com.handset.serialportsensor.BootReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>

+ 44
- 0
app/src/main/java/com/handset/serialportsensor/App.java View File

@ -0,0 +1,44 @@
package com.handset.serialportsensor;
import android.support.multidex.MultiDexApplication;
import com.blankj.utilcode.util.Utils;
import com.handset.serialportsensor.account.AccountManager;
import com.handset.serialportsensor.db.DBUpdateHelperMY;
import com.handset.serialportsensor.utils.CrashHandler;
import com.handset.serialportsensor.utils.PersistHelper;
import com.handset.serialportsensor.utils.Slog;
import net.danlew.android.joda.JodaTimeAndroid;
import org.kymjs.kjframe.KJDB;
public class App extends MultiDexApplication {
static boolean debug = BuildConfig.DEBUG;
@Override
public void onCreate() {
super.onCreate();
Utils.init(this);
JodaTimeAndroid.init(this);
Slog.init(this);
Slog.setDebug(true, true);
Slog.enableSaveLog(true);
KJDB.create(this, "htjc_sensor_history.db", !debug, DBUpdateHelperMY.DATABASE_VERSION, new DBUpdateHelperMY());
/*
* 初始化账户组件不使用自动登录
* */
AccountManager.init((this), debug);
//保存Crash的Log
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(getApplicationContext());
PersistHelper.init((this));
}
}

+ 24
- 0
app/src/main/java/com/handset/serialportsensor/BootReceiver.java View File

@ -0,0 +1,24 @@
package com.handset.serialportsensor;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.handset.serialportsensor.activity.Main2Activity;
import com.handset.serialportsensor.utils.Slog;
public class BootReceiver extends BroadcastReceiver {
private final String TAG = getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Slog.d(TAG, "Receive Broadcast");
Intent bootIntent = new Intent(context, Main2Activity.class);
bootIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(bootIntent);
}
}
}

+ 11
- 0
app/src/main/java/com/handset/serialportsensor/account/Account.java View File

@ -0,0 +1,11 @@
package com.handset.serialportsensor.account;
/**
* Created by Jeremy on 2018/8/2.
*/
public class Account {
//账户id
public String userId;
public String token;
}

+ 169
- 0
app/src/main/java/com/handset/serialportsensor/account/AccountManager.java View File

@ -0,0 +1,169 @@
package com.handset.serialportsensor.account;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.handset.serialportsensor.utils.SPUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by Jeremy on 2018/8/2.
* 账户管理应用适用于单用户系统
*/
@SuppressWarnings(value = "unused")
public class AccountManager {
private final String TAG = getClass().getSimpleName();
private static String AccountManager_user_id = "AccountManager_user_id";
private static String AccountManager_account_token = "AccountManager_account_token";
private static AccountManager sAccountManager;
private Context sContext;
//账户ID
private Account mAccount;
private List<AccountStatusCallback> mAccountStatusCallbacks = new ArrayList<>();
private HashMap<AccountStatusCallback, List<String>> mCallbackListHashMap = new HashMap<>();
public static AccountManager get() {
if (sAccountManager == null) {
throw new NullPointerException("please init AccountManager first before getting");
}
return sAccountManager;
}
private AccountManager(Context sContext, boolean autoLogin) {
this.sContext = sContext;
if (autoLogin) {
autoLogin();
}
}
public static void init(Context context) {
init(context, false);
}
public static void init(Context context, boolean autoLogin) {
if (sAccountManager == null) {
sAccountManager = new AccountManager(context, autoLogin);
}
}
public boolean isLogin() {
Log.i(TAG, "mAccount.userId: " + mAccount.userId);
return mAccount != null && !TextUtils.isEmpty(mAccount.userId);
}
public String getUserData(String key) {
if (isLogin()) {
return SPUtils.getInstance(sContext).get(mAccount.userId + key);
}
return null;
}
public void putUserData(String key, String data) {
Log.d(TAG, "putUserData [key, data]:" + key + " " + data);
if (isLogin()) {
SPUtils.getInstance(sContext).put(mAccount.userId + key, data);
if (mAccountStatusCallbacks.size() > 0) {
for (AccountStatusCallback accountStatusCallback : mAccountStatusCallbacks) {
if (mCallbackListHashMap.containsKey(accountStatusCallback)) {
for (String s : mCallbackListHashMap.get(accountStatusCallback)) {
if (key.equals(s)) {
accountStatusCallback.userInfoChange(key);
break;
}
}
} else {
accountStatusCallback.userInfoChange(key);
}
}
}
}
}
public String getUserId() {
if (isLogin()) {
return mAccount.userId;
}
return "";
}
public String getToken() {
return isLogin() ? mAccount.token : "";
}
private void autoLogin() {
String account = "admin"/*SPUtils.getInstance(sContext).get(AccountManager_user_id)*/;
String token = SPUtils.getInstance(sContext).get(account + AccountManager_account_token);
setAccount(account, token);
}
public void login(String userId, String token) {
setAccount(userId, token);
Log.i(TAG, "login [userId, pwd]:" + userId + " " + token + "");
}
public void logout() {
Log.i(TAG, "logout []:" + getUserId());
setAccount("", "");
}
private void setAccount(String userId, String token) {
if (mAccount == null) {
mAccount = new Account();
}
mAccount.userId = userId;
mAccount.token = token;
SPUtils.getInstance(sContext).put(AccountManager_user_id, userId);
SPUtils.getInstance(sContext).put(userId + AccountManager_account_token, token);
if (mAccountStatusCallbacks.size() > 0) {
if (isLogin()) {
for (AccountStatusCallback accountStatusCallback : mAccountStatusCallbacks) {
accountStatusCallback.loginCallback();
}
} else {
for (AccountStatusCallback accountStatusCallback : mAccountStatusCallbacks) {
accountStatusCallback.logoutCallback();
}
}
}
}
/*初次注册,立即回调一下*/
public void registerAccountStatusCallBack(AccountStatusCallback statusCallback) {
registerAccountStatusCallBack(statusCallback, null);
}
/*初次注册,立即回调一下*/
/**
* @param statusCallback 回调参数
* @param interestKeys 感兴趣的字段,默认回调所有的字段
*/
private void registerAccountStatusCallBack(AccountStatusCallback statusCallback, List<String> interestKeys) {
if (!mAccountStatusCallbacks.contains(mAccountStatusCallbacks)) {
mAccountStatusCallbacks.add(statusCallback);
if (interestKeys != null && interestKeys.size() > 0) {
if (mCallbackListHashMap.containsKey(statusCallback)) {
mCallbackListHashMap.remove(statusCallback);
}
mCallbackListHashMap.put(statusCallback, interestKeys);
}
if (isLogin()) {
statusCallback.loginCallback();
} else {
//statusCallback.logoutCallback();
}
}
}
public void unregisterAccountStatusCallBack(AccountStatusCallback statusCallback) {
mAccountStatusCallbacks.remove(statusCallback);
mCallbackListHashMap.remove(statusCallback);
}
}

+ 13
- 0
app/src/main/java/com/handset/serialportsensor/account/AccountStatusCallback.java View File

@ -0,0 +1,13 @@
package com.handset.serialportsensor.account;
/**
* Created by Jeremy on 2018/8/2.
*/
public interface AccountStatusCallback {
void loginCallback();
void logoutCallback();
void userInfoChange(String key);
}

+ 124
- 0
app/src/main/java/com/handset/serialportsensor/activity/BaseActivity.java View File

@ -0,0 +1,124 @@
package com.handset.serialportsensor.activity;
import android.app.AlertDialog;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.handset.serialportlib.CRCUtils;
public abstract class BaseActivity extends AppCompatActivity {
private static final String logTag = "HANDSET-JE002-EX";
private boolean mResume = false;
boolean mNeedToDismissProgressDlg = false;
boolean mNeedToShowProgressDlg = false;
AlertDialog mLoadingDialog;
@Override
protected void onResume() {
super.onResume();
this.mResume = true;
checkProgress();
}
@Override
protected void onPause() {
this.mResume = false;
super.onPause();
}
protected String genCmd(String sensorNo, int cmdId) {
try {
String content = sensorNo.concat("00" + Integer.toHexString(cmdId) + "00");
return "DDDD" + content + CRCUtils.genCrc(content);
} catch (Exception e) {
Log.e(logTag, e.getMessage());
return null;
}
}
public void showDialog(final AlertDialog loadingDialog) {
if (loadingDialog == null) {
return;
}
mLoadingDialog = loadingDialog;
if (mResume) {
mLoadingDialog.show();
mNeedToShowProgressDlg = false;
} else {
mNeedToShowProgressDlg = true;
}
}
private void checkProgress() {
if (mLoadingDialog != null && mResume) {
if (mNeedToShowProgressDlg) {
mLoadingDialog.show();
mNeedToShowProgressDlg = false;
}
if (mNeedToDismissProgressDlg) {
mLoadingDialog.dismiss();
mNeedToDismissProgressDlg = false;
mLoadingDialog = null;
}
}
}
public void dismissDialog(final AlertDialog loadingDialog) {
if (loadingDialog == null && mLoadingDialog == null) {
return;
}
if (mResume) {
if (loadingDialog != null && loadingDialog.isShowing()) {
loadingDialog.dismiss();
} else if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
mLoadingDialog.dismiss();
}
mNeedToDismissProgressDlg = false;
mLoadingDialog = null;
} else {
mLoadingDialog = loadingDialog;
mNeedToDismissProgressDlg = true;
}
}
public void disMissDialogDelay(final AlertDialog alertDialog, int delayMillis) {
new Handler().postDelayed(() -> dismissDialogD(alertDialog), delayMillis);
}
protected void dismissDialogD(final AlertDialog alertDialog) {
if (mLoadingDialog == null && alertDialog == null) {
return;
}
if (mLoadingDialog != null && alertDialog != null && mLoadingDialog == alertDialog) {
dismissDialog(alertDialog);
return;
}
if (mLoadingDialog == null) {
if (mResume && alertDialog.isShowing()) {
alertDialog.dismiss();
}
}
}
public void disMissLoadingDialog(final AlertDialog loadingDialog) {
runOnUiThread(() -> {
/*if (loadingDialog != null && loadingDialog.isShowing()) {
loadingDialog.dismiss();
}*/
dismissDialog(loadingDialog);
});
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}

+ 265
- 0
app/src/main/java/com/handset/serialportsensor/activity/BaudRateSettingActivity.java View File

@ -0,0 +1,265 @@
package com.handset.serialportsensor.activity;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportlib.CRCUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.presenter.SurfaceContract;
import com.handset.serialportsensor.presenter.SurfacePresenter;
import com.handset.serialportsensor.utils.ToastHelper;
import java.util.Arrays;
public class BaudRateSettingActivity extends BaseActivity implements View.OnClickListener, SurfaceContract.ISerialView {
private final String logTag = "HANDSET-JE002-EX";
private TextView tvBr9600;
private TextView tvBr19200;
private TextView tvNum3;
private ImageView ivBr9600;
private ImageView ivBr19200;
private ImageView ivBr38400;
private byte baudByte = 0x01;
private Integer baudRate;
private String sensorId;
private AlertDialog baudSettingsDialog;
private SurfacePresenter mPresenter = new SurfacePresenter((this));
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_baudrate_setting);
Intent intent = getIntent();
if (intent != null) {
baudRate = intent.getIntExtra(Constant.BAUD_RATE, (38400));
sensorId = intent.getStringExtra(Constant.SENSOR_ID);
}
initView();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
mPresenter.close();
super.onDestroy();
}
private void initView() {
TextView tvTitle = findViewById(R.id.title_text);
ImageView ivBack = findViewById(R.id.title_back);
TextView tvConfirm = findViewById(R.id.tv_confirm);
RelativeLayout rlNum1 = findViewById(R.id.rl_br_9600);
RelativeLayout rlNum2 = findViewById(R.id.rl_br_19200);
RelativeLayout rlNum3 = findViewById(R.id.rl_br_38400);
tvBr9600 = findViewById(R.id.tv_br_9600);
tvBr19200 = findViewById(R.id.tv_br_19200);
tvNum3 = findViewById(R.id.tv_br_38400);
ivBr9600 = findViewById(R.id.iv_br_9600);
ivBr19200 = findViewById(R.id.iv_br_19200);
ivBr38400 = findViewById(R.id.iv_br_38400);
tvTitle.setText(R.string.baud_rate_setting);
ivBack.setVisibility(View.VISIBLE);
tvConfirm.setVisibility(View.VISIBLE);
tvConfirm.setText(R.string.confirm);
tvBr9600.setTextColor(getResources().getColor(R.color.colorPrimaryDark));
ivBr9600.setVisibility(View.VISIBLE);
ivBack.setOnClickListener(this);
tvConfirm.setOnClickListener(this);
rlNum1.setOnClickListener(this);
rlNum2.setOnClickListener(this);
rlNum3.setOnClickListener(this);
if (baudRate == 38400) {
clickId(R.id.rl_br_38400);
} else if (baudRate == 19200) {
clickId(R.id.rl_br_19200);
} else if (baudRate == 9600) {
clickId(R.id.rl_br_9600);
}
}
@Override
public void onClick(View view) {
clickId(view.getId());
}
private void clickId(int id) {
switch (id) {
case R.id.title_back:
this.finish();
break;
case R.id.tv_confirm:
if (ivBr9600.getVisibility() == View.VISIBLE) {
baudByte = 0x01;
} else if (ivBr19200.getVisibility() == View.VISIBLE) {
baudByte = 0x02;
} else {
baudByte = 0x03;
}
setBaudRate();
break;
case R.id.rl_br_9600:
tvBr9600.setTextColor(getResources().getColor(R.color.colorPrimaryDark));
tvBr19200.setTextColor(getResources().getColor(R.color.text_general_color));
tvNum3.setTextColor(getResources().getColor(R.color.text_general_color));
ivBr9600.setVisibility(View.VISIBLE);
ivBr19200.setVisibility(View.GONE);
ivBr38400.setVisibility(View.GONE);
break;
case R.id.rl_br_19200:
tvBr9600.setTextColor(getResources().getColor(R.color.text_general_color));
tvBr19200.setTextColor(getResources().getColor(R.color.colorPrimaryDark));
tvNum3.setTextColor(getResources().getColor(R.color.text_general_color));
ivBr9600.setVisibility(View.GONE);
ivBr19200.setVisibility(View.VISIBLE);
ivBr38400.setVisibility(View.GONE);
break;
case R.id.rl_br_38400:
tvBr9600.setTextColor(getResources().getColor(R.color.text_general_color));
tvBr19200.setTextColor(getResources().getColor(R.color.text_general_color));
tvNum3.setTextColor(getResources().getColor(R.color.colorPrimaryDark));
ivBr9600.setVisibility(View.GONE);
ivBr19200.setVisibility(View.GONE);
ivBr38400.setVisibility(View.VISIBLE);
break;
default:
break;
}
}
private void setBaudRate() {
Log.i(logTag, ("Setting BaudRate:" + baudRate));
showSettingDialog();
new Thread(
() -> {
Looper.prepare();
new Handler().postDelayed(() -> mPresenter.open(baudRate), (300));
Looper.loop();
}
).start();
handler.sendEmptyMessageDelayed(Constant.Command.COMMAND_3C, (3300));
new Handler().postDelayed(() -> {
if (baudSettingsDialog != null && baudSettingsDialog.isShowing()) {
baudSettingsDialog.dismiss();
setBaudFailed();
}
}, (10000));
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == Constant.Command.COMMAND_3C) {//波特率设置
Log.i(logTag, ("baud rate set: sensorId: " + sensorId));
StringBuilder sb = new StringBuilder(sensorId);
sb.append("00").append("3C").append("01").append("0".concat(String.valueOf(baudByte)));
String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
Log.i(logTag, "baud rate set: cooked: " + cooked);
Log.i(logTag, "baud rate set: cooked 2: " + Arrays.toString(cooked.getBytes()));
mPresenter.write(cooked);
}
}
};
//正在设置波特率
private void showSettingDialog() {
runOnUiThread(() -> baudSettingsDialog = ToastHelper.showTipDialog((BaudRateSettingActivity.this), R.mipmap.ic_setting, R.string.set_baud_rate_now_tips));
}
@Override
public void onSerialOpen(boolean isOpen) {
}
@Override
public void onSerialBaudRate(Integer baudRate) {
}
@Override
public void onSerialData(RawData rawData) {
if (rawData.getItemType() == RawData.TYPE_RECEIVE) {
String message = rawData.getMessage();
Log.i(logTag, ("BaudRateSettingActivity, onSerialData: " + message));
byte[] bytes = ByteUtils.hexStrToBytes(message);
if ((bytes[6] & 0xff) == 0x0 && (bytes[7] & 0xff) == Constant.Command.COMMAND_3D) {
mPresenter.close();
if (baudSettingsDialog != null && baudSettingsDialog.isShowing()) {
baudSettingsDialog.dismiss();
}
setBaudSuccess();
}
}
}
@Override
public void onSerialError(Integer errorCode) {
}
//波特率设置成功
private void setBaudSuccess() {
runOnUiThread(() -> {
disMissLoadingDialog(baudSettingsDialog);
ToastHelper.showSubmitDialog(
getString(R.string.set_baud_rate_success),
R.mipmap.img_right,
getString(R.string.go_back_init_screen_content),
getResources().getColor(R.color.blue_button_bg),
getString(R.string.btn_ensure), BaudRateSettingActivity.this,
(View view) -> {
finish();
Intent intent = new Intent((BaudRateSettingActivity.this), Main2Activity.class);
intent.putExtra(Constant.SENSOR_ID, sensorId);
startActivity(intent);
});
});
}
//波特率设置失败
private void setBaudFailed() {
runOnUiThread(() -> {
disMissLoadingDialog(baudSettingsDialog);
ToastHelper.showSubmitDialog(
getString(R.string.set_baud_rate_failed),
R.mipmap.img_cross,
getString(R.string.go_back_init_screen_content),
getResources().getColor(R.color.button),
getString(R.string.btn_ensure),
(BaudRateSettingActivity.this),
(View view) -> finish()
);
});
}
}

+ 192
- 0
app/src/main/java/com/handset/serialportsensor/activity/ChangeSensorIdSettingsActivity.java View File

@ -0,0 +1,192 @@
package com.handset.serialportsensor.activity;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportlib.CRCUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.presenter.SurfaceContract;
import com.handset.serialportsensor.presenter.SurfacePresenter;
import com.handset.serialportsensor.utils.ToastHelper;
import java.util.Arrays;
/**
* Created by zy on 2019/2/23.
*/
public class ChangeSensorIdSettingsActivity extends BaseActivity implements SurfaceContract.ISerialView {
private static final String logTag = "HANDSET-JE002-EX";
private String sensorId;
private Integer baudRate;
private EditText etSensorId;
private SurfacePresenter mPresenter = new SurfacePresenter((this));
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_change_sensor_id_setings);
Intent intent = getIntent();
if (intent != null) {
sensorId = intent.getStringExtra(Constant.SENSOR_ID);
baudRate = intent.getIntExtra(Constant.BAUD_RATE, (38400));
}
etSensorId = findViewById(R.id.et_sensor_id);
findViewById(R.id.btn_save).setOnClickListener((View v) -> save());
initTitle();
etSensorId.setText(sensorIdToInt(sensorId));
}
@Override
protected void onDestroy() {
mPresenter.close();
super.onDestroy();
}
private String sensorIdToInt(String sensorId) {
byte[] bytes = ByteUtils.hexStrToBytes(sensorId);
Log.i(logTag, "sensorId hexStrToBytes: " + Arrays.toString(bytes));
int no = ((bytes[0] & 0xff) * 100 + (bytes[1] & 0xff)) * 10000 + ((bytes[2] & 0xff) << 8) + (bytes[3] & 0xff);
String s = "00000000".concat(String.valueOf(no));
return s.substring(s.length() - 8);
}
private void initTitle() {
ImageView ivBack = findViewById(R.id.title_back);
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View view) -> finish());
TextView tvTitle = findViewById(R.id.title_text);
tvTitle.setText(R.string.id_setting);
}
private void save() {
String sensorId = etSensorId.getText().toString();
if (TextUtils.isEmpty(sensorId) || sensorId.length() != 8) {
Toast.makeText((this), R.string.id_must_8bits_tip, Toast.LENGTH_SHORT).show();
} else {
boolean tagAccept = true;
for (int i = 0; i < 8; i++) {
char a = sensorId.charAt(i);
if (!from0to9(a)) {
Toast.makeText((this), R.string.id_must_8bits_tip, Toast.LENGTH_SHORT).show();
tagAccept = false;
break;
}
}
if (tagAccept) {
showSettingDialog();
new Thread(
() -> {
Looper.prepare();
new Handler().postDelayed(() -> mPresenter.open(baudRate), (500));
Looper.loop();
}
).start();
handler.sendEmptyMessageDelayed(Constant.Command.COMMAND_50, (3500));
}
}
}
private AlertDialog settingsDialog;
private void showSettingDialog() {
runOnUiThread(() -> {
settingsDialog = ToastHelper.showTipDialog((ChangeSensorIdSettingsActivity.this), R.mipmap.ic_setting, R.string.id_setting_tip);
//disMissDialogDelay(settingsDialog, (10000));
dismissSettingDialogDelay();
}
);
}
private Handler dismissHandler = new Handler();
private Runnable dismissRunnable;
private void dismissSettingDialogDelay() {
dismissRunnable = () -> {
dismissDialogD(settingsDialog);
runOnUiThread(() -> Toast.makeText((ChangeSensorIdSettingsActivity.this), R.string.sensor_id_set_fail, Toast.LENGTH_SHORT).show());
};
dismissHandler.postDelayed(dismissRunnable, (10000));
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == Constant.Command.COMMAND_50) {//设置传感器ID
StringBuilder sb = new StringBuilder(sensorId);
byte[] bytes = ByteUtils.getByte4Id(etSensorId.getText().toString());
String hexString = ByteUtils.bytesToHexStr(bytes);
Log.i(logTag, "sensor no set: sensor prior: " + Arrays.toString(bytes));
Log.i(logTag, "sensor no set: hexString: " + hexString);
sb.append("00").append("50").append("04").append(hexString);
String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
Log.i(logTag, "sensor no set: cooked: " + cooked);
Log.i(logTag, "sensor no set: cooked 2: " + Arrays.toString(cooked.getBytes()));
mPresenter.write(cooked);
}
}
};
private boolean from0to9(char c) {
return (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9');
}
@Override
public void onSerialOpen(boolean isOpen) {
}
@Override
public void onSerialBaudRate(Integer baudRate) {
}
@Override
public void onSerialData(RawData rawData) {
if (rawData.getItemType() == RawData.TYPE_RECEIVE) {
Log.i(logTag, "ChangeSensorIdSettingsActivity, onSerialData: " + rawData.getMessage());
byte[] bytes = ByteUtils.hexStrToBytes(rawData.getMessage());
Log.i(logTag, "ChangeSensorIdSettingsActivity, onSerialData 2: " + Arrays.toString(bytes));
if (bytes.length >= 8) {
if ((bytes[6] & 0xff) == 0 && (bytes[7] & 0xff) == Constant.Command.COMMAND_51) {
Log.i(logTag, "ChangeSensorIdSettingsActivity, onSerialData, 0x51 feedback: " + rawData.getMessage());
mPresenter.close();
dismissDialog(settingsDialog);
dismissHandler.removeCallbacks(dismissRunnable);
runOnUiThread(() -> Toast.makeText((ChangeSensorIdSettingsActivity.this), R.string.sensor_id_set_success, Toast.LENGTH_SHORT).show());
finish();
Intent intent = new Intent((ChangeSensorIdSettingsActivity.this), Main2Activity.class);
intent.putExtra(Constant.SENSOR_ID, sensorId);
startActivity(intent);
} else {
runOnUiThread(() -> Toast.makeText((ChangeSensorIdSettingsActivity.this), R.string.sensor_id_set_fail, Toast.LENGTH_SHORT).show());
}
}
}
}
@Override
public void onSerialError(Integer errorCode) {
}
}

+ 258
- 0
app/src/main/java/com/handset/serialportsensor/activity/ConeSettingActivity.java View File

@ -0,0 +1,258 @@
package com.handset.serialportsensor.activity;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.blankj.utilcode.util.ToastUtils;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportlib.CRCUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.presenter.SurfaceContract;
import com.handset.serialportsensor.presenter.SurfacePresenter;
import com.handset.serialportsensor.utils.ToastHelper;
import java.util.Arrays;
public class ConeSettingActivity extends BaseActivity implements SurfaceContract.ISerialView {
private static final String TAG = "HANDSET-JE002-EX";
private Integer baudRate;
private String sensorId;
boolean eggNoRes = false, coneNoRes = false, coneUsedTimesRes = false, eggTypeRes = false;
private AlertDialog settingsDialog;
private AlertDialog getSettingsDialog;
private SurfacePresenter mPresenter = new SurfacePresenter((this));
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cone_setting);
Intent intent = getIntent();
if (intent != null) {
baudRate = intent.getIntExtra(Constant.BAUD_RATE, (38400));
sensorId = intent.getStringExtra(Constant.SENSOR_ID);
}
initView();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
mPresenter.close();
super.onDestroy();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (im != null) {
View view = getCurrentFocus();
if (view != null) {
im.hideSoftInputFromWindow(getCurrentFocus().getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
return super.onTouchEvent(event);
}
private void initView() {
initTitle();
}
public void onClickBtnSave(View view) {
String value = ((EditText) (findViewById(R.id.et_egg_num))).getText().toString();
String value2 = ((EditText) (findViewById(R.id.et_cone_num))).getText().toString();
String value3 = ((EditText) (findViewById(R.id.et_use_num))).getText().toString();
String value4 = ((EditText) (findViewById(R.id.et_egg_type))).getText().toString();
if(TextUtils.isEmpty(value) && TextUtils.isEmpty(value2) &&TextUtils.isEmpty(value3) && TextUtils.isEmpty(value4)) {
ToastUtils.showShort(getString(R.string.input_empty));
} else {
showSettingDialog();
new Thread(
() -> {
Looper.prepare();
new Handler().postDelayed(() -> mPresenter.open(baudRate), (500));
Looper.loop();
}
).start();
handler.sendEmptyMessageDelayed(Constant.Command.COMMAND_32, (3500));
handler.sendEmptyMessageDelayed(Constant.Command.COMMAND_36, (3700));
handler.sendEmptyMessageDelayed(Constant.Command.COMMAND_3A, (3800));
handler.sendEmptyMessageDelayed(Constant.Command.COMMAND_40, (3900));
handler.sendEmptyMessageDelayed(Constant.READ_TIME_OUT, (10000));
}
}
private void initTitle() {
ImageView ivBack = findViewById(R.id.title_back);
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View view) -> finish());
TextView tvTitle = findViewById(R.id.title_text);
tvTitle.setText(R.string.cone_info_title);
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == Constant.Command.COMMAND_32) {//弹号设置
String value = ((EditText) (findViewById(R.id.et_egg_num))).getText().toString();
if (!TextUtils.isEmpty(value)) {
Log.i(TAG, "egg no set: sensorId: " + sensorId);
StringBuilder sb = new StringBuilder(sensorId);
//String length = "0".concat(String.valueOf(value.length()));
String length = "0".concat(Integer.toHexString(value.length()));
String length2 = length.substring(length.length() - 2);
//Log.i(TAG, "egg no set: length2: " + length2);
sb.append("00").append("32").append(length2).append(ByteUtils.strToHexStr(value));
String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
Log.i(TAG, "egg no set: cooked: " + cooked);
Log.i(TAG, "egg no set: cooked 2: " + Arrays.toString(cooked.getBytes()));
mPresenter.write(cooked);
}
} else if (msg.what == Constant.Command.COMMAND_36) {//筒号设置
String value = ((EditText) (findViewById(R.id.et_cone_num))).getText().toString();
if (!TextUtils.isEmpty(value)) {
StringBuilder sb = new StringBuilder(sensorId);
//String length = "0".concat(String.valueOf(value.length()));
String length = "0".concat(Integer.toHexString(value.length()));
String length2 = length.substring(length.length() - 2);
sb.append("00").append("36").append(length2).append(ByteUtils.strToHexStr(value));
String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
Log.i(TAG, "cone no set: cooked: " + cooked);
mPresenter.write(cooked);
}
} else if (msg.what == Constant.Command.COMMAND_3A) {//弹筒使用次数设置
String value = ((EditText) (findViewById(R.id.et_use_num))).getText().toString();
if (!TextUtils.isEmpty(value)) {
StringBuilder sb = new StringBuilder(sensorId);
String length = "0".concat(String.valueOf(value.length()));
String length2 = length.substring(length.length() - 2);
sb.append("00").append("3A").append(length2).append(ByteUtils.strToHexStr(value));
String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
Log.i(TAG, "cone used times set: cooked: " + cooked);
mPresenter.write(cooked);
}
} else if (msg.what == Constant.Command.COMMAND_40) { // 弹型
String value = ((EditText) (findViewById(R.id.et_egg_type))).getText().toString();
if (!TextUtils.isEmpty(value)) {
StringBuilder sb = new StringBuilder(sensorId);
String length = "0".concat(Integer.toHexString(value.length()));
String length2 = length.substring(length.length() - 2);
sb.append("00").append("40").append(length2).append(ByteUtils.strToHexStr(value));
String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
Log.i(TAG, "egg type set: cooked: " + cooked);
mPresenter.write(cooked);
}
} else if (msg.what == Constant.READ_TIME_OUT) {
if (eggNoRes || coneNoRes || coneUsedTimesRes || eggTypeRes) {
/*ToastUtils.showShort(R.string.setting_success);*/
runOnUiThread(() -> {
disMissLoadingDialog(settingsDialog);
if (!(getSettingsDialog != null && getSettingsDialog.isShowing())) {
getSettingsDialog = ToastHelper.showSubmitDialog(
getString(R.string.set_cone_info_success),
R.mipmap.img_right,
getString(R.string.go_back_init_screen_content),
getResources().getColor(R.color.blue_button_bg),
getString(R.string.btn_ensure),
(ConeSettingActivity.this),
(View view) -> finish()
);
}
});
} else {
runOnUiThread(() -> {
disMissLoadingDialog(settingsDialog);
if (!(getSettingsDialog != null && getSettingsDialog.isShowing())) {
getSettingsDialog = ToastHelper.showSubmitDialog(
getString(R.string.set_cone_info_failed),
R.mipmap.img_cross,
getString(R.string.go_back_init_screen_content),
getResources().getColor(R.color.blue_button_bg),
getString(R.string.btn_ensure),
(ConeSettingActivity.this),
(View view) -> finish()
);
}
});
}
/*findViewById(R.id.btn_save).setEnabled(true);
findViewById(R.id.btn_save).setBackgroundResource(R.drawable.bg_start_btn_new);
((Button) findViewById(R.id.btn_save)).setText(R.string.save_settings);*/
}
}
};
@Override
public void onSerialOpen(boolean isOpen) {
}
@Override
public void onSerialBaudRate(Integer baudRate) {
}
@Override
public void onSerialData(RawData rawData) {
if (rawData.getItemType() == RawData.TYPE_RECEIVE) {
String message = rawData.getMessage();
Log.i(TAG, "ConeSettingActivity, onSerialData: " + message);
byte[] bytes = ByteUtils.hexStrToBytes(message);
if ((bytes[6] & 0xff) == 0x0 && (bytes[7] & 0xff) == Constant.Command.COMMAND_33) { //egg no
eggNoRes = ((bytes[9] & 0xff) == 0xff);
} else if ((bytes[6] & 0xff) == 0x0 && (bytes[7] & 0xff) == Constant.Command.COMMAND_37) { //cone no
coneNoRes = (bytes[9] & 0xff) == 0xff;
} else if ((bytes[6] & 0xff) == 0x0 && (bytes[7] & 0xff) == Constant.Command.COMMAND_3B) { //cone used times
coneUsedTimesRes = (bytes[9] & 0xff) == 0xff;
} else if ((bytes[6] & 0xff) == 0x0 && (bytes[7] & 0xff) == Constant.Command.COMMAND_41) { //egg type
eggTypeRes = (bytes[9] & 0xff) == 0xff;
}
}
}
@Override
public void onSerialError(Integer errorCode) {
}
private void showSettingDialog() {
runOnUiThread(() -> settingsDialog = ToastHelper.showTipDialog((ConeSettingActivity.this), R.mipmap.ic_setting, R.string.write_info_now_tips));
}
}

+ 238
- 0
app/src/main/java/com/handset/serialportsensor/activity/DataRecoverActivity.java View File

@ -0,0 +1,238 @@
package com.handset.serialportsensor.activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.utils.DateUtils;
import com.handset.serialportsensor.utils.Slog;
import com.handset.serialportsensor.utils.ToastHelper;
import com.handset.serialportsensor.utils.ExcelMa;
import com.handset.serialportsensor.utils.PersistHelper;
import com.handset.serialportsensor.view.ExportProgressDialog;
import com.handset.serialportsensor.view.LinearLayoutManagerCus;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static com.handset.serialportsensor.utils.DateStyle.YYYY_MM_DD_HH_MM_SS;
/**
* Created by zy on 2019/3/11.
*/
public class DataRecoverActivity extends BaseActivity {
private final String TAG = getClass().getSimpleName();
private RecyclerView mRecyclerView;
private MyAdapter myAdapter;
boolean isRecovering = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recover_data);
TextView tvTitle = findViewById(R.id.title_text);
ImageView ivBack = findViewById(R.id.title_back);
tvTitle.setText(R.string.data_recovery);
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View v) -> onBackPressed());
findViewById(R.id.btn_sure).setOnClickListener((View v) -> {
int index = myAdapter.getSelectIndex();
if (index != -1) {
showRecoverConfirm(index);
}
});
mRecyclerView = findViewById(R.id.recycle_view);
mRecyclerView.setLayoutManager(new LinearLayoutManagerCus((this)));
DefaultItemAnimator animator = new DefaultItemAnimator();
animator.setRemoveDuration(1000);
mRecyclerView.setItemAnimator(animator);
getLocalFiles();
}
ExcelMa excelMa = new ExcelMa();
boolean recoverStatus = true;
private void recoverExcel(final int index) {
if (mFiles != null) {
mExportProgressDialog = null;
new Thread(() ->
excelMa.onReadClick(mFiles.get(index), new PersistHelper.ExportCallback() {
@Override
public void exportProgress(int counts, int remain) {
updateView(counts, remain);
recoverStatus = true;
}
@Override
public void finish(int counts, int remain) {
if (remain != 0) {
showCancelTip();
recoverStatus = true;
} else {
recoverStatus = false;
}
}
})
).start();
}
}
private void showCancelTip() {
runOnUiThread(() -> {
AlertDialog alertDialog = ToastHelper.showTipDialogNoShow((DataRecoverActivity.this), R.mipmap.chuchang_gray, R.string.cancel);
showDialog(alertDialog);
disMissDialogDelay(alertDialog, (3000));
});
}
private void showRecoverConfirm(final int index) {
runOnUiThread(() -> {
dismissDialog((null));
showExportProgress((0), (0));
AlertDialog a = ToastHelper.showChooseDialogNoShow(getString(R.string.data_recovery_confirm), R.mipmap.ic_exclamation_mark,
getString(R.string.recover_data_alarm), getResources().getColor(R.color.button),
getString(R.string.confirm), getString(R.string.cancel), (DataRecoverActivity.this), new ToastHelper.OnDialogClickListener() {
@Override
public void onOKClickListener(View view) {
recoverExcel(index);
}
@Override
public void onCancelClickListener(View view) {
}
});
showDialog(a);
});
}
public void updateView(int counts, int remain) {
showExportProgress(counts, remain);
}
ExportProgressDialog mExportProgressDialog;
private void showExportProgress(final int count, final int remain) {
if (mExportProgressDialog == null) {
runOnUiThread(() -> {
mExportProgressDialog = new ExportProgressDialog();
mExportProgressDialog.showExportDialogNoShow((DataRecoverActivity.this),
(View view) -> {
if (recoverStatus) {
excelMa.stopExport();
} else {
DataRecoverActivity.this.finish();
}
}, count, remain, getString(R.string.data_recovering), getString(R.string.recovery_data));
showDialog(mExportProgressDialog.mAlertDialog);
});
} else {
mExportProgressDialog.update((this), count, remain);
}
}
@Override
public void onBackPressed() {
if (!isRecovering) {
DataRecoverActivity.this.finish();
}
}
List<File> mFiles;
private void getLocalFiles() {
mFiles = Slog.getFiles(ExcelMa.getSavePath(), new ArrayList<>());
initData(mFiles);
}
void initData(List<File> list) {
//设置适配器
myAdapter = new MyAdapter(list);
myAdapter.setOnItemClickListener((View view, int position) -> {
});
mRecyclerView.setAdapter(myAdapter);
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvName;
TextView tv_file_size;
TextView tv_end_time;
ImageView ivSelect;
ConstraintLayout cl_content;
ViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_name);
tv_file_size = itemView.findViewById(R.id.tv_file_size);
tv_end_time = itemView.findViewById(R.id.tv_end_time);
ivSelect = itemView.findViewById(R.id.iv_select);
cl_content = itemView.findViewById(R.id.cl_content);
}
}
static class MyAdapter extends RecyclerView.Adapter<ViewHolder> {
List<File> mDataList;
private OnItemClickListener mOnItemClickListener;
int indexSelect = -1;
MyAdapter(List<File> mList) {
this.mDataList = mList;
}
int getSelectIndex() {
return indexSelect;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.revocer_data_item, null, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) {
File f = mDataList.get(viewHolder.getAdapterPosition());
String text = f.length() / (1024) + "kb";
viewHolder.tv_file_size.setText(text);
viewHolder.tvName.setText(f.getName());
viewHolder.tv_end_time.setText(DateUtils.formatMilliesTimestamp(f.lastModified(), YYYY_MM_DD_HH_MM_SS));
if (indexSelect == viewHolder.getAdapterPosition()) {
viewHolder.ivSelect.setImageResource(R.mipmap.ic_selected);
} else {
viewHolder.ivSelect.setImageResource(R.mipmap.ic_default);
}
viewHolder.cl_content.setOnClickListener((View v) -> {
indexSelect = viewHolder.getAdapterPosition();
notifyDataSetChanged();
});
}
@Override
public int getItemCount() {
return mDataList.size();
}
void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = onItemClickListener;
}
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
}

+ 284
- 0
app/src/main/java/com/handset/serialportsensor/activity/HistoryActivity.java View File

@ -0,0 +1,284 @@
package com.handset.serialportsensor.activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.Sensor;
import com.handset.serialportsensor.bean.TestRecordsTotal;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.utils.Utils;
import com.handset.serialportsensor.view.LinearLayoutManagerCus;
import org.kymjs.kjframe.KJDB;
import java.util.List;
public class HistoryActivity extends AppCompatActivity {
private static final String logTag = "HANDSET-JE002-EX";
private boolean delStatus = false;
private RecyclerView mRecyclerView;
private MyAdapter myAdapter;
private LinearLayout llDeleteContent;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
mRecyclerView = findViewById(R.id.recycle_view);
mRecyclerView.setLayoutManager(new LinearLayoutManagerCus(this));
DefaultItemAnimator animator = new DefaultItemAnimator();
animator.setRemoveDuration(1000);
mRecyclerView.setItemAnimator(animator);
initData();
TextView tvTitle = findViewById(R.id.title_text);
ImageView ivBack = findViewById(R.id.title_back);
tvTitle.setText(R.string.test_history);
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View v) -> HistoryActivity.this.finish());
Button btnSelAll = findViewById(R.id.btn_select_all);
btnSelAll.setOnClickListener((View v) -> myAdapter.selAll());
Button btnDelete = findViewById(R.id.btn_delete);
btnDelete.setOnClickListener((View v) -> {
delStatus = false;
llDeleteContent.setVisibility(View.GONE);
myAdapter.delSelected();
});
Button btnCancel = findViewById(R.id.btn_cancel);
btnCancel.setOnClickListener((View v) -> {
llDeleteContent.setVisibility(View.GONE);
myAdapter.setDeleteStatus(false);
delStatus = false;
myAdapter.cancelSelected();
});
llDeleteContent = findViewById(R.id.ll_delete_content);
llDeleteContent.setVisibility(View.GONE);
//initSensor();
}
void initData() {
final List<Sensor> sensors = KJDB.getDefaultInstance().findAll(Sensor.class);
for (Sensor sensor : sensors) {
Log.i(logTag, ("list every sensorId: " + sensor.sensor_id + ", id: " + sensor.id));
}
if (myAdapter == null) {
myAdapter = new MyAdapter(sensors, (View v) -> {
if (delStatus) {
return true;
} else {
delStatus = true;
myAdapter.setDeleteStatus(true);
llDeleteContent.setVisibility(View.VISIBLE);
}
return false;
});
}
myAdapter.setOnItemClickListener((View view, int position) -> {
Intent intent = new Intent((HistoryActivity.this), HistoryDetailActivity.class);
Log.e(logTag, "History Activity id: " + sensors.get(position).id + ", sensorId: " + sensors.get(position).sensor_id);
intent.putExtra(Constant.SENSOR_ID, sensors.get(position).id);
startActivity(intent);
});
mRecyclerView.setAdapter(myAdapter);
}
static class ViewHolder extends RecyclerView.ViewHolder {
private TextView tvEggNum;
private TextView tvEggType;
private TextView tvConeNo;
private TextView tvSensorId;
private TextView tvConeUsedTimes;
private TextView tvPro;
private LinearLayout llItem;
private ImageView ivSelectStatus;
private ViewHolder(@NonNull View itemView) {
super(itemView);
tvEggNum = itemView.findViewById(R.id.tv_his_egg_num);
tvEggType = itemView.findViewById(R.id.tv_his_egg_type);
tvConeNo = itemView.findViewById(R.id.tv_his_cone_no);
tvSensorId = itemView.findViewById(R.id.tv_his_sensor_id);
tvPro = itemView.findViewById(R.id.tv_his_pro);
tvConeUsedTimes = itemView.findViewById(R.id.tv_his_cone_used_times);
llItem = itemView.findViewById(R.id.ll_his_item);
ivSelectStatus = itemView.findViewById(R.id.iv_select_status);
}
}
public static class MyAdapter extends RecyclerView.Adapter<ViewHolder> {
private boolean delStatus = false;
private List<Sensor> mDataList;
private OnItemClickListener mOnItemClickListener;
private View.OnLongClickListener mOnLongClickListener;
MyAdapter(List<Sensor> mList, View.OnLongClickListener longClickListener) {
this.mDataList = mList;
this.mOnLongClickListener = longClickListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.history_item, viewGroup, (false)));
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder viewHolder, final int i) {
final Sensor sensor = mDataList.get(i);
viewHolder.tvEggNum.setText(TextUtils.isEmpty(sensor.egg_id) ? " " : " ".concat(sensor.egg_id));
viewHolder.tvEggType.setText(TextUtils.isEmpty(sensor.egg_type) ? " " : " ".concat(sensor.egg_type));
viewHolder.tvConeNo.setText(TextUtils.isEmpty(sensor.tupe_id) ? " " : " ".concat(sensor.tupe_id));
viewHolder.tvSensorId.setText(Utils.getSensorNoShow(String.valueOf(sensor.sensor_id)));
viewHolder.tvPro.setText(String.valueOf(sensor.sensor_id).length() < 5 ? "" : String.valueOf(String.valueOf(sensor.sensor_id).charAt(4)));
viewHolder.llItem.setOnLongClickListener((View v) -> {
if (mOnLongClickListener != null) {
mOnLongClickListener.onLongClick(v);
}
return false;
});
viewHolder.ivSelectStatus.setVisibility(this.delStatus ? View.VISIBLE : View.GONE);
if (delStatus) {
viewHolder.ivSelectStatus.setImageResource(sensor.tagBackup == 1 ? R.mipmap.ic_selected : R.mipmap.ic_default);
viewHolder.llItem.setOnClickListener((View v) -> {
sensor.tagBackup = sensor.tagBackup == 0 ? 1 : 0;
notifyDataSetChanged();
});
} else {
viewHolder.llItem.setOnClickListener((View v) -> {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(v, viewHolder.getAdapterPosition());
}
});
}
viewHolder.tvConeUsedTimes.setText(" ".concat(TextUtils.isEmpty(sensor.tv_tupe_use_times) ? "0" : sensor.tv_tupe_use_times));
}
@Override
public int getItemCount() {
return mDataList.size();
}
private void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = onItemClickListener;
}
private void setDeleteStatus(boolean delStatus) {
this.delStatus = delStatus;
notifyDataSetChanged();
}
void selAll() {
for (Sensor sensor : mDataList) {
sensor.tagBackup = 1;
}
notifyDataSetChanged();
}
private void delSelected() {
for (int i = mDataList.size() - 1; i >= 0; i--) {
Sensor t = mDataList.get(i);
if (t.tagBackup == 1) {
KJDB.getDefaultInstance().deleteByWhere(TestRecordsTotal.class, "sensor_id = " + t.sensor_id);
KJDB.getDefaultInstance().deleteById(Sensor.class, t.id);
mDataList.remove(i);
}
}
delStatus = false;
notifyDataSetChanged();
}
private void cancelSelected() {
for (Sensor sensor : mDataList) {
sensor.tagBackup = 0;
}
}
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
@SuppressWarnings(value = "all")
void initSensor() {
Sensor sensor = new Sensor();
sensor.id = 1;
sensor.egg_id = "EGG1";
sensor.sensor_id = 19011111;
sensor.egg_type = "EGGA";
sensor.tupe_id = "TUPEA";
KJDB.getDefaultInstance().save(sensor);
sensor.id = 2;
sensor.egg_id = "EGG2";
sensor.sensor_id = 19011112;
sensor.egg_type = "EGGB";
sensor.tupe_id = "TUPEB";
KJDB.getDefaultInstance().save(sensor);
TestRecordsTotal testRecordsTotal = new TestRecordsTotal();
int i = 1;
for (; i < 25; i++) {
testRecordsTotal.id = i;
testRecordsTotal.end_time = System.currentTimeMillis();
testRecordsTotal.Hum = 80;
testRecordsTotal.sensor_id = 1;
testRecordsTotal.pressure_yacha = 100;
testRecordsTotal.pressurein = 90;
testRecordsTotal.pressureout = 120;
testRecordsTotal.temp = 50;
testRecordsTotal.Hum20 = 90;
testRecordsTotal.pressurein20 = 20;
testRecordsTotal.tupe_use_times = "10";
KJDB.getDefaultInstance().save(testRecordsTotal);
}
i = 1;
for (; i < 25; i++) {
testRecordsTotal.id = i;
testRecordsTotal.Hum = 80;
testRecordsTotal.sensor_id = 1;
testRecordsTotal.pressure_yacha = 100;
testRecordsTotal.pressurein = 90;
testRecordsTotal.pressureout = 120;
testRecordsTotal.temp = 50;
testRecordsTotal.Hum20 = 90;
testRecordsTotal.pressurein20 = 20;
testRecordsTotal.tupe_use_times = "10";
KJDB.getDefaultInstance().save(testRecordsTotal);
}
i = 1;
for (; i < 25; i++) {
testRecordsTotal.id = i;
testRecordsTotal.end_time = System.currentTimeMillis() - 2 * 24 * 60 * 60 * 1000;
testRecordsTotal.Hum = 80;
testRecordsTotal.sensor_id = 1;
testRecordsTotal.pressure_yacha = 100;
testRecordsTotal.pressurein = 90;
testRecordsTotal.pressureout = 120;
testRecordsTotal.temp = 50;
testRecordsTotal.Hum20 = 90;
testRecordsTotal.pressurein20 = 20;
testRecordsTotal.tupe_use_times = "10";
KJDB.getDefaultInstance().save(testRecordsTotal);
}
}
}

+ 482
- 0
app/src/main/java/com/handset/serialportsensor/activity/HistoryDetailActivity.java View File

@ -0,0 +1,482 @@
package com.handset.serialportsensor.activity;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.Sensor;
import com.handset.serialportsensor.bean.TestRecordsTotal;
import com.handset.serialportsensor.bean.ThresholdBean;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.utils.DateUtils;
import com.handset.serialportsensor.utils.SPUtils;
import com.handset.serialportsensor.utils.SpUtil;
import com.handset.serialportsensor.utils.Utils;
import com.handset.serialportsensor.view.AutoLoadMoreListView;
import org.kymjs.kjframe.KJDB;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import static com.handset.serialportsensor.utils.DateStyle.YYYY_MM_DD;
import static com.handset.serialportsensor.utils.DateStyle.YYYY_MM_DD_HH_MM_SS;
/**
* Created by zy on 2019/2/24.
*/
public class HistoryDetailActivity extends AppCompatActivity {
private static final String logTag = "HANDSET-JE002-EX";
private final static int ZERO = 0;
private final static boolean FALSE = false;
private final static boolean TRUE = true;
private final static int REQUEST_START_TIME = 100;
private final static int REQUEST_END_TIME = 101;
private final static int PAGE_SIZE = 8; //每页显示的数据条数
private boolean delStatus = false;
private TextView tvStartTime;
private TextView tvEndTime;
private Sensor mSensor;
private LinearLayout llDeleteContent;
private AutoLoadMoreListView mRecyclerView;
private MyAdapter myAdapter;
private int currentPagedIndex = 0;//当前页码
private TextView etCurPage;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history_detail);
int id = getIntent().getIntExtra(Constant.SENSOR_ID, ZERO);
mSensor = KJDB.getDefaultInstance().findById(id, Sensor.class);
if (mSensor == null) {
finish();
}
initView();
initData();
}
void initView() {
tvStartTime = findViewById(R.id.tv_his_detail_start_time);
tvStartTime.setOnClickListener((View v) -> pickData(REQUEST_START_TIME));
tvStartTime.setEnabled(true);
tvEndTime = findViewById(R.id.tv_his_detail_end_time);
tvEndTime.setOnClickListener((View v) -> pickData(REQUEST_END_TIME));
etCurPage = findViewById(R.id.et_curr_page);
TextView tvTitle = findViewById(R.id.title_text);
ImageView ivBack = findViewById(R.id.title_back);
tvTitle.setText(Utils.getSensorNoShow(String.valueOf(mSensor.sensor_id)));
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View v) -> HistoryDetailActivity.this.finish());
mRecyclerView = findViewById(R.id.recycle_view);
mRecyclerView.setShowLoadMore(true);
mRecyclerView.setLoadMoreListener((AutoLoadMoreListView listView) -> {
Log.d(logTag, "onLoadMoreBegin [listView]:");
if (!loadAll) {
search((true));
}
});
Button btnSelAll = findViewById(R.id.btn_select_all);
btnSelAll.setOnClickListener((View v) -> myAdapter.selAll());
Button btnDelete = findViewById(R.id.btn_delete);
btnDelete.setOnClickListener((View v) -> {
delStatus = false;
llDeleteContent.setVisibility(View.GONE);
myAdapter.delSelected();
});
Button btnCancel = findViewById(R.id.btn_cancel);
btnCancel.setOnClickListener((View v) -> {
llDeleteContent.setVisibility(View.GONE);
myAdapter.setDeleteStatus(false);
delStatus = false;
});
llDeleteContent = findViewById(R.id.ll_delete_content);
llDeleteContent.setVisibility(View.GONE);
}
void initData() {
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH), ZERO, ZERO, ZERO);
long t = calendar.getTimeInMillis();
start_time = t - 31536000000L;
start_time = SPUtils.getInstance(this).get("search_history_start_time", start_time);
calendar.set(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
end_time = calendar.getTimeInMillis();
Log.i(logTag, ("initData, start_time: " + start_time + ", end_time: " + end_time));
end_time = SPUtils.getInstance(this).get("search_history_end_time", end_time);
loadAll = false;
search((false));
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView tvPreIn20;
private TextView tvHumidity20;
private TextView tvTemperature;
private TextView tvHumidity;
private TextView tvPreIn;
private TextView tvPreOut;
private TextView tvProId;
private TextView tvBotLv;
LinearLayout llTemperature;
LinearLayout llHumidity;
LinearLayout llPreIn;
LinearLayout llPreOut;
TextView tvPressureDiff;
TextView tvStartTime;
TextView tvEndTime;
TextView tvItemIndex;
LinearLayout llItem;
ImageView ivSelectStatus;
private ViewHolder(@NonNull View itemView) {
super(itemView);
tvPreIn20 = itemView.findViewById(R.id.tv_in_pre_20);
tvHumidity20 = itemView.findViewById(R.id.tv_shidu20);
tvTemperature = itemView.findViewById(R.id.tv_temp);
tvHumidity = itemView.findViewById(R.id.tv_shidu);
tvPreIn = itemView.findViewById(R.id.tv_pre_in);
tvPreOut = itemView.findViewById(R.id.tv_pre_out);
llTemperature = itemView.findViewById(R.id.ll_temp);
llHumidity = itemView.findViewById(R.id.ll_shidu);
llPreIn = itemView.findViewById(R.id.ll_pre_in);
llPreOut = itemView.findViewById(R.id.ll_pre_out);
tvPressureDiff = itemView.findViewById(R.id.tv_yacha);
tvStartTime = itemView.findViewById(R.id.tv_start_time);
tvEndTime = itemView.findViewById(R.id.tv_end_time);
tvItemIndex = itemView.findViewById(R.id.tv_item_index);
tvProId = itemView.findViewById(R.id.tv_pro_id);
tvBotLv = itemView.findViewById(R.id.tv_botelv);
llItem = itemView.findViewById(R.id.ll_item);
ivSelectStatus = itemView.findViewById(R.id.iv_select_status);
}
}
public static class MyAdapter extends BaseAdapter {
private Context mContext;
private ThresholdBean bean;
private boolean delStatus = false;
private List<TestRecordsTotal> mDataList;
private View.OnLongClickListener mOnLongClickListener;
private void setDataList(List<TestRecordsTotal> mList) {
if (mDataList == null) {
mDataList = new ArrayList<>();
}
mDataList.clear();
mDataList.addAll(mList);
notifyDataSetChanged();
}
private void delSelected() {
for (int i = mDataList.size() - 1; i >= 0; i--) {
TestRecordsTotal t = mDataList.get(i);
if (t.tagBackup == 1) {
KJDB.getDefaultInstance().deleteById(TestRecordsTotal.class, t.id);
mDataList.remove(i);
}
}
this.delStatus = false;
notifyDataSetChanged();
}
private void selAll() {
for (TestRecordsTotal testRecordsTotal : mDataList) {
testRecordsTotal.tagBackup = 1;
}
notifyDataSetChanged();
}
private void setDeleteStatus(boolean status) {
this.delStatus = status;
notifyDataSetChanged();
}
private void appendDataList(List<TestRecordsTotal> mList) {
if (mDataList == null) {
mDataList = new ArrayList<>();
}
mDataList.addAll(mList);
notifyDataSetChanged();
}
private MyAdapter(Context context, List<TestRecordsTotal> mList, View.OnLongClickListener longClickListener) {
this.mDataList = new ArrayList<>();
mDataList.addAll(mList);
mContext = context;
bean = new ThresholdBean();
bean.setTemperatureFloor("-40");
bean.setTemperatureCeiling("65");
bean.setHumidityFloor("0");
bean.setHumidityCeiling("100");
bean.setInnerPressureFloor("80");
bean.setInnerPressureCeiling("150");
bean.setOuterPressureFloor("80");
bean.setOuterPressureCeiling("150");
bean.setDiffPressureFloor("-20");
bean.setDiffPressureCeiling("30");
String bean2 = (String) SpUtil.get(context, Constant.THRESHOLD_KEY, "");
if (!TextUtils.isEmpty(bean2)) {
bean = new Gson().fromJson(bean2, ThresholdBean.class);
}
this.mOnLongClickListener = longClickListener;
}
private void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) {
final TestRecordsTotal sensor = mDataList.get(i);
DecimalFormat df = new DecimalFormat("0.00");
viewHolder.tvHumidity20.setText(df.format(sensor.Hum20));
viewHolder.tvPreIn20.setText(df.format(sensor.pressurein20));
viewHolder.tvTemperature.setText(df.format(sensor.temp));
viewHolder.tvHumidity.setText(df.format(sensor.Hum));
viewHolder.tvPreIn.setText(df.format(sensor.pressurein));
viewHolder.tvPreOut.setText(df.format(sensor.pressureout));
viewHolder.tvPressureDiff.setText(df.format(sensor.pressure_yacha));
String ids = String.valueOf(sensor.sensor_id);
viewHolder.tvProId.setText(ids.length() < 5 ? "" : ids.substring(4, 5));
viewHolder.tvBotLv.setText(sensor.botelv);
viewHolder.tvStartTime.setVisibility(View.GONE);
viewHolder.tvEndTime.setText(DateUtils.formatMilliesTimestamp(sensor.end_time, YYYY_MM_DD_HH_MM_SS));
if (bean != null) {
viewHolder.tvTemperature.setTextColor(Color.parseColor(sensor.temp > Float.parseFloat(bean.getTemperatureFloor()) && sensor.temp < Float.parseFloat(bean.getTemperatureCeiling()) ? "#333333" : "#F02323"));
viewHolder.tvHumidity.setTextColor(Color.parseColor(sensor.Hum > Float.parseFloat(bean.getHumidityFloor()) && sensor.Hum < Float.parseFloat(bean.getHumidityCeiling()) ? "#333333" : "#F02323"));
viewHolder.tvPreIn.setTextColor(Color.parseColor(sensor.pressurein > Float.parseFloat(bean.getInnerPressureFloor()) && sensor.pressurein < Float.parseFloat(bean.getInnerPressureCeiling()) ? "#333333" : "#F02323"));
viewHolder.tvPreOut.setTextColor(Color.parseColor(sensor.pressureout > Float.parseFloat(bean.getOuterPressureFloor()) && sensor.pressureout < Float.parseFloat(bean.getOuterPressureCeiling()) ? "#333333" : "#F02323"));
viewHolder.tvPressureDiff.setTextColor(Color.parseColor(sensor.pressure_yacha > Float.parseFloat(bean.getDiffPressureFloor()) && sensor.pressure_yacha < Float.parseFloat(bean.getDiffPressureCeiling()) ? "#333333" : "#F02323"));
}
viewHolder.llItem.setOnLongClickListener((View v) -> {
if (mOnLongClickListener != null) {
mOnLongClickListener.onLongClick(v);
}
return false;
});
viewHolder.ivSelectStatus.setVisibility(this.delStatus ? View.VISIBLE : View.GONE);
if (this.delStatus) {
viewHolder.ivSelectStatus.setImageResource(sensor.tagBackup == 1 ? R.mipmap.ic_selected : R.mipmap.ic_default);
viewHolder.llItem.setOnClickListener((View v) -> {
sensor.tagBackup = sensor.tagBackup == 0 ? 1 : 0;
notifyDataSetChanged();
});
} else {
viewHolder.llItem.setOnClickListener(null);
}
}
private int getItemCount() {
return mDataList == null ? 0 : mDataList.size();
}
@Override
public int getCount() {
return getItemCount();
}
@Override
public Object getItem(int position) {
return mDataList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.activity_history_detail_item, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
onBindViewHolder(viewHolder, position);
return convertView;
}
}
private void pickData(final int requestCode) {
Calendar calendar2 = Calendar.getInstance();
Log.e(logTag, ("startTime: " + start_time + ", end_time: " + end_time));
calendar2.setTimeInMillis(requestCode == REQUEST_START_TIME ? start_time : end_time);
new DatePickerDialog(this, (DatePicker view, int year, int month, int dayOfMonth) -> {
Calendar calendar = Calendar.getInstance();
long t = calendar.getTimeInMillis();
if (requestCode == REQUEST_END_TIME) {
calendar.set(year, month, dayOfMonth, 23, 59, 59);
if (t == 0) {
Toast.makeText(HistoryDetailActivity.this, "请选择结束时间", Toast.LENGTH_SHORT).show();
} else {
t = calendar.getTimeInMillis();
end_time = t;
SPUtils.getInstance(HistoryDetailActivity.this).put("search_history_end_time", end_time);
}
loadAll = false;
search(false);
} else if (requestCode == REQUEST_START_TIME) {
calendar.set(year, month, dayOfMonth, 0, 0, 0);
if (t == 0) {
Toast.makeText(HistoryDetailActivity.this, "请选择开始时间", Toast.LENGTH_SHORT).show();
} else {
t = calendar.getTimeInMillis();
start_time = t;
SPUtils.getInstance(HistoryDetailActivity.this).put("search_history_start_time", start_time);
}
loadAll = false;
search(false);
}
}, calendar2.get(Calendar.YEAR), calendar2.get(Calendar.MONTH), calendar2.get(Calendar.DAY_OF_MONTH)).show();
}
long start_time = 0;
long end_time = 0;
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Log.d(logTag, ("result ok"));
}
}
public long findStartId(long start_time, long end_time) {//查找perPageItems条
if (start_time > end_time) return 0;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(end_time);
long startDatT = calendar.get(Calendar.DAY_OF_YEAR) + calendar.get(Calendar.YEAR) * 1000;
List<TestRecordsTotal> t = KJDB.getDefaultInstance().findAllByWhere(TestRecordsTotal.class, "day_t = " + startDatT + " And sensor_id = " + mSensor.sensor_id, "end_time desc");
long curId;
if (t != null && t.size() > 0) {
curId = t.get(0).id;
for (int i = 1; i < t.size(); i++) {
long tempId = t.get(i).id;
if (curId < tempId) {
curId = tempId;
}
}
return curId;
}
return findStartId(start_time, end_time - 24 * 3600000);
}
public TestRecordsTotal findNextItem(long start_time, long end_time) {
if (startId <= 0) {
return null;
}
TestRecordsTotal t = KJDB.getDefaultInstance().findById(startId, TestRecordsTotal.class);
startId--;
if (t != null) {
if (t.end_time >= start_time && t.end_time <= end_time) {
if (t.sensor_id != mSensor.sensor_id) {
return findNextItem(start_time, end_time);
}
return t;
}
} else {
return findNextItem(start_time, end_time);
}
return null;
}
long startId = 0;
boolean loadAll = false;
private void search(boolean append) {
if (!append) {
startId = 0;
}
if (start_time >= end_time) {
return;
}
tvStartTime.setText(DateUtils.formatMilliesTimestamp(start_time, YYYY_MM_DD));
tvEndTime.setText(DateUtils.formatMilliesTimestamp(end_time, YYYY_MM_DD));
if (startId == 0) {
startId = findStartId(start_time, end_time);
}
List<TestRecordsTotal> testRecordsTotals = new ArrayList<>();
boolean tagLoadMore = true;
if (startId != 0) {
for (int i = 0; i < PAGE_SIZE; i++) {
TestRecordsTotal t = findNextItem(start_time, end_time);
if (t != null) {
testRecordsTotals.add(t);
}
}
}
if (testRecordsTotals.size() < PAGE_SIZE) {
tagLoadMore = false;
}
String curPageIndex = String.valueOf(currentPagedIndex + 1);
etCurPage.setText(curPageIndex);
mRecyclerView.setShowLoadMore(tagLoadMore);
updateListView(testRecordsTotals, append);
mRecyclerView.loadMoreComplete();
}
void updateListView(List<TestRecordsTotal> list, boolean append) {
if (myAdapter == null) {
myAdapter = new MyAdapter((this), list, (View v) -> {
if (delStatus) {
return true;
}
delStatus = true;
myAdapter.setDeleteStatus(true);
llDeleteContent.setVisibility(View.VISIBLE);
return false;
});
mRecyclerView.setAdapter(myAdapter);
} else {
if (append) {
myAdapter.appendDataList(list);
} else {
myAdapter.setDataList(list);
}
}
}
}

+ 253
- 0
app/src/main/java/com/handset/serialportsensor/activity/LoginActivity.java View File

@ -0,0 +1,253 @@
package com.handset.serialportsensor.activity;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.blankj.utilcode.util.ToastUtils;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.account.AccountManager;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.presenter.SurfaceContract;
import com.handset.serialportsensor.presenter.SurfacePresenter;
import com.handset.serialportsensor.utils.ToastHelper;
import com.handset.serialportsensor.utils.SPUtils;
public class LoginActivity extends BaseActivity implements SurfaceContract.ISerialView/*implements ServiceConnection, SerialService.OnReadValueCallback, SerialService.OnMateBaudRateCallback*/ {
private static final String logTag = "HANDSET-JE002-EX";
private static int role = Constant.SENIOR_ROLE;
private static final int DIALOG_TIMEOUT = 30000;
private static final int READ_TIMEOUT = 3000;
private Boolean isReady = false;
private Integer baudRate;
private EditText etUserName;
private EditText etPwd;
private AlertDialog alertDialog;
private SurfacePresenter mPresenter;
private Handler mHandlerIdRead = new Handler();
Handler mHandlerAlertDialog = new Handler();
private Runnable mRunnableIdRead, mRunnableAlertDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ImageView ivBack = findViewById(R.id.title_back);
findViewById(R.id.title_layout).setBackground(null);
ivBack.setVisibility(View.VISIBLE);
ivBack.setImageResource(R.mipmap.img_back);
ivBack.setOnClickListener((View view) -> finish());
etPwd = findViewById(R.id.et_pwd);
etUserName = findViewById(R.id.et_user_name);
findViewById(R.id.btn_login).setOnClickListener((View view) -> login());
mPresenter = new SurfacePresenter(this);
checkLoginStatus();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStop() {
super.onStop();
//mHandlerAlertDialog.removeCallbacks(mRunnableAlertDialog);
}
@Override
protected void onDestroy() {
super.onDestroy();
//mHandlerAlertDialog.removeCallbacks(mRunnableAlertDialog);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager im = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
if(im != null) {
View view = getCurrentFocus();
if(view != null) {
im.hideSoftInputFromWindow(getCurrentFocus().getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
return super.onTouchEvent(event);
}
private void login() {
if (checkoutLoginInfo()) {
Log.i(logTag, ("auth ok, go to setting view."));
alertDialog = ToastHelper.showTipDialog((this), R.mipmap.img_loading, R.string.identifying);
new Thread(
() -> {
Looper.prepare();
new Handler().postDelayed(() -> mPresenter.open(), (1000));
Looper.loop();
}
).start();
mRunnableAlertDialog = () -> {
Log.i(logTag, ("alertDialog force close!"));
alertDialog.dismiss();
};
mHandlerAlertDialog.postDelayed(mRunnableAlertDialog, DIALOG_TIMEOUT);
}
}
@Override
public void onSerialOpen(boolean isOpen) {
runOnUiThread(() -> {
if (isOpen) {
mRunnableIdRead = () -> {
String cmd = genCmd(("FFFFFFFF"), Constant.Command.COMMAND_25);
Log.e(logTag, "login activity cmd: " + cmd);
mPresenter.write(cmd);
new Thread(
() -> {
Looper.prepare();
new Handler().postDelayed(() -> {
Log.i(logTag, ("login fetching sensor no ready: " + isReady));
if (!isReady) {
Log.e(logTag, ("login watch dog check, no data report!"));
runOnUiThread(() -> {
ToastUtils.showShort(R.string.test_id_error);
if(alertDialog.isShowing()) {
alertDialog.dismiss();
}
mHandlerAlertDialog.removeCallbacks(mRunnableAlertDialog);
LoginActivity.this.finish();
new Thread(
() -> {
Looper.prepare();
new Handler().post(() -> {
mPresenter.close();
});
Looper.loop();
}
).start();
});
} else {
Log.i(logTag, ("login watch dog check, data report normally"));
}
}, (1000));
Looper.loop();
}
).start();
//mPresenter.write("DDDDFFFFFFFF0025003E90");
};
mHandlerIdRead.postDelayed(mRunnableIdRead, READ_TIMEOUT);
} else {
Log.i(logTag, "port is closing!");
}
});
}
@Override
public void onSerialBaudRate(Integer baudRate) {
this.baudRate = baudRate;
}
@Override
public void onSerialData(RawData rawData) {
if (rawData.getItemType() == RawData.TYPE_RECEIVE) {
String data = rawData.getMessage();
Log.i(logTag, ("LoginActivity onSerialData: " + data));
if (data.length() == 22) {
isReady = true;
alertDialog.dismiss();
mHandlerAlertDialog.removeCallbacks(mRunnableAlertDialog);
mPresenter.close();
boolean isRoot = AccountManager.get().getUserId().equals("root");
boolean sensorThirdEnable = SPUtils.getInstance(this).get(("sensor_third_enable"), (false));
boolean isOwn = isOwnSensor(data);
Log.i(logTag, ("onSerialData: isRoot: " + isRoot + ", sensorThirdEnable: " + sensorThirdEnable + ", isOwn: " + isOwn));
int roleType = (isRoot || sensorThirdEnable || isOwn) ? Constant.SENIOR_ROLE : Constant.NOT_CONNECTED_ROLE;
SensorSettingsActivity.open(this.baudRate, roleType, data.substring(4, 12), (LoginActivity.this));
LoginActivity.this.finish();
}
}
}
private boolean isOwnSensor(String data) {
byte[] bytes = ByteUtils.hexStrToBytes(data.substring(0, data.length() - 4));
int no = ((bytes[2] & 0xff) * 100 + (bytes[3] & 0xff)) * 10000 + ((bytes[4] & 0xff) << 8) + (bytes[5] & 0xff);
String s = "00000000".concat(String.valueOf(no));
String sensorNo = s.substring(s.length() - 8);
Log.i(logTag, ("isThirdSensor: " + sensorNo + ", position[4]: " + sensorNo.charAt(4)));
return sensorNo.charAt(4) == '1';
}
@Override
public void onSerialError(Integer errorCode) {
runOnUiThread(() -> {
ToastUtils.showShort(R.string.test_btl_error);
mPresenter.close();
alertDialog.dismiss();
LoginActivity.this.finish();
});
}
private void checkLoginStatus() {
if (AccountManager.get().isLogin()) {
login();
}
}
private boolean checkoutLoginInfo() {
if (AccountManager.get().isLogin()) {
return true;
}
String pwd = etPwd.getText().toString();
String username = etUserName.getText().toString();
if (TextUtils.isEmpty(username)) {
Toast.makeText((this), "登录失败,用户名为空", Toast.LENGTH_SHORT).show();
return false;
}
if (TextUtils.isEmpty(pwd)) {
Toast.makeText((this), "登录失败,密码为空", Toast.LENGTH_SHORT).show();
return false;
}
String pwdSp = SPUtils.getInstance(this).get(username);
Log.i(logTag, "pwdSp: " + pwdSp + ", username: " + username);
if (TextUtils.isEmpty(pwdSp)) {
if ("root".equals(username) && "root".equals(pwd)) {
Toast.makeText((this), "root 登录成功", Toast.LENGTH_SHORT).show();
AccountManager.get().login("root", "root");
return true;
}
if ("admin".equals(username) && "admin".equals(pwd)) {
AccountManager.get().login("admin", "admin");
Toast.makeText((this), "admin 登录成功", Toast.LENGTH_SHORT).show();
return true;
}
} else {
if (pwdSp.equals(pwd)) {
AccountManager.get().login(username, pwdSp);
Toast.makeText((this), username + " 登录成功", Toast.LENGTH_SHORT).show();
return true;
}
}
Toast.makeText((this), "登录失败,用户名或密码错误", Toast.LENGTH_SHORT).show();
return false;
}
}

+ 624
- 0
app/src/main/java/com/handset/serialportsensor/activity/Main2Activity.java View File

@ -0,0 +1,624 @@
package com.handset.serialportsensor.activity;
import android.Manifest;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.blankj.utilcode.util.ToastUtils;
import com.google.common.base.Splitter;
import com.google.gson.Gson;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportsensor.bean.MetaData;
import com.handset.serialportsensor.bean.ThresholdBean;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.presenter.SurfaceContract;
import com.handset.serialportsensor.presenter.SurfacePresenter;
import com.handset.serialportsensor.utils.Slog;
import com.handset.serialportsensor.utils.SpUtil;
import com.handset.serialportsensor.utils.ToastHelper;
import com.handset.serialportsensor.utils.PersistHelper;
import com.handset.serialportsensor.utils.StatusBarUtils;
import com.handset.serialportsensor.utils.Utils;
import com.handset.serialportsensor.widget.DashBoard;
import java.text.DecimalFormat;
public class Main2Activity extends BaseActivity implements SurfaceContract.ISerialView {
private static final String logTag = "HANDSET-JE002-EX";
private Integer baudRate = 38400;
private final static String FLOAT_TYPE = "0.00";
private final static int STARTING_TIMEOUT = 3000;
private final static int SAVING_TIMEOUT = 7000;
private final static int WATCHDOG_TIMEOUT = 1000;
private static boolean readBtnStatusOpen = false;
private final static String DEFAULT_VALUE = "- - -";
private static ThresholdBean thresholdBean;
private SurfacePresenter mPresenter;
private static MetaData metaData = MetaData.builder().build();
private DashBoard mDashBoardTemperature;
private DashBoard mDashBoardHumidity;
private DashBoard mDashBoardInnerPressure;
private DashBoard mDashBoardOuterPressure;
private DashBoard mDashBoardDiffPressure;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private Handler mHandlerResetReadBtn = new Handler();
private Runnable mRunnableResetReadBtn;
private Handler mHandlerSaveClose = new Handler();
private Runnable mRunnableSaveClose;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StatusBarUtils.setTranslucentStatus(this);
StatusBarUtils.setStatusColor((this), (false), (true), R.color.white);
setContentView(R.layout.activity_main2);
initView();
disableSettingBtn();
thresholdBean = new Gson().fromJson((String) SpUtil.get((this), Constant.THRESHOLD_KEY, ("")), ThresholdBean.class);
if (thresholdBean == null) {
Log.i(logTag, ("onCreate: thresholdBean null"));
thresholdBean = ThresholdBean.builder()
.temperatureFloor("-40").temperatureCeiling("65")
.humidityFloor("0").humidityCeiling("100")
.innerPressureFloor("80").innerPressureCeiling("150")
.outerPressureFloor("80").outerPressureCeiling("150")
.diffPressureFloor("-20").diffPressureCeiling("30")
.build();
}
SpUtil.put((this), Constant.THRESHOLD_KEY, new Gson().toJson(thresholdBean));
Slog.i(logTag, ("onCreate, thresholdBean value: " + thresholdBean));
//Slog.save(logTag, ("onCreate, thresholdBean value: " + thresholdBean));
mPresenter = new SurfacePresenter((this));
mPresenter.initBLNStatus('0');
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission((this), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((this), PERMISSIONS_STORAGE, (1));
}
}
// emulator
//initEmulator();
}
@Override
protected void onPause() {
super.onPause();
Log.i(logTag, ("onPause, close bln"));
}
@Override
protected void onResume() {
super.onResume();
Slog.i(logTag, ("onResume, open bln"));
thresholdBean = new Gson().fromJson((String) SpUtil.get((this), Constant.THRESHOLD_KEY, ("")), ThresholdBean.class);
if (thresholdBean == null) {
Log.i(logTag, ("onResume: thresholdBean null"));
}
if (thresholdBean != null) {
if (mDashBoardTemperature != null && mDashBoardTemperature.textStart != null) {
mDashBoardTemperature.textStart = thresholdBean.temperatureFloor;
}
if (mDashBoardTemperature != null && mDashBoardTemperature.textEnd != null) {
mDashBoardTemperature.textEnd = thresholdBean.temperatureCeiling;
}
//
if (mDashBoardHumidity != null && mDashBoardHumidity.textStart != null) {
mDashBoardHumidity.textStart = thresholdBean.humidityFloor;
}
if (mDashBoardHumidity != null && mDashBoardHumidity.textEnd != null) {
mDashBoardHumidity.textEnd = thresholdBean.humidityCeiling;
}
//
if (mDashBoardInnerPressure != null && mDashBoardInnerPressure.textStart != null) {
mDashBoardInnerPressure.textStart = thresholdBean.innerPressureFloor;
}
if (mDashBoardInnerPressure != null && mDashBoardInnerPressure.textEnd != null) {
mDashBoardInnerPressure.textEnd = thresholdBean.innerPressureCeiling;
}
//
if (mDashBoardOuterPressure != null && mDashBoardOuterPressure.textStart != null) {
mDashBoardOuterPressure.textStart = thresholdBean.outerPressureFloor;
}
if (mDashBoardOuterPressure != null && mDashBoardOuterPressure.textEnd != null) {
mDashBoardOuterPressure.textEnd = thresholdBean.outerPressureCeiling;
}
//
if (mDashBoardDiffPressure != null && mDashBoardDiffPressure.textStart != null) {
mDashBoardDiffPressure.textStart = thresholdBean.diffPressureFloor;
}
if (mDashBoardDiffPressure != null && mDashBoardDiffPressure.textEnd != null) {
mDashBoardDiffPressure.textEnd = thresholdBean.diffPressureCeiling;
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(logTag, ("main activity destroy"));
mHandlerResetReadBtn.removeCallbacks(mRunnableResetReadBtn);
mPresenter.close();
mPresenter.onDestroy();
}
private void initView() {
mDashBoardTemperature = findViewById(R.id.dashboard_temperature);
mDashBoardHumidity = findViewById(R.id.dashboard_humidity);
mDashBoardInnerPressure = findViewById(R.id.dashboard_inner_pressure);
mDashBoardOuterPressure = findViewById(R.id.dashboard_outer_pressure);
mDashBoardDiffPressure = findViewById(R.id.dashboard_diff_pressure);
}
@SuppressWarnings(value = "unused")
private void initEmulator() {
mDashBoardTemperature.setSecondText("26.97");
mDashBoardHumidity.setSecondText("31.61");
mDashBoardInnerPressure.setSecondText("102.55");
mDashBoardDiffPressure.setSecondText("-0.76");
mDashBoardOuterPressure.setSecondText("103.32");
}
private void disableSettingBtn() {
ImageView ivSettings = findViewById(R.id.title_back);
ivSettings.setImageResource(R.mipmap.settings_disable);
ivSettings.setEnabled(false);
}
private void enableSettingBtn() {
ImageView ivSettings = findViewById(R.id.title_back);
ivSettings.setImageResource(R.mipmap.settings);
ivSettings.setEnabled(true);
}
private void disableHistoryBtn() {
ImageView ivSettings = findViewById(R.id.iv_start);
ivSettings.setImageResource(R.mipmap.history_disable);
ivSettings.setEnabled(false);
}
private void enableHistoryBtn() {
ImageView ivSettings = findViewById(R.id.iv_start);
ivSettings.setImageResource(R.mipmap.history);
ivSettings.setEnabled(true);
}
public void onClickBtnRead(View view) {
clearDashBoard();
if (!readBtnStatusOpen) {
disableSettingBtn();
disableHistoryBtn();
readBtnToStartingState();
new Thread(
() -> {
Looper.prepare();
new Handler().post(() -> mPresenter.open());
Looper.loop();
}
).start();
} else {
mPresenter.close();
resetStatus();
showStopTestDialog();
}
}
private void showStopTestDialog() {
ToastHelper.showSaveSensorDialog((this), new ToastHelper.OnDialogClickListener() {
@Override
public void onOKClickListener(View view) {
PersistHelper.endTest();
showSavingDataDialog();
}
@Override
public void onCancelClickListener(View view) {
PersistHelper.endTest((false));
showCancelingDataDialog();
}
});
}
private void showSavingDataDialog() {
runOnUiThread(() -> {
AlertDialog alertDialog = ToastHelper.showTipDialog((Main2Activity.this), R.mipmap.img_loading, R.string.saving);
mRunnableSaveClose = alertDialog::dismiss;
mHandlerSaveClose.postDelayed(mRunnableSaveClose, SAVING_TIMEOUT);
});
}
private void showCancelingDataDialog() {
runOnUiThread(() -> {
AlertDialog alertDialog = ToastHelper.showTipDialog((Main2Activity.this), R.mipmap.img_loading, R.string.canceling);
mRunnableSaveClose = alertDialog::dismiss;
mHandlerSaveClose.postDelayed(mRunnableSaveClose, SAVING_TIMEOUT);
});
}
public void onClickSettingBtn(View view) {
startActivity(new Intent((Main2Activity.this), LoginActivity.class));
}
public void onClickHistoryBtn(View view) {
startActivity(new Intent((Main2Activity.this), HistoryActivity.class));
}
@Override
public void onSerialOpen(boolean isOpen) {
runOnUiThread(() -> {
readBtnStatusOpen = isOpen;
if (isOpen) {
mRunnableResetReadBtn = () -> {
mPresenter.write(genCmd(("FFFFFFFF"), Constant.Command.COMMAND_25));
new Thread(
() -> {
Looper.prepare();
new Handler().postDelayed(() -> {
Log.i(logTag, ("metaData sensorNo: " + metaData.getSensorNo()));
if (TextUtils.isEmpty(metaData.getSensorNo())) {
Log.e(logTag, ("watch dog check, no data report!"));
runOnUiThread(() -> {
ToastUtils.showShort(R.string.test_id_error);
new Thread(
() -> {
Looper.prepare();
new Handler().post(() -> {
mPresenter.close();
});
Looper.loop();
}
).start();
});
} else {
Log.i(logTag, ("watch dog check, data report normally"));
runOnUiThread(this::readBtnToStopState);
}
}, WATCHDOG_TIMEOUT);
Looper.loop();
}
).start();
};
mHandlerResetReadBtn.postDelayed(mRunnableResetReadBtn, STARTING_TIMEOUT);
} else {
Log.i(logTag, ("Testing closing"));
metaData.resetData();
readBtnToState((false));
//enableSettingBtn();
enableHistoryBtn();
}
});
}
@Override
public void onSerialBaudRate(Integer baudRate) {
this.baudRate = baudRate;
}
@Override
public void onSerialData(RawData rawData) {
String message = rawData.getMessage();
boolean res = rawData.getItemType() == RawData.TYPE_SEND
? doSendMessage(message)
: doReceiveMessage(message);
Log.v(logTag, ("res: " + res));
}
@Override
public void onSerialError(Integer errorCode) {
runOnUiThread(() -> {
ToastUtils.showShort(R.string.test_btl_error);
readBtnToOriginState();
//enableSettingBtn();
enableHistoryBtn();
});
}
private void setMakerNoView(int text) {
((TextView) (findViewById(R.id.tv_maker))).setText(String.valueOf(text));
}
private void setSensorNoView(String text) {
//String textCooked = text.substring(0, 4) + text.substring(5);
((TextView) (findViewById(R.id.tv_sensor_no))).setText(text);
}
private void setEggNoView(String text) {
((TextView) (findViewById(R.id.tv_egg_no))).setText(text);
}
private void setEggTypeView(String text) {
((TextView) (findViewById(R.id.tv_egg_type))).setText(text);
}
private void setConeNoView(String text) {
((TextView) (findViewById(R.id.tv_cone_no))).setText(text);
}
private void setConeUsedTimesView(String text) {
((TextView) (findViewById(R.id.tv_cone_used_times))).setText(text);
}
private boolean doReceiveMessage(String contain) {
try {
Log.i(logTag, ("doReceiveMessage: " + contain));
if (contain.length() < 100) {
doCalcBasicData(contain);
} else {
metaData.resetData20Degree();
for (String data : Splitter.fixedLength(30).split(contain)) {
metaData.doCalcMeta(data);
}
metaData.doCalcMetaEx();
boolean valid = metaData.isValid();
Log.i(logTag, "valid: " + valid);
if (!valid) {
//setStatusAbnormal();
return false;
}
doPersist(metaData);
setDashBoard(metaData);
//setStatusNormal();
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private boolean doSendMessage(String message) {
Log.v(logTag, ("Activity send message: " + message));
return true;
}
private void doCalcBasicData(String data) {
byte[] bytes = ByteUtils.hexStrToBytes(data.substring(0, data.length() - 4));
switch (bytes[7] & 0xff) {
case Constant.Command.COMMAND_26:
metaData.setMakerId(getMakerId(bytes));
metaData.setSensorNo(getSensorNo(bytes));
metaData.setSensorNoRadix(getSensorNoRadix(bytes));
setMakerNoView(metaData.getMakerId());
setSensorNoView(Utils.getSensorNoShow(metaData.getSensorNo()));
Log.e(logTag, "sensorNo: " + metaData.getSensorNo());
PersistHelper.genItem(Integer.valueOf(metaData.getSensorNo()), String.valueOf(this.baudRate));
//mPresenter.write(genCmd(metaData.getSensorNoRadix(), Constant.Command.COMMAND_27));
break;
case Constant.Command.COMMAND_28:
mPresenter.write(genCmd(metaData.getSensorNoRadix(), Constant.Command.COMMAND_30));
break;
case Constant.Command.COMMAND_31:
metaData.setEggNo(getEggNo(bytes));
setEggNoView(metaData.getEggNo());
PersistHelper.saveEggID(metaData.getEggNo());
mPresenter.write(genCmd(metaData.getSensorNoRadix(), Constant.Command.COMMAND_3E));
break;
case Constant.Command.COMMAND_3F:
metaData.setEggType(getEggType(bytes));
setEggTypeView(metaData.getEggType());
PersistHelper.saveEggType(metaData.getEggType());
mPresenter.write(genCmd(metaData.getSensorNoRadix(), Constant.Command.COMMAND_34));
break;
case Constant.Command.COMMAND_35:
metaData.setConeNo(getConeNo(bytes));
setConeNoView(metaData.getConeNo());
PersistHelper.saveConeNo(metaData.getConeNo());
Log.i(logTag, "sensorNoRadix: " + metaData.getSensorNoRadix());
mPresenter.write(genCmd(metaData.getSensorNoRadix(), Constant.Command.COMMAND_38));
break;
case Constant.Command.COMMAND_39:
metaData.setConeUsedTimes(getConeUsedTimes(bytes));
setConeUsedTimesView(metaData.getConeUsedTimes());
PersistHelper.saveConeUsedTimes(metaData.getConeUsedTimes());
break;
}
}
private int getMakerId(byte[] bytes) {
int i = ((bytes[4] & 0xff) << 8) | (bytes[5] & 0xff);
String s = "0000".concat(String.valueOf(i));
String s2 = s.substring(s.length() - 4);
return Integer.valueOf(s2.substring(0, 1));
}
private String getSensorNo(byte[] bytes) {
int no = ((bytes[2] & 0xff) * 100 + (bytes[3] & 0xff)) * 10000 + ((bytes[4] & 0xff) << 8) + (bytes[5] & 0xff);
String s = "00000000".concat(String.valueOf(no));
return s.substring(s.length() - 8);
}
private String getSensorNoRadix(byte[] bytes) {
int len = 4;
byte[] dest = new byte[len];
System.arraycopy(bytes, 2, dest, 0, len);
return ByteUtils.bytesToHexStr(dest);
}
private String getEggNo(byte[] bytes) {
int len = bytes[8];
byte[] dest = new byte[len];
System.arraycopy(bytes, 9, dest, 0, len);
ByteUtils.bytesToAscii(dest);
return ByteUtils.bytesToAscii(dest);
}
private String getEggType(byte[] bytes) {
int len = bytes[8];
byte[] dest = new byte[len];
System.arraycopy(bytes, 9, dest, 0, len);
ByteUtils.bytesToAscii(dest);
return ByteUtils.bytesToAscii(dest);
}
private String getConeNo(byte[] bytes) {
int len = bytes[8];
byte[] dest = new byte[len];
System.arraycopy(bytes, 9, dest, 0, len);
ByteUtils.bytesToAscii(dest);
return ByteUtils.bytesToAscii(dest);
}
private String getConeUsedTimes(byte[] bytes) {
int len = bytes[8];
byte[] dest = new byte[len];
System.arraycopy(bytes, 9, dest, 0, len);
ByteUtils.bytesToAscii(dest);
return ByteUtils.bytesToAscii(dest);
}
private void clearDashBoard() {
mDashBoardTemperature.setSecondText(DEFAULT_VALUE);
mDashBoardHumidity.setSecondText(DEFAULT_VALUE);
mDashBoardInnerPressure.setSecondText(DEFAULT_VALUE);
mDashBoardOuterPressure.setSecondText(DEFAULT_VALUE);
mDashBoardDiffPressure.setSecondText(DEFAULT_VALUE);
((TextView) (findViewById(R.id.tv_20degree_humidity))).setText(DEFAULT_VALUE);
((TextView) (findViewById(R.id.tv_20degree_inner_press))).setText(DEFAULT_VALUE);
((TextView) (findViewById(R.id.tv_maker))).setText(DEFAULT_VALUE);
((TextView) (findViewById(R.id.tv_sensor_no))).setText(DEFAULT_VALUE);
((TextView) (findViewById(R.id.tv_egg_no))).setText(DEFAULT_VALUE);
((TextView) (findViewById(R.id.tv_egg_type))).setText(DEFAULT_VALUE);
((TextView) (findViewById(R.id.tv_cone_no))).setText(DEFAULT_VALUE);
((TextView) (findViewById(R.id.tv_cone_used_times))).setText(DEFAULT_VALUE);
}
private void setDashBoard(MetaData metaData) {
boolean isNormal = true;
if (thresholdBean == null) {
Log.i(logTag, "thresholdBean is null");
}
if (metaData.getTemperature() < Float.valueOf(thresholdBean.getTemperatureFloor()) || metaData.getTemperature() > Float.valueOf(thresholdBean.getTemperatureCeiling())) {
isNormal = false;
mDashBoardTemperature.setSecondText(metaData.getTemperature(), (false));
} else {
mDashBoardTemperature.setSecondText(metaData.getTemperature(), (true));
}
if (metaData.getHumidity() < Float.valueOf(thresholdBean.getHumidityFloor()) || metaData.getHumidity() > Float.valueOf(thresholdBean.getHumidityCeiling())) {
isNormal = false;
mDashBoardHumidity.setSecondText(metaData.getHumidity(), (false));
} else {
mDashBoardHumidity.setSecondText(metaData.getHumidity(), (true));
}
if (metaData.getInnerPressure() < Float.valueOf(thresholdBean.getInnerPressureFloor()) || metaData.getInnerPressure() > Float.valueOf(thresholdBean.getInnerPressureCeiling())) {
isNormal = false;
mDashBoardInnerPressure.setSecondText(metaData.getInnerPressure(), (false));
} else {
mDashBoardInnerPressure.setSecondText(metaData.getInnerPressure(), (true));
}
if (metaData.getOuterPressure() < Float.valueOf(thresholdBean.getOuterPressureFloor()) || metaData.getOuterPressure() > Float.valueOf(thresholdBean.getOuterPressureCeiling())) {
isNormal = false;
mDashBoardOuterPressure.setSecondText(metaData.getOuterPressure(), (false));
} else {
mDashBoardOuterPressure.setSecondText(metaData.getOuterPressure(), (true));
}
if (metaData.getDiffPressure() < Float.valueOf(thresholdBean.getDiffPressureFloor()) || metaData.getDiffPressure() > Float.valueOf(thresholdBean.getDiffPressureCeiling())) {
isNormal = false;
mDashBoardDiffPressure.setSecondText(metaData.getDiffPressure(), (false));
} else {
mDashBoardDiffPressure.setSecondText(metaData.getDiffPressure(), (true));
}
((TextView) (findViewById(R.id.tv_20degree_humidity))).setText(new DecimalFormat(FLOAT_TYPE).format(metaData.getDegree20Humidity()));
((TextView) (findViewById(R.id.tv_20degree_inner_press))).setText(new DecimalFormat(FLOAT_TYPE).format(metaData.getDegree20Pressure()));
if (isNormal) {
setStatusNormal();
} else {
setStatusAbnormal();
}
}
private void setStatusNormal() {
((TextView) (findViewById(R.id.tv_main_status_normal))).setTextColor(getResources().getColor(R.color.param_black_color));
findViewById(R.id.tv_main_status_normal_round).setBackgroundResource(R.drawable.shape_status_green_round);
((TextView) (findViewById(R.id.tv_main_status_err))).setTextColor(getResources().getColor(R.color.status_grey));
findViewById(R.id.tv_main_status_err_round).setBackgroundResource(R.drawable.shape_status_grey_round);
}
private void setStatusAbnormal() {
((TextView) (findViewById(R.id.tv_main_status_normal))).setTextColor(getResources().getColor(R.color.status_grey));
findViewById(R.id.tv_main_status_normal_round).setBackgroundResource(R.drawable.shape_status_grey_round);
((TextView) (findViewById(R.id.tv_main_status_err))).setTextColor(getResources().getColor(R.color.param_black_color));
findViewById(R.id.tv_main_status_err_round).setBackgroundResource(R.drawable.shape_status_red_round);
}
private void resetStatus() {
((TextView) (findViewById(R.id.tv_main_status_normal))).setTextColor(getResources().getColor(R.color.param_grey_color));
findViewById(R.id.tv_main_status_normal_round).setBackgroundResource(R.drawable.shape_status_grey_round);
((TextView) (findViewById(R.id.tv_main_status_err))).setTextColor(getResources().getColor(R.color.status_grey));
findViewById(R.id.tv_main_status_err_round).setBackgroundResource(R.drawable.shape_status_grey_round);
}
private void readBtnToOriginState() {
findViewById(R.id.btn_read).setEnabled(true);
findViewById(R.id.btn_read).setBackgroundResource(R.drawable.bg_start_btn_new);
((Button) findViewById(R.id.btn_read)).setText(R.string.start_test);
}
private void readBtnToStopState() {
findViewById(R.id.btn_read).setEnabled(true);
findViewById(R.id.btn_read).setBackgroundResource(R.drawable.bg_stop_btn_new);
((Button) findViewById(R.id.btn_read)).setText(R.string.stop_test);
}
private void readBtnToStartingState() {
findViewById(R.id.btn_read).setBackgroundResource(R.drawable.bg_read_btn_starting);
((Button) findViewById(R.id.btn_read)).setText(R.string.read_btn_starting);
findViewById(R.id.btn_read).setEnabled(false);
}
private void readBtnToState(boolean isOpen) {
findViewById(R.id.btn_read).setEnabled(true);
findViewById(R.id.btn_read).setBackgroundResource(isOpen ? R.drawable.bg_stop_btn_new : R.drawable.bg_start_btn_new);
((Button) findViewById(R.id.btn_read)).setText(isOpen ? R.string.stop_test : R.string.start_test);
}
private void doPersist(MetaData metaData) {
PersistHelper.save(metaData.getTemperature(), Constant.Command.COMMAND_29);
PersistHelper.save(metaData.getInnerPressure(), Constant.Command.COMMAND_2A);
PersistHelper.save(metaData.getHumidity(), Constant.Command.COMMAND_2B);
PersistHelper.save(metaData.getOuterPressure(), Constant.Command.COMMAND_2C);
PersistHelper.save(metaData.getDiffPressure(), Constant.Command.COMMAND_2D);
PersistHelper.save(metaData.getDegree20Humidity(), Constant.Command.COMMAND_2E);
PersistHelper.save(metaData.getDegree20Pressure(), Constant.Command.COMMAND_2F);
}
}

+ 77
- 0
app/src/main/java/com/handset/serialportsensor/activity/PasswordResetActivity.java View File

@ -0,0 +1,77 @@
package com.handset.serialportsensor.activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.account.AccountManager;
import com.handset.serialportsensor.utils.SPUtils;
public class PasswordResetActivity extends BaseActivity {
private EditText etOriginal;
private EditText etNew;
private EditText etRepeat;
LinearLayout ll_old_pas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reset_password);
initView();
}
boolean showAdmin;
private void initView() {
initTitle();
etOriginal = findViewById(R.id.et_original_password);
etNew = findViewById(R.id.et_new_password);
etRepeat = findViewById(R.id.et_repeat_password);
ll_old_pas = findViewById(R.id.ll_old_pas);
TextView btnSave = findViewById(R.id.btn_save);
btnSave.setOnClickListener((View view) -> save());
showAdmin = "admin".equals(AccountManager.get().getUserId());
ll_old_pas.setVisibility(showAdmin ? View.VISIBLE : View.GONE);
}
private void save() {
String pwdOld = etOriginal.getText().toString();
String etn = etNew.getText().toString();
String etR = etRepeat.getText().toString();
if (AccountManager.get().isLogin()) {
if (showAdmin) {
String pwdOldTrue = SPUtils.getInstance(this).get("admin");
if (!TextUtils.isEmpty(pwdOldTrue) && !pwdOld.equals(pwdOldTrue)) {
Toast.makeText(this, getString(R.string.old_pwd_wrong), Toast.LENGTH_SHORT).show();
return;
}
}
if (TextUtils.isEmpty(etn) || TextUtils.isEmpty(etR)) {
Toast.makeText((this), getString(R.string.new_pwd_empty), Toast.LENGTH_SHORT).show();
} else if (!etn.equals(etR)) {
Toast.makeText((this), getString(R.string.new_pwd_not_same), Toast.LENGTH_SHORT).show();
} else {
SPUtils.getInstance(this).put("admin", etR);
Toast.makeText((this), getString(R.string.pwd_change_success), Toast.LENGTH_SHORT).show();
finish();
}
} else {
Toast.makeText((this), getString(R.string.pwd_login_first), Toast.LENGTH_SHORT).show();
}
}
private void initTitle() {
ImageView ivBack = findViewById(R.id.title_back);
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View view) -> finish());
TextView tvTitle = findViewById(R.id.title_text);
tvTitle.setText(R.string.reset_password_title);
}
}

+ 21
- 0
app/src/main/java/com/handset/serialportsensor/activity/SPKey.java View File

@ -0,0 +1,21 @@
package com.handset.serialportsensor.activity;
public interface SPKey {
String SU_PATH = "su_path";
String SERIAL_PORT = "serial_port";
String BAUD_RATE = "baud_rate";
String DATA_BITS = "data_bits";
String CHECK_DIGIT = "check_digit";
String STOP_BIT = "stop_bit";
String FLOW_CONTROL = "flow_control";
String SETTING_RECEIVE_TYPE = "receive_type";
String SETTING_RECEIVE_SHOW_TIME = "setting_receive_show_time";
String SETTING_RECEIVE_SHOW_SEND = "setting_receive_show_send";
String SETTING_SEND_TYPE = "setting_send_type";
String SETTING_SEND_REPEAT = "setting_send_repeat";
String SETTING_SEND_DURING = "setting_send_during";
String SEND_HISTORY = "send_history";
}

+ 441
- 0
app/src/main/java/com/handset/serialportsensor/activity/SensorSettingsActivity.java View File

@ -0,0 +1,441 @@
package com.handset.serialportsensor.activity;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportlib.CRCUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.account.AccountManager;
import com.handset.serialportsensor.adapter.SettingsAdapter;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportsensor.bean.SettingsItem;
import com.handset.serialportsensor.bean.TestRecordsTotal;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.presenter.SurfaceContract;
import com.handset.serialportsensor.presenter.SurfacePresenter;
import com.handset.serialportsensor.utils.DateUtils;
import com.handset.serialportsensor.utils.ToastHelper;
import com.handset.serialportsensor.utils.ExcelMa;
import com.handset.serialportsensor.utils.PersistHelper;
import com.handset.serialportsensor.view.ExportProgressDialog;
import org.kymjs.kjframe.KJDB;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.handset.serialportsensor.utils.DateStyle.YYYY_MM_DD_HH_MM;
public class SensorSettingsActivity extends BaseActivity implements SettingsAdapter.OnItemClickListener, SurfaceContract.ISerialView {
private final static String logTag = "HANDSET-JE002-EX";
private String sensorId;
private Integer baudRate;
private AlertDialog resetDialog;
private ExcelMa mExcelMa = new ExcelMa();
private SurfacePresenter mPresenter = new SurfacePresenter((this));
private int[] iconsAdmin = new int[]{
R.mipmap.ic_settings1, R.mipmap.ic_settings2, R.mipmap.ic_settings3,
R.mipmap.ic_settings4, R.mipmap.ic_settings5, R.mipmap.ic_settings6, R.mipmap.ic_settings7,
R.mipmap.ic_settings8, R.mipmap.ic_settings9, R.mipmap.ic_settings9, R.mipmap.ic_settings9
};
private String[] namesAdmin = new String[]{"波特率设置", "阈值设置", "弹筒信息", "数据导出", "数据恢复", "设置系统时间", "重置密码"};
private int[] mPositionAdmin = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
private int[] iconsRoot = new int[]{
R.mipmap.ic_settings7, R.mipmap.ic_settings8, R.mipmap.img_right,
R.mipmap.ic_settings2, R.mipmap.ic_settings9
};
private String[] namesRoot = new String[]{"重置密码", "恢复传感器出厂设置", "第三方传感器弹筒信息开关", "传感器ID设置", "查看操作日志"};
private int[] mPositionRoot = new int[]{6, 7, 8, 9, 10};
public static void open(Integer baudRate, Integer role, String sensorId, Context context) {
Intent intent = new Intent(context, SensorSettingsActivity.class);
intent.putExtra(Constant.ROLE_KEY, role);
Log.e(logTag, "sensorId 444: " + sensorId);
intent.putExtra(Constant.BAUD_RATE, baudRate);
intent.putExtra(Constant.SENSOR_ID, sensorId);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sensor_settings);
initView();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private void initView() {
initTitle();
RecyclerView recyclerView = findViewById(R.id.recycle_view);
recyclerView.setLayoutManager(new LinearLayoutManager((this)));
Intent intent = getIntent();
int role = Constant.NOT_CONNECTED_ROLE;
if (intent != null) {
role = intent.getIntExtra(Constant.ROLE_KEY, Constant.NOT_CONNECTED_ROLE);
baudRate = intent.getIntExtra(Constant.BAUD_RATE, (38400));
sensorId = intent.getStringExtra(Constant.SENSOR_ID);
Log.i(logTag, ("hex string sensorId: " + sensorId));
}
ArrayList<SettingsItem> items = new ArrayList<>();
Log.i(logTag, ("accountId: " + AccountManager.get().getUserId()));
if (AccountManager.get().getUserId().equals("admin")) {
for (int i = 0; i < namesAdmin.length; i++) {
items.add(new SettingsItem(namesAdmin[i], iconsAdmin[i], mPositionAdmin[i]));
}
} else {
for (int i = 0; i < namesRoot.length; i++) {
items.add(new SettingsItem(namesRoot[i], iconsRoot[i], mPositionRoot[i]));
}
}
SettingsAdapter adapter = new SettingsAdapter(items, role);
adapter.setOnItemClickListener(this);
recyclerView.setAdapter(adapter);
findViewById(R.id.btn_logout).setOnClickListener((View v) -> {
AccountManager.get().logout();
finish();
startActivity(new Intent((SensorSettingsActivity.this), LoginActivity.class));
});
}
private void initTitle() {
ImageView ivBack = findViewById(R.id.title_back);
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View view) -> finish());
TextView tvTitle = findViewById(R.id.title_text);
tvTitle.setText(R.string.sensor_settings_title);
}
@Override
public void onItemClick(View view, int position) {
int id = mPositionAdmin[position];
if (AccountManager.get().getUserId().equals("root")) {
id = mPositionRoot[position];
}
Intent intent;
switch (id) {
case 0:
intent = new Intent((SensorSettingsActivity.this), BaudRateSettingActivity.class);
intent.putExtra(Constant.BAUD_RATE, baudRate);
intent.putExtra(Constant.SENSOR_ID, sensorId);
startActivity(intent);
break;
case 1:
startActivity(new Intent((SensorSettingsActivity.this), ThresholdActivity.class));
break;
case 2:
intent = new Intent((SensorSettingsActivity.this), ConeSettingActivity.class);
Log.e(logTag, "sensorId 222: " + sensorId);
intent.putExtra(Constant.BAUD_RATE, baudRate);
intent.putExtra(Constant.SENSOR_ID, sensorId);
startActivity(intent);
break;
case 3:
//数据导出
confirmExport();
break;
case 4:
//数据恢复
startActivity(new Intent((SensorSettingsActivity.this), DataRecoverActivity.class));
break;
case 5:
startActivity(new Intent(Settings.ACTION_DATE_SETTINGS));
break;
case 6:
startActivity(new Intent((SensorSettingsActivity.this), PasswordResetActivity.class));
break;
case 7:
ToastHelper.showResetSensorDialog((this), new ToastHelper.OnDialogClickListener() {
@Override
public void onOKClickListener(View view) {
reset();
}
@Override
public void onCancelClickListener(View view) {
}
});
break;
case 8:
if (AccountManager.get().getUserId().equals("root")) {
startActivity(new Intent((SensorSettingsActivity.this), ThirdSensorSettingsActivity.class));
} else {
Toast.makeText((this), "请登录root 后在操作", Toast.LENGTH_SHORT).show();
}
break;
case 9:
if (AccountManager.get().getUserId().equals("root")) {
intent = new Intent((SensorSettingsActivity.this), ChangeSensorIdSettingsActivity.class);
intent.putExtra(Constant.BAUD_RATE, baudRate);
intent.putExtra(Constant.SENSOR_ID, sensorId);
startActivityForResult(intent, (10001));
} else {
Toast.makeText((this), "请登录root 后在操作", Toast.LENGTH_SHORT).show();
}
break;
case 10:
if (AccountManager.get().getUserId().equals("root")) {
startActivityForResult(new Intent((SensorSettingsActivity.this), ViewOperateLogListActivity.class), 10001);
} else {
Toast.makeText((this), "请登录root 后在操作", Toast.LENGTH_SHORT).show();
}
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 10001) {
if (resultCode == RESULT_OK && data != null) {
String sensorId = data.getStringExtra(Constant.SENSOR_ID);
sendSensorId(sensorId);
}
}
}
private void sendSensorId(String sensorId) {
StringBuilder sb = new StringBuilder(this.sensorId);
sb.append("00").append("80").append("04").append(sensorId);
String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
Log.i(logTag, "sensor no set: cooked: " + cooked);
Log.i(logTag, "sensor no set: cooked 2: " + Arrays.toString(cooked.getBytes()));
mPresenter.write(cooked);
}
private void openAssignFolder(final String times) {
mExportProgressDialog = null;
new Thread(() -> {
List<TestRecordsTotal> testRecordsTotals = KJDB.getDefaultInstance().findAllByWhere(TestRecordsTotal.class, "1=1");
mExcelMa.write(testRecordsTotals, new PersistHelper.ExportCallback() {
@Override
public void exportProgress(int counts, int remain) {
Log.d(logTag, "exportProgress [counts, remain]:" + counts + " " + remain);
showExportProgress(counts, remain);
}
@Override
public void finish(int counts, int remain) {
if (remain != 0) {
showCancelTip();
}
}
}, times);
}).start();
}
//数据导出确认
private void confirmExport() {
runOnUiThread(() -> {
dismissDialog(null);
final String items = DateUtils.formatMilliesTimestamp(System.currentTimeMillis(), YYYY_MM_DD_HH_MM);
final String name = "检测结果(" + items + ").xlsx";
String alarm = "导出数据到 内部存储/htjc/sensor/export/" + name + "";
AlertDialog a = ToastHelper.showChooseDialogNoShow(
getString(R.string.import_out_confirm),
R.mipmap.ic_exclamation_mark,
alarm,
getResources().getColor(R.color.button),
getString(R.string.confirm), getString(R.string.cancel),
(SensorSettingsActivity.this),
new ToastHelper.OnDialogClickListener() {
@Override
public void onOKClickListener(View view) {
openAssignFolder(items);
}
@Override
public void onCancelClickListener(View view) {
}
});
showDialog(a);
});
}
private void showCancelTip() {
runOnUiThread(() -> {
AlertDialog alertDialog = ToastHelper.showTipDialogNoShow((SensorSettingsActivity.this), R.mipmap.chuchang_gray, R.string.cancel);
showDialog(alertDialog);
disMissDialogDelay(alertDialog, (3000));
});
}
ExportProgressDialog mExportProgressDialog;
private void showExportProgress(final int count, final int remain) {
if (mExportProgressDialog == null) {
runOnUiThread(() -> {
mExportProgressDialog = new ExportProgressDialog();
mExportProgressDialog.showExportDialogNoShow(
(SensorSettingsActivity.this),
(View view) -> mExcelMa.stopExport(),
count,
remain,
getString(R.string.importing_to_excel_file),
getString(R.string.import_out)
);
showDialog(mExportProgressDialog.mAlertDialog);
});
} else {
mExportProgressDialog.update(this, count, remain);
}
}
//正在设置
private void showSettingDialog() {
runOnUiThread(() -> {
resetDialog = ToastHelper.showTipDialog((SensorSettingsActivity.this), R.mipmap.ic_setting, R.string.reset_tip);
disMissDialogDelay(resetDialog, (10000));
}
);
}
private Handler mHandler = new Handler();
private Runnable mRunnable;
@Override
public void disMissDialogDelay(final AlertDialog alertDialog, int delayMillis) {
mRunnable = () -> {
Log.i(logTag, "SensorSettingsActivity, disMissDialogDelay");
mPresenter.close();
dismissDialogD(alertDialog);
};
mHandler.postDelayed(mRunnable, delayMillis);
}
private void reset() {
showSettingDialog();
new Thread(() -> {
Looper.prepare();
new Handler().postDelayed(() -> mPresenter.open(baudRate), (500));
Looper.loop();
}
).start();
handler.sendEmptyMessageDelayed(Constant.Command.COMMAND_49, (3000));
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == Constant.Command.COMMAND_49) {//恢复出厂值
StringBuilder sb = new StringBuilder(sensorId);
sb.append("00").append("49").append("00");
String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
Log.i(logTag, "SensorSettingsActivity, cooked: " + cooked);
mPresenter.write(cooked);
}
}
};
@Override
public void onSerialOpen(boolean isOpen) {
}
@Override
public void onSerialBaudRate(Integer baudRate) {
}
@Override
public void onSerialData(RawData rawData) {
if (rawData.getItemType() == RawData.TYPE_RECEIVE) {
Log.i(logTag, "SensorSettingsActivity, onSerialData: " + rawData.getMessage());
byte[] bytes = ByteUtils.hexStrToBytes(rawData.getMessage());
Log.i(logTag, "SensorSettingsActivity, onSerialData 2: " + Arrays.toString(bytes));
if (bytes.length > 8) {
if ((bytes[6] & 0xff) == 0 && (bytes[7] & 0xff) == Constant.Command.COMMAND_4A) {
Log.i(logTag, "SensorSettingsActivity, onSerialData, 0x49 feedback: " + rawData.getMessage());
mPresenter.close();
dismissDialog(resetDialog);
mHandler.removeCallbacks(mRunnable);
restoreToFactorySuccess();
} else {
mPresenter.close();
dismissDialog(resetDialog);
mHandler.removeCallbacks(mRunnable);
restoreToFactoryFail();
}
}
}
}
@Override
public void onSerialError(Integer errorCode) {
}
//设置成功
private void restoreToFactorySuccess() {
runOnUiThread(() -> {
disMissLoadingDialog(resetDialog);
ToastHelper.showSubmitDialog(
getString(R.string.restore_factory_success),
R.mipmap.img_right,
getString(R.string.go_back_init_screen_content),
getResources().getColor(R.color.blue_button_bg),
getString(R.string.btn_ensure),
(SensorSettingsActivity.this),
(View view) -> finish()
);
});
}
//设置失败
private void restoreToFactoryFail() {
runOnUiThread(() -> {
disMissLoadingDialog(resetDialog);
ToastHelper.showSubmitDialog(
getString(R.string.restore_factory_failed),
R.mipmap.img_cross,
getString(R.string.go_back_init_screen_content),
getResources().getColor(R.color.button),
getString(R.string.btn_ensure),
(SensorSettingsActivity.this),
(View view) -> {
}
);
}
);
}
}

+ 40
- 0
app/src/main/java/com/handset/serialportsensor/activity/SplashActivity.java View File

@ -0,0 +1,40 @@
package com.handset.serialportsensor.activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.handset.serialportsensor.R;
import io.reactivex.Observable;
import io.reactivex.disposables.Disposable;
import java.util.concurrent.TimeUnit;
public class SplashActivity extends AppCompatActivity {
private Disposable mDisposable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
mDisposable = Observable
.timer((1), TimeUnit.SECONDS)
.subscribe(this::jumpToMain, Throwable::printStackTrace);
}
@SuppressWarnings(value = "unused")
private void jumpToMain(Long aLong) {
startActivity(new Intent((this), Main2Activity.class));
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mDisposable != null) {
mDisposable.dispose();
}
}
}

+ 41
- 0
app/src/main/java/com/handset/serialportsensor/activity/ThirdSensorSettingsActivity.java View File

@ -0,0 +1,41 @@
package com.handset.serialportsensor.activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.account.AccountManager;
import com.handset.serialportsensor.utils.SPUtils;
/**
* Created by zy on 2019/2/23.
*/
public class ThirdSensorSettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third_sensor_settings);
Switch sw_sensor = (Switch) findViewById(R.id.sw_sensor);
boolean sensor_third_enable = SPUtils.getInstance(this).get("sensor_third_enable", false);
sw_sensor.setChecked(sensor_third_enable);
sw_sensor.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SPUtils.getInstance(ThirdSensorSettingsActivity.this).put("sensor_third_enable", isChecked);
AccountManager.get().putUserData("sensor_third_enable", isChecked + "");
}
});
TextView tvTitle = findViewById(R.id.title_text);
ImageView ivBack = findViewById(R.id.title_back);
tvTitle.setText("第三方传感器弹筒信息开关");
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View v) -> ThirdSensorSettingsActivity.this.finish());
}
}

+ 264
- 0
app/src/main/java/com/handset/serialportsensor/activity/ThresholdActivity.java View File

@ -0,0 +1,264 @@
package com.handset.serialportsensor.activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.account.AccountManager;
import com.handset.serialportsensor.bean.ThresholdBean;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.utils.SpUtil;
public class ThresholdActivity extends AppCompatActivity {
private EditText etTempLow;
private EditText etTempHigh;
private EditText etHumLow;
private EditText etHumHigh;
private EditText etPressureLow1;
private EditText etPressureHigh1;
private EditText etPressureLow2;
private EditText etPressureHigh2;
private EditText etDiffPressureLow;
private EditText etDiffPressureHigh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_threshold);
initView();
setDefaultValue();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager im = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
if(im != null) {
View view = getCurrentFocus();
if(view != null) {
im.hideSoftInputFromWindow(getCurrentFocus().getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
return super.onTouchEvent(event);
}
private void initView() {
initTitle();
}
private void initTitle() {
ImageView ivBack = findViewById(R.id.title_back);
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener((View view) -> finish());
TextView tvTitle = findViewById(R.id.title_text);
tvTitle.setText(R.string.set_threshold_title);
etTempLow = findViewById(R.id.et_temp_low);
etTempHigh = findViewById(R.id.et_temp_high);
etHumLow = findViewById(R.id.et_humidity_low);
etHumHigh = findViewById(R.id.et_humidity_high);
etPressureLow1 = findViewById(R.id.et_pressure1_low);
etPressureHigh1 = findViewById(R.id.et_pressure1_high);
etPressureLow2 = findViewById(R.id.et_pressure2_low);
etPressureHigh2 = findViewById(R.id.et_pressure2_high);
etDiffPressureHigh = findViewById(R.id.et_pressure_yahcha_high);
etDiffPressureLow = findViewById(R.id.et_pressure_yacha_low);
findViewById(R.id.btn_save).setOnClickListener((View view) -> save());
}
private void save() {
if (check()) {
ThresholdBean bean = new ThresholdBean();
bean.setTemperatureFloor(etTempLow.getText().toString());
bean.setTemperatureCeiling(etTempHigh.getText().toString());
bean.setHumidityFloor(etHumLow.getText().toString());
bean.setHumidityCeiling(etHumHigh.getText().toString());
bean.setInnerPressureFloor(etPressureLow1.getText().toString());
bean.setInnerPressureCeiling(etPressureHigh1.getText().toString());
bean.setOuterPressureFloor(etPressureLow2.getText().toString());
bean.setOuterPressureCeiling(etPressureHigh2.getText().toString());
bean.setDiffPressureFloor(etDiffPressureLow.getText().toString());
bean.setDiffPressureCeiling(etDiffPressureHigh.getText().toString());
SpUtil.put(this, Constant.THRESHOLD_KEY, new Gson().toJson(bean));
Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show();
AccountManager.get().putUserData("ThresholdBean", "ThresholdBean");
finish();
}
}
private boolean check() {
if (!checkDataFormat(etTempLow.getText().toString())) {
Toast.makeText(this, "温度下限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etTempHigh.getText().toString())) {
Toast.makeText(this, "温度上限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etHumLow.getText().toString())) {
Toast.makeText(this, "湿度下限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etHumHigh.getText().toString())) {
Toast.makeText(this, "湿度上限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etPressureLow1.getText().toString())) {
Toast.makeText(this, "内压下限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etPressureHigh1.getText().toString())) {
Toast.makeText(this, "内压上限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etPressureLow2.getText().toString())) {
Toast.makeText(this, "外压下限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etPressureHigh2.getText().toString())) {
Toast.makeText(this, "外压上限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etDiffPressureLow.getText().toString())) {
Toast.makeText(this, "压差下限格式不正确", Toast.LENGTH_SHORT).show();
return false;
} else if (!checkDataFormat(etDiffPressureHigh.getText().toString())) {
Toast.makeText(this, "压差上限格式不正确", Toast.LENGTH_SHORT).show();
return false;
}
if (!between(checkDataFormatF(etTempHigh.getText().toString()), 85f, -45f)
|| !between(checkDataFormatF(etTempLow.getText().toString()), 85f, -45f)) {
Toast.makeText(this, "温度范围只能输入 -45~85", Toast.LENGTH_SHORT).show();
return false;
}
if (!between(checkDataFormatF(etHumHigh.getText().toString()), 100f, 0f)
|| !between(checkDataFormatF(etHumLow.getText().toString()), 100f, 0f)) {
Toast.makeText(this, "湿度范围只能输入 0~100", Toast.LENGTH_SHORT).show();
return false;
}
if (!between(checkDataFormatF(etPressureHigh1.getText().toString()), 200f, 0f)
|| !between(checkDataFormatF(etPressureLow1.getText().toString()), 200f, 0f)
|| !between(checkDataFormatF(etPressureHigh2.getText().toString()), 200f, 0f)
|| !between(checkDataFormatF(etPressureLow2.getText().toString()), 200f, 0f)) {
Toast.makeText(this, "压力范围只能输入 0~200", Toast.LENGTH_SHORT).show();
return false;
}
if (!between(checkDataFormatF(etDiffPressureHigh.getText().toString()), 30f, -20f)
|| !between(checkDataFormatF(etDiffPressureLow.getText().toString()), 30f, -20f)) {
Toast.makeText(this, "压差范围只能输入 -20~30", Toast.LENGTH_SHORT).show();
return false;
}
if (!compareBS(etTempHigh.getText().toString(), etTempLow.getText().toString())) {
Toast.makeText(this, "湿度上限不能低于下限", Toast.LENGTH_SHORT).show();
return false;
}
if (!compareBS(etHumHigh.getText().toString(), etHumLow.getText().toString())) {
Toast.makeText(this, "湿度上限不能低于下限", Toast.LENGTH_SHORT).show();
return false;
}
if (!compareBS(etPressureHigh1.getText().toString(), etPressureLow1.getText().toString())) {
Toast.makeText(this, "内压上限不能低于下限", Toast.LENGTH_SHORT).show();
return false;
}
if (!compareBS(etPressureHigh2.getText().toString(), etPressureLow2.getText().toString())) {
Toast.makeText(this, "外压上限不能低于下限", Toast.LENGTH_SHORT).show();
return false;
}
if (!compareBS(etDiffPressureHigh.getText().toString(), etDiffPressureLow.getText().toString())) {
Toast.makeText(this, "压差上限不能低于下限", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
private boolean between(Float f, Float up, Float low) {
if (f == null || up == null || low == null) {
return false;
}
return low <= f && f <= up;
}
private boolean checkDataFormat(String a) {
return checkDataFormatF(a) != null;
}
private Float checkDataFormatF(String a) {
if (TextUtils.isEmpty(a)) {
return null;
}
try {
Float f = Float.parseFloat(a);
return f;
} catch (NumberFormatException e) {
e.printStackTrace();
return null;
}
}
private boolean compareBS(String bigger, String smaller) {
if (TextUtils.isEmpty(bigger) || TextUtils.isEmpty(smaller)) {
return false;
}
try {
Float bigErf = Float.parseFloat(bigger);
Float smallErf = Float.parseFloat(smaller);
if (bigErf >= smallErf) {
return true;
}
} catch (NumberFormatException e) {
e.printStackTrace();
return false;
}
return false;
}
/**
* 配置默认阈值参数
*/
private void setDefaultValue() {
ThresholdBean bean = new ThresholdBean();
bean.setTemperatureFloor("-40");
bean.setTemperatureCeiling("65");
bean.setHumidityFloor("0");
bean.setHumidityCeiling("100");
bean.setInnerPressureFloor("80");
bean.setInnerPressureCeiling("150");
bean.setOuterPressureFloor("80");
bean.setOuterPressureCeiling("150");
bean.setDiffPressureFloor("-20");
bean.setDiffPressureCeiling("30");
String bean2 = (String) SpUtil.get(this, Constant.THRESHOLD_KEY, "");
ThresholdBean bean1 = null;
if (!TextUtils.isEmpty(bean2)) {
bean1 = new Gson().fromJson(bean2, ThresholdBean.class);
}
if (bean1 != null) {
bean = bean1;
}
etTempLow.setText(bean.getTemperatureFloor());
etTempHigh.setText(bean.getTemperatureCeiling());
etHumLow.setText(bean.getHumidityFloor());
etHumHigh.setText(bean.getHumidityCeiling());
etPressureLow1.setText(bean.getInnerPressureFloor());
etPressureHigh1.setText(bean.getInnerPressureCeiling());
etPressureLow2.setText(bean.getOuterPressureFloor());
etPressureHigh2.setText(bean.getOuterPressureCeiling());
etDiffPressureHigh.setText(bean.getDiffPressureCeiling());
etDiffPressureLow.setText(bean.getDiffPressureFloor());
}
}

+ 70
- 0
app/src/main/java/com/handset/serialportsensor/activity/ViewLogActivity.java View File

@ -0,0 +1,70 @@
package com.handset.serialportsensor.activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.handset.serialportsensor.R;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Created by zy on 2019/2/28.
*/
public class ViewLogActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_log);
Intent intent = getIntent();
String filePath = intent.getStringExtra("file_path");
TextView tv_log = findViewById(R.id.tv_log);
TextView tvTitle = findViewById(R.id.title_text);
ImageView ivBack = findViewById(R.id.title_back);
tvTitle.setText("操作日志");
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ViewLogActivity.this.finish();
}
});
if (!TextUtils.isEmpty(filePath)) {
String ac = getfileC(filePath);
tv_log.setText(ac);
}
}
private String getfileC(String filePath) {
String c = "";
File file = new File(filePath);
FileInputStream in;
try {
in = new FileInputStream(file);
int l = (int) file.length();
byte[] filecontent = new byte[l];
in.read(filecontent);
in.close();
c = new String(filecontent);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return c;
}
}

+ 136
- 0
app/src/main/java/com/handset/serialportsensor/activity/ViewOperateLogListActivity.java View File

@ -0,0 +1,136 @@
package com.handset.serialportsensor.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.utils.Slog;
import com.handset.serialportsensor.view.LinearLayoutManagerCus;
import java.io.File;
import java.util.List;
import static android.support.v7.widget.DividerItemDecoration.VERTICAL;
/**
* Created by zy on 2019/2/27.
*/
public class ViewOperateLogListActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
MyAdapter myAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_operate_log);
mRecyclerView = findViewById(R.id.recycle_view);
mRecyclerView.setLayoutManager(new LinearLayoutManagerCus(this));
DefaultItemAnimator animator = new DefaultItemAnimator();
animator.setRemoveDuration(1000);
mRecyclerView.setItemAnimator(animator);
TextView tvTitle = findViewById(R.id.title_text);
ImageView ivBack = findViewById(R.id.title_back);
tvTitle.setText("操作日志");
ivBack.setVisibility(View.VISIBLE);
ivBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ViewOperateLogListActivity.this.finish();
}
});
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL));
getOperateLog();
}
private void getOperateLog() {
List<File> list = Slog.getOperateLogFiles();
//设置适配器
if (myAdapter == null) {
myAdapter = new MyAdapter(this, list);
mRecyclerView.setAdapter(myAdapter);
} else {
myAdapter.setDataList(list);
}
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvIndex;
TextView tvLog;
ConstraintLayout cl_content;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tvIndex = itemView.findViewById(R.id.tv_item_index);
tvLog = itemView.findViewById(R.id.tv_name);
cl_content = itemView.findViewById(R.id.cl_content);
}
}
static class MyAdapter extends RecyclerView.Adapter<ViewHolder> {
List<File> mDataList;
private OnItemClickListener mOnItemClickListener;
Context mContext;
public MyAdapter(Context context, List<File> mList) {
mContext = context;
this.mDataList = mList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.operate_log_item, null, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) {
final File file = mDataList.get(i);
viewHolder.tvIndex.setText((i + 1) + "");
viewHolder.tvLog.setText(file.getName());
viewHolder.cl_content.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, ViewLogActivity.class);
intent.putExtra("file_path", file.getAbsolutePath());
mContext.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mDataList.size();
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = onItemClickListener;
}
public void setDataList(List<File> dataList) {
mDataList = dataList;
notifyDataSetChanged();
}
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
}

+ 19
- 0
app/src/main/java/com/handset/serialportsensor/adapter/HistoryAdapter.java View File

@ -0,0 +1,19 @@
package com.handset.serialportsensor.adapter;
import android.support.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.handset.serialportsensor.R;
import java.util.List;
public class HistoryAdapter extends BaseQuickAdapter<String,BaseViewHolder> {
public HistoryAdapter(@Nullable List<String> data) {
super(R.layout.rv_item_history, data);
}
@Override
protected void convert(BaseViewHolder helper, String item) {
helper.setText(R.id.item_history, item);
}
}

+ 86
- 0
app/src/main/java/com/handset/serialportsensor/adapter/LeftAdapter.java View File

@ -0,0 +1,86 @@
package com.handset.serialportsensor.adapter;
import android.text.TextUtils;
import com.blankj.utilcode.util.SPUtils;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chad.library.adapter.base.entity.MultiItemEntity;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.LeftDetailBean;
import com.handset.serialportsensor.bean.LeftHeadBean;
import java.util.List;
public class LeftAdapter extends BaseMultiItemQuickAdapter<MultiItemEntity, BaseViewHolder> {
public static final int TYPE_HEAD = 1;
public static final int TYPE_DETAIL = 2;
/**
* Same as QuickAdapter#QuickAdapter(Context,int) but with
* some initialization data.
*
* @param data A new list is created out of this one to avoid mutable list
*/
public LeftAdapter(List<MultiItemEntity> data) {
super(data);
addItemType(TYPE_HEAD, R.layout.left_rv_item_head);
addItemType(TYPE_DETAIL, R.layout.left_rv_item_detail);
}
@Override
protected void convert(BaseViewHolder helper, MultiItemEntity item) {
switch (helper.getItemViewType()) {
case TYPE_HEAD:
if (item instanceof LeftHeadBean) {
helper.setImageResource(R.id.left_rv_item_image, ((LeftHeadBean) item).getImageRes())
.setText(R.id.left_rv_item_title, ((LeftHeadBean) item).getTitle())
.setText(R.id.left_rv_item_value,
TextUtils.isEmpty(((LeftHeadBean) item).getValue()) ? ""
: ((LeftHeadBean) item).getValue());
helper.itemView.setOnClickListener(v -> {
collapseOrExpand(item);
});
}
break;
case TYPE_DETAIL:
if (item instanceof LeftDetailBean) {
helper.setText(R.id.left_rv_item_item, ((LeftDetailBean) item).getItem())
.setChecked(R.id.left_rv_item_check, ((LeftDetailBean) item).isCheck());
helper.itemView.setOnClickListener(v -> {
int parentPosition = getParentPosition(item);
LeftHeadBean headBean = (LeftHeadBean) getData().get(parentPosition);
List<LeftDetailBean> subItems = headBean.getSubItems();
for (int i = 0; i < subItems.size(); i++) {
if (subItems.get(i).isCheck()) {
subItems.get(i).setCheck(false);
break;
}
}
int subPosition = helper.getAdapterPosition() - parentPosition - 1;
LeftDetailBean bean = subItems.get(subPosition);
bean.setCheck(true);
headBean.setValue(String.valueOf(bean.getItem()));
SPUtils.getInstance().put(headBean.getSpKey(), headBean.getValue());
notifyDataSetChanged();
});
}
break;
}
}
public void collapseOrExpand(MultiItemEntity item) {
int position = getParentPosition(item);
if (((LeftHeadBean) item).isExpanded()) {
collapse(position);
} else {
expand(position);
}
}
}

+ 46
- 0
app/src/main/java/com/handset/serialportsensor/adapter/MsgAdapter.java View File

@ -0,0 +1,46 @@
package com.handset.serialportsensor.adapter;
import android.text.TextUtils;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.RawData;
import java.util.List;
import java.util.Locale;
public class MsgAdapter extends BaseMultiItemQuickAdapter<RawData, BaseViewHolder> {
private String mFormat;
/**
* Same as QuickAdapter#QuickAdapter(Context,int) but with
* some initialization data.
*
* @param data A new list is created out of this one to avoid mutable list
*/
public MsgAdapter(List<RawData> data) {
super(data);
addItemType(RawData.TYPE_RECEIVE, R.layout.rv_item_receive);
addItemType(RawData.TYPE_SEND, R.layout.rv_item_send);
}
@Override
protected void convert(BaseViewHolder helper, RawData item) {
if (TextUtils.isEmpty(mFormat)) {
mFormat = mContext.getString(R.string.time_format);
}
if (item.getItemType() == RawData.TYPE_RECEIVE) {
helper.setGone(R.id.item_receive_date, !TextUtils.isEmpty(item.getDate()))
.setText(R.id.item_receive_date, TextUtils.isEmpty(item.getDate()) ? ""
: String.format(Locale.getDefault(), mFormat, item.getDate()))
.setText(R.id.item_receive_contain, item.getMessage());
} else {
helper.setGone(R.id.item_send_date, !TextUtils.isEmpty(item.getDate()))
.setText(R.id.item_send_date, TextUtils.isEmpty(item.getDate()) ? ""
: String.format(Locale.getDefault(), mFormat, item.getDate()))
.setText(R.id.item_send_contain, item.getMessage());
}
}
}

+ 98
- 0
app/src/main/java/com/handset/serialportsensor/adapter/SettingsAdapter.java View File

@ -0,0 +1,98 @@
package com.handset.serialportsensor.adapter;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.bean.SettingsItem;
import com.handset.serialportsensor.constant.Constant;
import java.util.List;
public class SettingsAdapter extends RecyclerView.Adapter<SettingsAdapter.ViewHolder> {
private List<SettingsItem> list;
private int role;
private OnItemClickListener listener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.listener = onItemClickListener;
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
public SettingsAdapter(List<SettingsItem> list, int role) {
this.list = list;
this.role = role;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View inflate = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.settings_adapter_item, viewGroup, false);
return new ViewHolder(inflate);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) {
final SettingsItem item = list.get(i);
viewHolder.iv_img.setImageResource(item.getIconRes());
viewHolder.tv_title.setText(item.getName());
viewHolder.itemView.setOnClickListener((View view) ->
Toast.makeText(view.getContext(), item.getName(), Toast.LENGTH_SHORT).show()
);
if (i == list.size() - 1) {
viewHolder.line.setVisibility(View.GONE);
if (role == Constant.SENIOR_ROLE) {
viewHolder.third_layout.setVisibility(View.VISIBLE);
} else {
viewHolder.third_layout.setVisibility(View.INVISIBLE);
}
} else {
viewHolder.third_layout.setVisibility(View.GONE);
viewHolder.line.setVisibility(View.VISIBLE);
}
viewHolder.itemView.setOnClickListener((View view) -> listener.onItemClick(view, i));
if (role == Constant.NOT_CONNECTED_ROLE) {
if (item.getPosition() == 0 || item.getPosition() == 2 || item.getPosition() == 7 || item.getPosition() == 9) {
viewHolder.iv_img.setImageResource(R.mipmap.ic_settings3_gray);
viewHolder.tv_title.setTextColor(viewHolder.tv_title.getContext().getResources().getColor(R.color.very_light_gray));
viewHolder.iv_right.setImageResource(R.mipmap.ic_right_arrow_light);
viewHolder.itemView.setClickable(false);
}
}
}
@Override
public int getItemCount() {
return list.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private ImageView iv_img;
private TextView tv_title;
private ImageView iv_right;
private View line;
private LinearLayout third_layout;
public ViewHolder(@NonNull View itemView) {
super(itemView);
iv_img = itemView.findViewById(R.id.iv_img);
tv_title = itemView.findViewById(R.id.tv_title);
iv_right = itemView.findViewById(R.id.iv_right);
line = itemView.findViewById(R.id.line);
third_layout = itemView.findViewById(R.id.third_layout);
}
}
}

+ 31
- 0
app/src/main/java/com/handset/serialportsensor/bean/LeftDetailBean.java View File

@ -0,0 +1,31 @@
package com.handset.serialportsensor.bean;
import com.chad.library.adapter.base.entity.MultiItemEntity;
import com.handset.serialportsensor.adapter.LeftAdapter;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
public class LeftDetailBean implements MultiItemEntity {
private String item;
private boolean isCheck;
public LeftDetailBean(String item) {
this.item = item;
}
public LeftDetailBean(String item, boolean isCheck) {
this.item = item;
this.isCheck = isCheck;
}
@Override
public int getItemType() {
return LeftAdapter.TYPE_DETAIL;
}
}

+ 36
- 0
app/src/main/java/com/handset/serialportsensor/bean/LeftHeadBean.java View File

@ -0,0 +1,36 @@
package com.handset.serialportsensor.bean;
import android.support.annotation.DrawableRes;
import com.chad.library.adapter.base.entity.AbstractExpandableItem;
import com.chad.library.adapter.base.entity.MultiItemEntity;
import com.handset.serialportsensor.adapter.LeftAdapter;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LeftHeadBean extends AbstractExpandableItem<LeftDetailBean> implements MultiItemEntity {
@DrawableRes
private int imageRes;
private String title;
private String value;
private String spKey;
@Override
public int getLevel() {
return 0;
}
@Override
public int getItemType() {
return LeftAdapter.TYPE_HEAD;
}
}

+ 187
- 0
app/src/main/java/com/handset/serialportsensor/bean/MetaData.java View File

@ -0,0 +1,187 @@
package com.handset.serialportsensor.bean;
import android.util.Log;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportsensor.constant.Constant;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MetaData {
private static final String logTag = "HANDSET-JE002-EX";
private static final BigDecimal T_CEILING = new BigDecimal(100.00f);
private static final BigDecimal T_FLOOR = new BigDecimal(-60.00f);
private static final BigDecimal H_CEILING = new BigDecimal(100.00f);
private static final BigDecimal H_FLOOR = new BigDecimal(00.00f);
private static final BigDecimal I_CEILING = new BigDecimal(300.00f);
private static final BigDecimal I_FLOOR = new BigDecimal(00.00f);
private static final BigDecimal O_CEILING = new BigDecimal(300.00f);
private static final BigDecimal O_FLOOR = new BigDecimal(00.00f);
private static final BigDecimal DP_CEILING = new BigDecimal(600.00f);
private static final BigDecimal DP_FLOOR = new BigDecimal(-600.00f);
private static final BigDecimal P20_CEILING = new BigDecimal(300.00f);
private static final BigDecimal P20_FLOOR = new BigDecimal(00.00f);
private static final BigDecimal H20_CEILING = new BigDecimal(100.00f);
private static final BigDecimal H20_FLOOR = new BigDecimal(00.00f);
private static final int[] temperatureConvertDatum = {
18, 23, 28, 34, 41, 50, 61, 73, 88, 105,
125, 148, 175, 207, 244, 286, 334, 390, 454, 528,
611, 706, 814, 935, 1073, 1228, 1403, 1599, 1819, 2065,
2339, 2645, 2985, 3362, 3781, 4244, 4756, 5321, 5942, 6626,
7377, 8201, 9103, 10089, 11165, 12339, 13618, 15009, 16520, 18160, 19937
};
private Integer makerId;
private String sensorNo;
private String sensorNoRadix;
private String eggNo;
private String eggType;
private String coneNo;
private String coneUsedTimes;
private Float temperature;
private Float humidity;
private Float innerPressure;
private Float outerPressure;
private Float diffPressure;
private Float degree20Pressure;
private Float degree20Humidity;
public void doCalcMeta(String data) {
byte[] bytes = ByteUtils.hexStrToBytes(data.substring(0, data.length() - 4));
switch (bytes[7] & 0xff) {
case Constant.Command.COMMAND_29:
this.setTemperature((float) parseValue(bytes) / 100);
break;
case Constant.Command.COMMAND_2A:
this.setInnerPressure((float) parseValue(bytes) / 1000);
break;
case Constant.Command.COMMAND_2B:
this.setHumidity((float) parseValue(bytes) / 100);
break;
case Constant.Command.COMMAND_2C:
this.setOuterPressure((float) parseValue(bytes) / 1000);
break;
case Constant.Command.COMMAND_2D:
this.setDiffPressure((float) parseValue(bytes) / 1000);
break;
case Constant.Command.COMMAND_2E:
this.setDegree20Humidity((float) parseValue(bytes) / 100);
break;
case Constant.Command.COMMAND_2F:
this.setDegree20Pressure((float) parseValue(bytes) / 1000);
break;
default:
break;
}
}
public void doCalcMetaEx() {
calcPressDiff();
calcPressOfDegree20();
calcHumidityOfDegree20();
}
public void calcPressDiff() {
try {
if(this.diffPressure == 0) {
Log.i(logTag, "Diff pressure not report, need to be calculated");
this.diffPressure = this.innerPressure - this.outerPressure;
}
} catch (Exception e) {
e.printStackTrace();
this.diffPressure = 0.00f;
}
}
public void calcPressOfDegree20() {
try {
if(this.degree20Pressure == 0) {
Log.i(logTag, "20 degree pressure not report, need to be calculated");
int tempMustInt = (int) (this.temperature * 10);
double temp = (293000.00) / ((tempMustInt + 400) + 2330);
double innerPress20Degree = (temp * (this.innerPressure * 1000)) / 100 / 1000;
DecimalFormat df = new DecimalFormat(Constant.FORMAT_FLOAT_PATTERN);
df.setRoundingMode(RoundingMode.FLOOR);
this.degree20Pressure = Float.valueOf(df.format(innerPress20Degree));
}
} catch (Exception e) {
e.printStackTrace();
this.degree20Pressure = 0.00f;
}
}
public void calcHumidityOfDegree20() {
try {
if(this.degree20Humidity == 0) {
Log.i(logTag, "20 degree humidity not report, need to be calculated");
int tmp = (((int) (this.temperature * 10) + 400) / 10) / 2;
tmp = (((int) (this.temperature * 10) + 400) / 10) % 2 == 0 ? tmp : tmp + 1;
tmp = tmp > 50 || tmp < 0 ? 50 : tmp;
double degree20Humidity = (temperatureConvertDatum[tmp] * ((double) (this.humidity * 100) / 100)) / 2339;
DecimalFormat df2 = new DecimalFormat(Constant.FORMAT_FLOAT_PATTERN);
df2.setRoundingMode(RoundingMode.FLOOR);
this.degree20Humidity = Float.valueOf(df2.format(degree20Humidity));
}
} catch (Exception e) {
e.printStackTrace();
this.degree20Humidity = 0.00f;
}
this.degree20Humidity = new BigDecimal(this.degree20Humidity).compareTo(H20_CEILING) >=0 ? 100.f : this.degree20Humidity;
}
private int parseValue(byte[] bytes) {
return (bytes[9] & 0xff) | ((bytes[10] & 0xff) << 8) | ((bytes[11] & 0xff) << 16) | ((bytes[12] & 0xff) << 24);
}
public boolean isValid() {
BigDecimal t = new BigDecimal(this.temperature);
BigDecimal h = new BigDecimal(this.humidity);
BigDecimal i = new BigDecimal(this.innerPressure);
BigDecimal o = new BigDecimal(this.outerPressure);
BigDecimal dp = new BigDecimal(this.diffPressure);
BigDecimal p20 = new BigDecimal(this.degree20Pressure);
BigDecimal h20 = new BigDecimal(this.degree20Humidity);
Log.i(logTag, "t:" + t.floatValue() + ",h:" + h.floatValue() + ",i:" + i.floatValue() + ",o:" + o.floatValue() + ",dp:" + dp.floatValue() + ",p20:" + p20.floatValue()+ ",h20:" + h20.floatValue());
return t.compareTo(T_CEILING) <= 0 && t.compareTo(T_FLOOR) >= 0
&& h.compareTo(H_CEILING) <= 0 && h.compareTo(H_FLOOR) >= 0
&& i.compareTo(I_CEILING) <= 0 && i.compareTo(I_FLOOR) >= 0
&& o.compareTo(O_CEILING) <= 0 && o.compareTo(O_FLOOR) >= 0
&& dp.compareTo(DP_CEILING) <= 0 && dp.compareTo(DP_FLOOR) >= 0
&& p20.compareTo(P20_CEILING) <= 0 && p20.compareTo(P20_FLOOR) >= 0
&& h20.compareTo(H20_CEILING) <= 0 && h20.compareTo(H20_FLOOR) >= 0
;
}
public void resetData() {
this.setSensorNo(null);
this.setSensorNoRadix(null);
this.temperature = 0.0F;
this.humidity = 0.0F;
this.innerPressure = 0.0F;
this.outerPressure = 0.0F;
this.diffPressure = 0.0F;
this.degree20Humidity = 0.0F;
this.degree20Pressure = 0.0F;
}
public void resetData20Degree() {
this.diffPressure = 0.0F;
this.degree20Humidity = 0.0F;
this.degree20Pressure = 0.0F;
}
}

+ 34
- 0
app/src/main/java/com/handset/serialportsensor/bean/RawData.java View File

@ -0,0 +1,34 @@
package com.handset.serialportsensor.bean;
import com.chad.library.adapter.base.entity.MultiItemEntity;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
public class RawData implements MultiItemEntity {
public static final int TYPE_RECEIVE = 0;
public static final int TYPE_SEND = 1;
private int mItemType;
private String date;
private String message;
public RawData(int itemType) {
mItemType = itemType;
}
public RawData(int itemType, String date, String message) {
mItemType = itemType;
this.date = date;
this.message = message;
}
@Override
public int getItemType() {
return mItemType;
}
}

+ 29
- 0
app/src/main/java/com/handset/serialportsensor/bean/Sensor.java View File

@ -0,0 +1,29 @@
package com.handset.serialportsensor.bean;
import org.kymjs.kjframe.database.annotate.Id;
import org.kymjs.kjframe.database.annotate.Table;
import org.kymjs.kjframe.database.annotate.Transient;
/**
* Created by zy on 2019/2/24.
* 用来记录传感器信息
*/
@Table(name = "sensor")
public class Sensor {
@Id
public int id;
/*传感器编号*/
public long sensor_id;
/*弹号*/
public String egg_id;
/*弹型*/
public String egg_type;
/*筒号*/
public String tupe_id;
public String tv_tupe_use_times;
@Transient
public int tagBackup = 0;
}

+ 37
- 0
app/src/main/java/com/handset/serialportsensor/bean/SettingsItem.java View File

@ -0,0 +1,37 @@
package com.handset.serialportsensor.bean;
public class SettingsItem {
private String name;
private int iconRes;
private int position;
public SettingsItem(String name, int iconRes, int position) {
this.name = name;
this.iconRes = iconRes;
this.position = position;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIconRes() {
return iconRes;
}
public void setIconRes(int iconRes) {
this.iconRes = iconRes;
}
}

+ 80
- 0
app/src/main/java/com/handset/serialportsensor/bean/TestData.java View File

@ -0,0 +1,80 @@
package com.handset.serialportsensor.bean;
public class TestData {
private String title;
public String getZhankai() {
return zhankai;
}
public void setZhankai(String zhankai) {
this.zhankai = zhankai;
}
private String zhankai;
private int tag;
public boolean isSelect;
public int temp;
public int neiYa;
public int waiYa;
public int shiDu;
public int getTemp() {
return temp;
}
public void setTemp(int temp) {
this.temp = temp;
}
public int getNeiYa() {
return neiYa;
}
public void setNeiYa(int neiYa) {
this.neiYa = neiYa;
}
public int getWaiYa() {
return waiYa;
}
public void setWaiYa(int waiYa) {
this.waiYa = waiYa;
}
public int getShiDu() {
return shiDu;
}
public void setShiDu(int shiDu) {
this.shiDu = shiDu;
}
public boolean isSelect() {
return isSelect;
}
public void setSelect(boolean isSelect) {
this.isSelect = isSelect;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getTag() {
return tag;
}
public void setTag(int tag) {
this.tag = tag;
}
}

+ 49
- 0
app/src/main/java/com/handset/serialportsensor/bean/TestRecordsTotal.java View File

@ -0,0 +1,49 @@
package com.handset.serialportsensor.bean;
import org.kymjs.kjframe.database.annotate.Id;
import org.kymjs.kjframe.database.annotate.Property;
import org.kymjs.kjframe.database.annotate.Table;
/**
* Created by zy on 2019/2/24.
* 单条汇总测试数据求取平均值之后的数据
*/
@Table(name = "test_record_total")
public class TestRecordsTotal {
/**
* 测试id
*/
@Id
public long id;
//记录数据保存的日期标记方便之后能够查出来
public long day_t;
/*温度*/
public float temp;
/*湿度*/
public float Hum;
/*内压*/
public float pressurein;
/*湿度*/
public float Hum20;
/*内压*/
public float pressurein20;
/*外压*/
public float pressureout;
/*压差*/
public float pressure_yacha;
/*传感器编号*/
public long sensor_id;
/*波特率*/
@Property(column = "tupe_id")
public String botelv;
/*筒使用次数*/
public String tupe_use_times;
/*测试结束时间*/
public long end_time;
/*数据是否已经备份过*/
public int tagBackup = 0;
}

+ 28
- 0
app/src/main/java/com/handset/serialportsensor/bean/TestRecordsitems.java View File

@ -0,0 +1,28 @@
package com.handset.serialportsensor.bean;
import org.kymjs.kjframe.database.annotate.Id;
import org.kymjs.kjframe.database.annotate.Table;
/**
* Created by zy on 2019/2/24.
*/
@Table(name = "test_record_item")
public class TestRecordsitems {
@Id(autoInc = true)
public int id;
/**
* 对应 TestRecordsTotal 中的id
*/
public long test_id;
/**
* 对应数据类型
* 具体类型见报文解析字段
*/
public int type;
/**
* 测试的数据值
*/
public float value;
}

+ 23
- 0
app/src/main/java/com/handset/serialportsensor/bean/ThresholdBean.java View File

@ -0,0 +1,23 @@
package com.handset.serialportsensor.bean;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ThresholdBean {
public String temperatureFloor;
public String temperatureCeiling;
public String humidityFloor;
public String humidityCeiling;
public String innerPressureFloor;
public String innerPressureCeiling;
public String outerPressureFloor;
public String outerPressureCeiling;
public String diffPressureFloor;
public String diffPressureCeiling;
}

+ 74
- 0
app/src/main/java/com/handset/serialportsensor/constant/Constant.java View File

@ -0,0 +1,74 @@
package com.handset.serialportsensor.constant;
import android.graphics.Color;
public class Constant {
public final static String SENSOR_ID = "sensor_id";
public final static String BAUD_RATE = "baud_rate";
public static final String ROLE_KEY = "role_key";
public static final int NOT_CONNECTED_ROLE = 0;
public static final int PRIMARY_ROLE = 1;
public static final int SENIOR_ROLE = 2;
public static final int BAUD_9600 = 9600;
public static final int BAUD_19200 = 19200;
public static final int BAUD_38400 = 38400;
public static final String DDDD = "DDDD";
//ID高16位
public static final String ID_HIGH_KEY = "id_high_key";
//ID低16位
public static final String ID_LOW_KEY = "id_low_key";
public static final String THRESHOLD_KEY = "id_key";
public static final String idHigh1 = "id1";
public static final String idHigh2 = "id2";
public static final String idHigh3 = "id3";
public static final String idHigh4 = "id4";
public static final int READ_TIME_OUT = 3000;
public static final int READ_TIME_OUT_TIME = 1000;//延迟1秒
public static final String FORMAT_FLOAT_PATTERN = "0.00";
public final static int red = Color.rgb((255), (0), (0));
public final static int green = Color.rgb((0), (255), (0));
public final static int yellow = Color.rgb((255), (255), (0));
public final static int grey = Color.rgb((0x9d), (0x9d), (0x9d));
public static final class Command {
public static final int COMMAND_25 = 0x25;//ID查询
public static final int COMMAND_26 = 0x26;//ID上报
public static final int COMMAND_27 = 0x27;//检测仪模式切换
public static final int COMMAND_28 = 0x28;//模式切换结果指令上报
public static final int COMMAND_29 = 0x29;//温度指令上报
public static final int COMMAND_2A = 0x2A;//内压指令上报
public static final int COMMAND_2B = 0x2B;//湿度指令上报
public static final int COMMAND_2C = 0x2C;//外压指令上报
public static final int COMMAND_2D = 0x2D;//差压指令上报
public static final int COMMAND_2E = 0x2E;//20度湿度指令上报
public static final int COMMAND_2F = 0x2F;//20度内压指令上报
public static final int COMMAND_30 = 0x30;//弹号读取
public static final int COMMAND_31 = 0x31;//弹号指令上报
public static final int COMMAND_32 = 0x32;//弹号设置
public static final int COMMAND_33 = 0x33;//弹号设置指令上报
public static final int COMMAND_34 = 0x34;//筒号读取
public static final int COMMAND_35 = 0x35;//筒号指令上报
public static final int COMMAND_36 = 0x36;//筒号设置
public static final int COMMAND_37 = 0x37;//筒号设置指令上报
public static final int COMMAND_38 = 0x38;//弹筒使用次数读取
public static final int COMMAND_39 = 0x39;//弹筒使用次数指令上报
public static final int COMMAND_3A = 0x3A;//弹筒使用次数设置
public static final int COMMAND_3B = 0x3B;//弹筒使用次数设置指令上报
public static final int COMMAND_3C = 0x3C;//波特率设置
public static final int COMMAND_3D = 0x3D;//波特率设置结果指令上报
public static final int COMMAND_3E = 0x3E; //弹型读取
public static final int COMMAND_3F = 0x3F; //弹型读取回复
public static final int COMMAND_40 = 0x40; //弹型设置
public static final int COMMAND_41 = 0x41; //弹型设置回复
public static final int COMMAND_49 = 0x49;//恢复出厂设置
public static final int COMMAND_4A = 0x4A;//恢复出厂设置结果返回
public static final int COMMAND_50 = 0x50;//传感器ID设置
public static final int COMMAND_51 = 0x51;//传感器ID设置
}
}

+ 55
- 0
app/src/main/java/com/handset/serialportsensor/db/DBUpdateHelperMY.java View File

@ -0,0 +1,55 @@
package com.handset.serialportsensor.db;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import org.kymjs.kjframe.KJDB;
/**
* Created by zy on 2019/3/7.
*/
public class DBUpdateHelperMY implements KJDB.DbUpdateListener {
private static final String TAG = com.suntiago.dblib.DBUpdateHelper.class.getSimpleName();
public static final int DATABASE_VERSION = 2;
public DBUpdateHelperMY() {
}
public void onCreate(Context context, SQLiteDatabase sqLiteDatabase) {
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
if (tabbleIsExist(db, "sensor")) {
db.execSQL("ALTER TABLE media ADD COLUMN tv_tupe_use_times String DEFAULT \'\';");
}
}
}
public boolean tabbleIsExist(SQLiteDatabase db, String tableName) {
boolean result = false;
if (tableName == null) {
return false;
}
Cursor cursor = null;
try {
//这里表名可以是Sqlite_master
String sql = "select count(*) as c from htjc_sensor_history where type ='table' and name ='" + tableName + "'";
cursor = db.rawQuery(sql, null);
if (cursor.moveToNext()) {
int count = cursor.getInt(0);
if (count > 0) {
result = true;
}
}
} catch (Exception e) {
// TODO: handle exception
}
return result;
}
}

+ 15
- 0
app/src/main/java/com/handset/serialportsensor/presenter/SurfaceContract.java View File

@ -0,0 +1,15 @@
package com.handset.serialportsensor.presenter;
import com.handset.serialportsensor.bean.RawData;
public interface SurfaceContract {
interface ISerialView {
void onSerialOpen(boolean isOpen);
void onSerialData(RawData rawData);
void onSerialBaudRate(Integer baudRate);
void onSerialError(Integer errorCode);
}
}

+ 315
- 0
app/src/main/java/com/handset/serialportsensor/presenter/SurfacePresenter.java View File

@ -0,0 +1,315 @@
package com.handset.serialportsensor.presenter;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.handset.serialportlib.CRCUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.activity.SPKey;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportlib.SerialPort;
import com.handset.serialportsensor.utils.SplitUtils;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashSet;
import org.joda.time.DateTime;
public class SurfacePresenter {
private static final String logTag = "HANDSET-JE002-EX";
private final static String POWER_EN_PATH = "/sys/class/peijian_dev/function/PeijianPowerEn";
private final static String POGO_WAKE = "/sys/class/peijian_dev/function/pogo_wake";
private final static String SERIAL_PATH = "dev/ttyHSL1";
private final static Integer SERIAL_BAUD_RATE = 38400;
private final static String mDateFormat = "HH:mm:ss:SSS";
private SurfaceContract.ISerialView mSerialView;
private LinkedHashSet<String> mSendHistory;
private int mCheckDigit;
private int mDataBits;
private int mStopBit;
private boolean isHexReceive;
private boolean isHexSend;
private boolean isShowSend;
private boolean isShowTime;
private SerialPort mSerialPort;
private boolean isInterrupted;
private Disposable mReceiveDisposable;
private ObservableEmitter<String> mEmitter;
private Disposable mSendDisposable;
public SurfacePresenter(SurfaceContract.ISerialView view) {
mSerialView = view;
isHexReceive = true;
isHexSend = SPUtils.getInstance().getBoolean(SPKey.SETTING_SEND_TYPE, (true));
isShowSend = SPUtils.getInstance().getBoolean(SPKey.SETTING_RECEIVE_SHOW_SEND, (true));
isShowTime = SPUtils.getInstance().getBoolean(SPKey.SETTING_RECEIVE_SHOW_TIME, (true));
try {
mSendHistory = (LinkedHashSet<String>) SPUtils.getInstance().getStringSet(SPKey.SEND_HISTORY, new LinkedHashSet<>((30)));
} catch (ClassCastException e) {
e.printStackTrace();
mSendHistory = new LinkedHashSet<>((30));
}
}
private void refreshValueFormSp() {
//String mPath = SPUtils.getInstance().getString(SPKey.SERIAL_PORT, (""));
//int mBaudRate = Integer.parseInt(SPUtils.getInstance().getString(SPKey.BAUD_RATE, ("9600")));
mCheckDigit = Integer.parseInt(SPUtils.getInstance().getString(SPKey.CHECK_DIGIT, ("0")));
mDataBits = Integer.parseInt(SPUtils.getInstance().getString(SPKey.DATA_BITS, ("8")));
mStopBit = Integer.parseInt(SPUtils.getInstance().getString(SPKey.STOP_BIT, ("1")));
}
public void open() {
refreshValueFormSp();
try {
mSerialPort = new SerialPort(new File(SERIAL_PATH), SERIAL_BAUD_RATE, mCheckDigit, mDataBits, mStopBit, (0));
} catch (Exception e) {
e.printStackTrace();
mSerialPort = null;
ToastUtils.showLong(R.string.open_serial_port_failure);
}
if (mSerialPort != null) {
this.initBLNStatus('1');
isInterrupted = false;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
onReceiveSubscribe();
onSendSubscribe();
mSerialView.onSerialOpen((mSerialPort != null));
//ToastUtils.showLong(R.string.open_serial_port_success);
} else {
mSerialView.onSerialError((0));
}
}
public void open(Integer baudRate) {
if (baudRate == null) {
Log.i(logTag, ("onSerialBaudRate null"));
return;
}
refreshValueFormSp();
try {
Log.i(logTag, ("onSerialBaudRate: " + baudRate));
mSerialPort = new SerialPort(new File(SERIAL_PATH), baudRate, mCheckDigit, mDataBits, mStopBit, (0));
} catch (IOException e) {
e.printStackTrace();
ToastUtils.showLong(R.string.open_serial_port_failure);
}
if (mSerialPort != null) {
this.initBLNStatus('1');
isInterrupted = false;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
onReceiveSubscribe();
onSendSubscribe();
}
mSerialView.onSerialOpen((mSerialPort != null));
}
public void close() {
Log.i(logTag, ("closing!!!"));
this.initBLNStatus('0');
isInterrupted = true;
disposable(mReceiveDisposable);
disposable(mSendDisposable);
mEmitter = null;
mSerialPort = null;
mSerialView.onSerialOpen((false));
}
public void initBLNStatus(char status) {
setBLNStatus(status, POWER_EN_PATH);
setBLNStatus(status, POGO_WAKE);
}
private void setBLNStatus(char status, String path) {
FileOutputStream fos = null;
try {
File file = new File(path);
if (file.exists()) {
fos = new FileOutputStream(file);
fos.write(status);
fos.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void onSendSubscribe() {
mSendDisposable =
Observable.create((ObservableOnSubscribe<String>) emitter -> mEmitter = emitter)
.filter(s -> !TextUtils.isEmpty(s))
.doOnNext(s -> mSendHistory.add(s))
.doOnNext(s -> {
Log.i(logTag, ("Sent: " + addSpace(s.toUpperCase())));
mSerialPort.getOutputStream().write(isHexSend ? ByteUtils.hexStrToBytes(s) : ByteUtils.strToAsciiBytes(s));
mSerialPort.getOutputStream().flush();
})
.observeOn(AndroidSchedulers.mainThread())
.filter(s -> isShowSend)
.subscribe(s -> {
//Log.d(logTag, ("sender: " + addSpace(s.toUpperCase())));
mSerialView.onSerialData(new RawData(RawData.TYPE_SEND, isShowTime ? DateTime.now().toString(mDateFormat) : "", addSpace(s.toUpperCase())));
}, Throwable::printStackTrace);
}
private void onReceiveSubscribe() {
mReceiveDisposable =
Flowable.create((FlowableOnSubscribe<byte[]>) emitter -> {
int first, available;
InputStream is = mSerialPort.getInputStream();
while (!isInterrupted
&& mSerialPort != null
&& is != null
&& (first = is.read()) != -1) {
do {
available = is.available();
SystemClock.sleep((1));
} while (available != is.available());
available = is.available();
byte[] bytes = new byte[available + 1];
int n = is.read(bytes, (1), available);
Log.d(logTag, ("Received n: " + n + ", raw: " + ByteUtils.bytesToHexStr(bytes)));
bytes[0] = (byte) (first & 0xFF);
Log.d(logTag, ("Received first: " + first + ", raw: " + ByteUtils.bytesToHexStr(bytes)));
emitter.onNext(bytes);
}
Log.d(logTag, ("onReceiveSubscribe close:"));
close();
}, BackpressureStrategy.MISSING
).retry().map(bytes -> isHexReceive ? ByteUtils.bytesToHexStr(bytes) : ByteUtils.bytesToAscii(bytes))
.filter(this::validate)
.filter(this::crcVerify)
.map(this::getBody)
.subscribeOn(Schedulers.single())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
it -> {
Log.v(logTag, ("Received: " + addSpace(it)));
mSerialView.onSerialData(new RawData(RawData.TYPE_RECEIVE, isShowTime ? DateTime.now().toString(mDateFormat) : "", it));
}, Throwable::printStackTrace
);
}
private boolean validate(String raw) {
try {
Log.v(logTag, ("len: " + raw.length()));
return !TextUtils.isEmpty(raw) && raw.length() >= 22;
} catch (Exception e) {
Log.v(logTag, ("validate, exp: " + e.getMessage()));
return false;
}
}
private boolean crcVerify(String rawData) {
try {
Log.v(logTag, ("crcVerify: " + rawData));
for (String str : SplitUtils.split(rawData)) {
if (TextUtils.isEmpty(str) || str.length() < 4) continue;
if (!CRCUtils.genCrc(str.substring(4, str.length() - 4)).equals(str.substring(str.length() - 4))) {
Log.w(logTag, ("str: " + str + " crc fail!"));
return (str.charAt(12) == '0' && str.charAt(13) == '0' && str.charAt(14) == '2' && str.charAt(15) == '6');
}
}
return true;
} catch (Exception e) {
Log.v(logTag, ("crcVerify, exp: " + e.getMessage()));
return false;
}
}
private String getBody(String raw) {
return raw;
}
private String addSpace(String s) {
if (s.length() % 2 == 0) {
StringBuilder builder = new StringBuilder();
char[] array = s.toCharArray();
int length = array.length;
for (int i = 0; i < length; i += 2) {
if (i != 0 && i <= length - 2) {
builder.append(" ");
}
builder.append(array[i]);
builder.append(array[i + 1]);
}
return builder.toString();
}
return s;
}
public void write(String message) {
if (mEmitter == null) {
ToastUtils.showLong(R.string.open_serial_port_first);
return;
}
if (TextUtils.isEmpty(message)) {
Log.w(logTag, "Message is empty!");
return;
}
mEmitter.onNext(message);
}
public void onDestroy() {
close();
SPUtils.getInstance().put(SPKey.SEND_HISTORY, mSendHistory);
}
private void disposable(Disposable disposable) {
if (disposable != null && !disposable.isDisposed()) {
disposable.dispose();
}
}
}

+ 78
- 0
app/src/main/java/com/handset/serialportsensor/utils/CRC16Utils.java View File

@ -0,0 +1,78 @@
package com.handset.serialportsensor.utils;
/**
* @author dizhou
*/
public class CRC16Utils {
/*
* CCITT标准CRC16(1021)余数表 CRC16-CCITT ISO HDLC, ITU X.25, x16+x12+x5+1 多项式
* 高位在先时生成多项式 Gm=0x11021 低位在先时生成多项式Gm=0x8408 本例采用高位在先
*/
private static int crc16_ccitt_table[] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a,
0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b,
0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528,
0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719,
0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e,
0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf,
0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec,
0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd,
0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2,
0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3,
0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0,
0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691,
0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806,
0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37,
0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64,
0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55,
0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
public static int getCRC1021(byte bytes[]) {
return getCRC2(bytes);
}
public static int getCRC1021_old(byte bytes[]) {
int crc = 0x00; // initial value
int polynomial = 0x1021;
for (int index = 0; index < bytes.length; index++) {
byte b = bytes[index];
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7 - i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) crc ^= polynomial;
}
}
crc &= 0xffff;
return crc;
}
public static int getCRC2(byte[] bytes) {
int CRC = 0xffff;
int POLYNOMIAL = 0xA001;
int i, j;
for (i = 0; i < bytes.length; i++) {
CRC ^= ((int) bytes[i] & 0x00ff);
for (j = 0; j < 8; j++) {
if ((CRC & 0x0001) != 0) {
CRC >>= 1;
CRC ^= POLYNOMIAL;
} else {
CRC >>= 1;
}
}
}
return CRC ;
}
// 测试
// public static void main(String[] args) {
// // 0xf360 DD DD 13 01 03 EF 00 29 04 DB 08 00 00 1B 42
// byte[] a = new byte[]{(byte) 0x13, (byte) 0x01, (byte) 0x03
// , (byte) 0xef
// , (byte) 0x00, (byte) 0x29, (byte) 0x04, (byte) 0xdb, (byte) 0x08, (byte) 0x00, (byte) 0x00};
// int crc2 = getCRC1021(a);
// System.out.println("结果=" + Integer.toHexString(crc2));
//
// }
}

+ 245
- 0
app/src/main/java/com/handset/serialportsensor/utils/CrashHandler.java View File

@ -0,0 +1,245 @@
package com.handset.serialportsensor.utils;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录发送错误报告.
*
* @author Jeremy
*/
public class CrashHandler implements UncaughtExceptionHandler {
public static final String TAG = "HANDSET-JE002-EX";
private static final String BROADCAST_ACTION = "com.ss.permission.crash_log_update";
//private LocalBroadcastManager mLocalBroadcastManager;
//系统默认的UncaughtException处理类
private UncaughtExceptionHandler mDefaultHandler;
//程序的Context对象
private Context mContext;
//用来存储设备信息和异常信息
private Map<String, String> infos = new HashMap<>();
//用于格式化日期,作为日志文件名的一部分
private DateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.CHINA);
private String packageName = "";
private static class CrashHandlerHolder {
private static CrashHandler instance = new CrashHandler();
}
/**
* 保证只有一个CrashHandler实例
*/
private CrashHandler() {
}
/**
* 获取CrashHandler实例 ,单例模式
*/
public static CrashHandler getInstance() {
return CrashHandlerHolder.instance;
}
private String getCrashLogPath() {
return getSavePath();
}
private static String getSavePath() {
return Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "htjc" + File.separator + "sensor" + File.separator + "crashlog/";
}
/**
* 初始化
* use init(Context context) instead
*
* @param context context
*/
@Deprecated
public void init(Context context, String com, String pkgId) {
mContext = context;
//获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
//mLocalBroadcastManager = LocalBroadcastManager.getInstance(mContext);
//设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
if (!TextUtils.isEmpty(pkgId)) {
this.packageName = pkgId;
}
}
public void init(Context context) {
mContext = context;
//获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
//mLocalBroadcastManager = LocalBroadcastManager.getInstance(mContext);
//设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
String pkgId = context.getPackageName().replace(".", "_") + "_";
if (!TextUtils.isEmpty(pkgId)) {
this.packageName = pkgId;
}
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
//如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Log.e(TAG, "error : ", e);
}
//退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
*
* @param ex 异常
* @return true:如果处理了该异常信息;否则返回false.
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
//使用Toast来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
//收集设备参数信息
collectDeviceInfo(mContext);
//打印异常log,以供分析调试
ex.printStackTrace();
//保存日志文件
String path = saveCrashInfo2File(ex);
Log.d(TAG, BROADCAST_ACTION);
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
intent.putExtra("path", path);
intent.putExtra("pkgName", mContext.getPackageName());
mContext.sendBroadcast(intent);
return true;
}
/**
* 收集设备参数信息
*
* @param ctx 异常
*/
private void collectDeviceInfo(Context ctx) {
try {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
infos.put("versionName", versionName);
infos.put("versionCode", versionCode);
}
} catch (NameNotFoundException e) {
Log.e(TAG, "An error occur when collect package info", e);
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
Log.d(TAG, field.getName() + " : " + field.get(null));
} catch (Exception e) {
Log.e(TAG, "An error occur when collect crash info", e);
}
}
}
/**
* 保存错误信息到文件中
*
* @param ex 异常
* @return 返回文件名称, 便于将文件传送到服务器
*/
private String saveCrashInfo2File(Throwable ex) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : infos.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key + "=" + value + "\n");
}
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
try {
long timestamp = System.currentTimeMillis();
String time = formatter.format(new Date());
String pkgNamePath = packageName.replace(".", "_");
String fileName = "crash_" + pkgNamePath + "_" + time + "_" + timestamp + ".log";
String path = getCrashLogPath();
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File dir = new File(path);
if (!dir.exists()) {
boolean res = dir.mkdirs();
Log.v(TAG, ("saveCrashInfo2File res: " + res));
}
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
fos.close();
}
return path + fileName;
} catch (Exception e) {
Log.e(TAG, "an error occur while writing file...", e);
}
return null;
}
}

+ 49
- 0
app/src/main/java/com/handset/serialportsensor/utils/DateStyle.java View File

@ -0,0 +1,49 @@
package com.handset.serialportsensor.utils;
/**
* 从AndroidOne上导入的
* Created by LiGang on 2016/6/1.
*/
public class DateStyle {
/**
* 默认时间格式
*/
public static final String MM_DD = "MM-dd";
public static final String YYYY_MM = "yyyy-MM";
public static final String YYYYMM = "yyyyMM";
public static final String YYYY_MM_DD = "yyyy-MM-dd";
public static final String MM_DD_HH_MM = "MM-dd HH:mm";
public static final String MM_DD_HH_MM_SS = "MM-dd HH:mm:ss";
public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd-HH-mm";
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
/**
* 英文时间格式
*/
public static final String MM_DD_EN = "MM/dd";
public static final String YYYY_MM_EN = "yyyy/MM";
public static final String YYYY_MM_DD_EN = "yyyy/MM/dd";
public static final String MM_DD_HH_MM_EN = "MM/DD HH:mm";
public static final String MM_DD_HH_MM_SS_EN = "MM/dd HH:mm:ss";
public static final String YYYY_MM_DD_HH_MM_EN = "yyyy/MM/dd HH:mm";
public static final String YYYY_MM_DD_HH_MM_SS_EN = "yyyy/MM/dd HH:mm:ss";
/**
* 中文时间格式
*/
public static final String MM_DD_CN = "MM月dd日";
public static final String YYYY_MM_CN = "yyyy年MM月";
public static final String YYYY_MM_DD_CN = "yyyy年MM月dd日";
public static final String MM_DD_HH_MM_CN = "MM月dd日 HH:mm";
public static final String MM_DD_HH_MM_SS_CN = "MM月dd日 HH:mm:ss";
public static final String YYYY_MM_DD_HH_MM_CN = "yyyy年MM月dd日 HH:mm";
public static final String YYYY_MM_DD_HH_MM_SS_CN = "yyyy年MM月dd日 HH:mm:ss";
/**
* 具体时间格式
*/
public static final String HH_MM = "HH:mm";
public static final String HH_MM_SS = "HH:mm:ss";
}

+ 322
- 0
app/src/main/java/com/handset/serialportsensor/utils/DateUtils.java View File

@ -0,0 +1,322 @@
package com.handset.serialportsensor.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
/**
* 日期显示格式化
* Created by LiGang on 2016/6/1.
*/
@SuppressWarnings("ALL")
@SuppressLint("SimpleDateFormat")
public class DateUtils {
/**
* 获取当前时间
* 格式 "yyyy_MM_dd"
*
* @return
*/
public static String currentDateTime() {
return currentDateTime(DateStyle.YYYY_MM_DD);
}
/**
* 获取当前时间
* 指定样式
*
* @param dateStyle 格式
* @return
*/
public static String currentDateTime(String dateStyle) {
SimpleDateFormat formatter = new SimpleDateFormat(dateStyle);
return formatter.format(new Date());
}
/**
* 格式化时间
*
* @param date 时间
* @param style 格式
* @return 格式化结果
*/
public static String format(Date date, String style) {
SimpleDateFormat format = new SimpleDateFormat(style);
return format.format(date);
}
/**
* 今天零点的时间
*
* @param date
* @return
*/
public static Date startOfDate(Date date) {
long time = date.getTime() / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();// 今天零点零分零秒的毫秒数
return new Date(time);
}
/**
* 第一个时间是不是在第二个时间之前
*
* @param date
* @param now
* @return
*/
public static boolean before(Date date, Date now) {
if (date.before(now)) {
return true;
} else {
long between = date.getTime() - now.getTime();
if (between > (24 * 3600000)) {
return false;
}
return true;
}
}
/**
* 今天235959的时间
*
* @param date
* @return
*/
public static Date endOfDate(Date date) {
long time = date.getTime() / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset() + 24 * 60 * 60 * 1000 - 1;
return new Date(time);
}
/**
* 格式化timestamp格式的时间以秒为单位
*
* @param timestamp
* @param dateStyle 格式
* @return 格式化结果
*/
public static String formatSecondTimestamp(long timestamp, String dateStyle) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(timestamp * 1000);
return format(c.getTime(), dateStyle);
}
/**
* 格式化timestamp格式的时间以秒为单位
*
* @param timestamp 毫秒
* @param dateStyle 格式
* @return 格式化结果
*/
public static String formatMilliesTimestamp(long timestamp, String dateStyle) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(timestamp );
return format(c.getTime(), dateStyle);
}
/**
* 根据时间戳格式化日期当天只返回时间其他返回日期
*
* @param timestamp
* @return 格式化的时间
*/
public static String getCurrentTimeIFCurrentDayOrDate(long timestamp) {
Calendar now = Calendar.getInstance();
Calendar c = Calendar.getInstance();
c.setTimeInMillis(timestamp * 1000);
if (c.get(Calendar.YEAR) == now.get(Calendar.YEAR)
&& c.get(Calendar.MONTH) == now.get(Calendar.MONTH)
&& c.get(Calendar.DATE) == now.get(Calendar.DATE)) {
return format(c.getTime(), DateStyle.HH_MM);
}
return format(c.getTime(), DateStyle.YYYY_MM_DD);
}
/**
* 获取yyyy-MM-dd格式日期
*
* @param context
* @param date
* @return
*/
public static String getDateFormatYYYYMMDD(Context context, Date date) {
if (context == null) return null;
SimpleDateFormat format = new SimpleDateFormat(DateStyle.YYYY_MM_DD);
return format.format(date);
}
/**
* 把一个日期格式的字符串转化为日期
*
* @param context
* @param dateStr
* @return
* @throws ParseException
*/
public static Date parseStringToDate(Context context, String dateStr) throws ParseException {
if (context == null || dateStr == null) return null;
SimpleDateFormat format = new SimpleDateFormat(DateStyle.YYYY_MM_DD);
return format.parse(dateStr);
}
/**
* 将一个时间转换为提示性字符串
*
* @param timeStamp 秒值
* @return
*/
public static String convertTimeToFormat(long timeStamp) {
int current = (int) (System.currentTimeMillis() / 1000 - timeStamp);
Calendar calendar = Calendar.getInstance();
String today = DateUtils.format(calendar.getTime(), "yyyy-MM-dd");
String currentYear = DateUtils.format(calendar.getTime(), "yyyy");
calendar.setTimeInMillis(timeStamp * 1000);
String publishDay = DateUtils.format(calendar.getTime(), "yyyy-MM-dd");
String publishYear = DateUtils.format(calendar.getTime(), "yyyy");
String publishMonth = DateUtils.format(calendar.getTime(), "MM-dd HH:mm");
if (current < 60) {
return "刚刚";
} else if (current < 3600) {
if (today.equals(publishDay)) {
return current / 60 + "分钟前";
} else {
return publishMonth;
}
} else if (current < 86400) {
if (today.equals(publishDay)) {
return current / 3600 + "小时前";
} else {
return publishMonth;
}
} else if (current < 31536000) {
if (publishYear.equals(currentYear)) {
return publishMonth;
} else {
return publishDay;
}
} else {
return publishDay;
}
}
/**
* 将一个日期转换为提示性时间字符串
*
* @param date 日期
* @return
*/
public static String formatDateTime(Date date) {
String text;
long dateTime = date.getTime();
if (isSameDay(dateTime)) {
Calendar calendar = GregorianCalendar.getInstance();
if (inOneMinute(dateTime, calendar.getTimeInMillis())) {
return "刚刚";
} else if (inOneHour(dateTime, calendar.getTimeInMillis())) {
return String.format("%d分钟之前", Math.abs(dateTime - calendar.getTimeInMillis()) / 60000);
} else {
calendar.setTime(date);
text = "HH:mm";
}
} else if (isYesterday(dateTime)) {
text = "昨天 HH:mm";
} else if (isSameYear(dateTime)) {
text = "M-d HH:mm";
} else {
text = "yyyy-M-d HH:mm";
}
// 注意如果使用android.text.format.DateFormat这个工具类在API 17之前它只支持adEhkMmszy
return new SimpleDateFormat(text, Locale.CHINA).format(date);
}
/**
* 时间间隔是否在1min内
*
* @param time1 毫秒
* @param time2 毫秒
* @return
*/
private static boolean inOneMinute(long time1, long time2) {
return Math.abs(time1 - time2) < 60000;
}
/**
* 时间间隔是否在1h内
*
* @param time1 毫秒
* @param time2 毫秒
* @return
*/
private static boolean inOneHour(long time1, long time2) {
return Math.abs(time1 - time2) < 3600000;
}
/**
* 是否是同一天
*
* @param time 毫秒
* @return
*/
private static boolean isSameDay(long time) {
long startTime = floorDay(Calendar.getInstance()).getTimeInMillis();
long endTime = ceilDay(Calendar.getInstance()).getTimeInMillis();
return time > startTime && time < endTime;
}
/**
* 是否是昨天
*
* @param time 毫秒
* @return
*/
private static boolean isYesterday(long time) {
Calendar startCal;
startCal = floorDay(Calendar.getInstance());
startCal.add(Calendar.DAY_OF_MONTH, -1);
long startTime = startCal.getTimeInMillis();
Calendar endCal;
endCal = ceilDay(Calendar.getInstance());
endCal.add(Calendar.DAY_OF_MONTH, -1);
long endTime = endCal.getTimeInMillis();
return time > startTime && time < endTime;
}
/**
* 是否是同一年
*
* @param time 毫秒
* @return
*/
private static boolean isSameYear(long time) {
Calendar startCal;
startCal = floorDay(Calendar.getInstance());
startCal.set(Calendar.MONTH, Calendar.JANUARY);
startCal.set(Calendar.DAY_OF_MONTH, 1);
return time >= startCal.getTimeInMillis();
}
private static Calendar floorDay(Calendar startCal) {
startCal.set(Calendar.HOUR_OF_DAY, 0);
startCal.set(Calendar.MINUTE, 0);
startCal.set(Calendar.SECOND, 0);
startCal.set(Calendar.MILLISECOND, 0);
return startCal;
}
private static Calendar ceilDay(Calendar endCal) {
endCal.set(Calendar.HOUR_OF_DAY, 23);
endCal.set(Calendar.MINUTE, 59);
endCal.set(Calendar.SECOND, 59);
endCal.set(Calendar.MILLISECOND, 999);
return endCal;
}
}

+ 144
- 0
app/src/main/java/com/handset/serialportsensor/utils/EmulatorUtils.java View File

@ -0,0 +1,144 @@
package com.handset.serialportsensor.utils;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import java.io.File;
public class EmulatorUtils {
private static final String TAG = "EmulatorDetector";
private static int rating = -1;
/**
* Detects if app is currenly running on emulator, or real device.
* @return true for emulator, false for real devices
*/
public static boolean isEmulator() {
int newRating = 0;
if(rating < 0) {
if (Build.PRODUCT.contains("sdk") ||
Build.PRODUCT.contains("Andy") ||
Build.PRODUCT.contains("ttVM_Hdragon") ||
Build.PRODUCT.contains("google_sdk") ||
Build.PRODUCT.contains("Droid4X") ||
Build.PRODUCT.contains("nox") ||
Build.PRODUCT.contains("sdk_x86") ||
Build.PRODUCT.contains("sdk_google") ||
Build.PRODUCT.contains("vbox86p")) {
newRating++;
}
if (Build.MANUFACTURER.equals("unknown") ||
Build.MANUFACTURER.equals("Genymotion") ||
Build.MANUFACTURER.contains("Andy") ||
Build.MANUFACTURER.contains("MIT") ||
Build.MANUFACTURER.contains("nox") ||
Build.MANUFACTURER.contains("TiantianVM")){
newRating++;
}
if (Build.BRAND.equals("generic") ||
Build.BRAND.equals("generic_x86") ||
Build.BRAND.equals("TTVM") ||
Build.BRAND.contains("Andy")) {
newRating++;
}
if (Build.DEVICE.contains("generic") ||
Build.DEVICE.contains("generic_x86") ||
Build.DEVICE.contains("Andy") ||
Build.DEVICE.contains("ttVM_Hdragon") ||
Build.DEVICE.contains("Droid4X") ||
Build.DEVICE.contains("nox") ||
Build.DEVICE.contains("generic_x86_64") ||
Build.DEVICE.contains("vbox86p")) {
newRating++;
}
if (Build.MODEL.equals("sdk") ||
Build.MODEL.equals("google_sdk") ||
Build.MODEL.contains("Droid4X") ||
Build.MODEL.contains("TiantianVM") ||
Build.MODEL.contains("Andy") ||
Build.MODEL.equals("Android SDK built for x86_64") ||
Build.MODEL.equals("Android SDK built for x86")) {
newRating++;
}
if (Build.HARDWARE.equals("goldfish") ||
Build.HARDWARE.equals("vbox86") ||
Build.HARDWARE.contains("nox") ||
Build.HARDWARE.contains("ttVM_x86")) {
newRating++;
}
if (Build.FINGERPRINT.contains("generic/sdk/generic") ||
Build.FINGERPRINT.contains("generic_x86/sdk_x86/generic_x86") ||
Build.FINGERPRINT.contains("Andy") ||
Build.FINGERPRINT.contains("ttVM_Hdragon") ||
Build.FINGERPRINT.contains("generic_x86_64") ||
Build.FINGERPRINT.contains("generic/google_sdk/generic") ||
Build.FINGERPRINT.contains("vbox86p") ||
Build.FINGERPRINT.contains("generic/vbox86p/vbox86p")) {
newRating++;
}
try {
String opengl = android.opengl.GLES20.glGetString(android.opengl.GLES20.GL_RENDERER);
if (opengl != null){
if( opengl.contains("Bluestacks") ||
opengl.contains("Translator")
)
newRating += 10;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
File sharedFolder = new File(Environment
.getExternalStorageDirectory().toString()
+ File.separatorChar
+ "windows"
+ File.separatorChar
+ "BstSharedFolder");
if (sharedFolder.exists()) {
newRating += 10;
}
} catch (Exception e) {
e.printStackTrace();
}
rating = newRating;
}
return rating > 3;
}
/**
* Returns string with human-readable listing of Build.* parameters used in {@link #isEmulator()} method.
* @return all involved Build.* parameters and its values
*/
public static String getDeviceListing() {
return "Build.PRODUCT: " + Build.PRODUCT + "\n" +
"Build.MANUFACTURER: " + Build.MANUFACTURER + "\n" +
"Build.BRAND: " + Build.BRAND + "\n" +
"Build.DEVICE: " + Build.DEVICE + "\n" +
"Build.MODEL: " + Build.MODEL + "\n" +
"Build.HARDWARE: " + Build.HARDWARE + "\n" +
"Build.FINGERPRINT: " + Build.FINGERPRINT + "\n" +
"Build.TAGS: " + android.os.Build.TAGS + "\n" +
"GL_RENDERER: " +android.opengl.GLES20.glGetString(android.opengl.GLES20.GL_RENDERER) + "\n" +
"GL_VENDOR: " +android.opengl.GLES20.glGetString(android.opengl.GLES20.GL_VENDOR) + "\n" +
"GL_VERSION: " +android.opengl.GLES20.glGetString(android.opengl.GLES20.GL_VERSION) + "\n" +
"GL_EXTENSIONS: " +android.opengl.GLES20.glGetString(android.opengl.GLES20.GL_EXTENSIONS) + "\n";
}
/**
* Prints all Build.* parameters used in {@link #isEmulator()} method to logcat.
*/
public static void logcat() {
Log.d(TAG, getDeviceListing());
}
}

+ 368
- 0
app/src/main/java/com/handset/serialportsensor/utils/ExcelMa.java View File

@ -0,0 +1,368 @@
package com.handset.serialportsensor.utils;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import com.handset.serialportsensor.bean.Sensor;
import com.handset.serialportsensor.bean.TestRecordsTotal;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.kymjs.kjframe.KJDB;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import static com.handset.serialportsensor.utils.DateStyle.YYYY_MM_DD_HH_MM_SS;
/**
* Created by zy on 2019/3/4.
*/
public class ExcelMa {
private final static String TAG = "ExcelMa";
public static String getSavePath() {
String path = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "htjc" + File.separator + "sensor" + File.separator + "export" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
return path;
}
public static File getSavePathFile() {
String path = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "htjc" + File.separator + "sensor" + File.separator + "export" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
return dir;
}
public void createExcel() {
String name = getSavePath() + "workbook.xlsx";
Workbook wb = new XSSFWorkbook();
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(name);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
wb.write(fileOut);
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void stopExport() {
exportStatus = false;
}
public void write(List<TestRecordsTotal> testRecordsTotals, PersistHelper.ExportCallback exportCallback, String timePerfix) {
exportStatus = true;
int counts = testRecordsTotals.size();
int remain = counts;
for (int i = 0; i < counts; i++) {
if (!exportStatus) {
break;
}
remain = counts - i;
exportCallback.exportProgress(counts, remain);
write(testRecordsTotals.get(i), timePerfix);
remain = counts - i - 1;
exportCallback.exportProgress(counts, remain);
if (!exportStatus) {
break;
}
}
exportCallback.finish(counts, remain);
}
public void write(TestRecordsTotal t, Sensor s, String tiems) {
File cacheDir = getSavePathFile();
String sheetNama = t.sensor_id + "(" + tiems + ")";
String outFileName = "检测结果(" + tiems + ").xlsx";
File outFile = new File(cacheDir, outFileName);
InputStream stream = null;
try {
stream = new FileInputStream(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
XSSFWorkbook workbook = null;
try {
if (stream != null) {
workbook = new XSSFWorkbook(stream);
}
} catch (IOException e) {
e.printStackTrace();
}
if (workbook == null) {
workbook = new XSSFWorkbook();
Log.d(TAG, "write [t, s]:" + "create workbook");
}
XSSFSheet sheet = workbook.getSheet(sheetNama);
if (sheet == null) {
sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName(sheetNama));
Log.d(TAG, "write [t, s]:" + "create sheet" + sheetNama);
}
int rows = sheet.getPhysicalNumberOfRows();
Log.d(TAG, "write [t, s]rows:" + rows);
if (rows == 0) {
XSSFRow row = sheet.createRow(0);
row.createCell(0).setCellValue("采样时间戳");
row.createCell(1).setCellValue("高精度温度(℃)温度");
row.createCell(2).setCellValue("高精度湿度(%RH)");
row.createCell(3).setCellValue("高精度内压(kPa)");
row.createCell(4).setCellValue("高精度外压(kPa)");
row.createCell(5).setCellValue("差压(kPa");
row.createCell(6).setCellValue("20℃湿度(%RH)");
row.createCell(7).setCellValue("20℃压力(kPa)");
row.createCell(8).setCellValue("传感器编号");
row.createCell(9).setCellValue("弹型");
row.createCell(10).setCellValue("弹号");
row.createCell(11).setCellValue("筒号");
row.createCell(12).setCellValue("弹筒使用次数");
row.createCell(13).setCellValue("波特率");
rows++;
}
XSSFRow row = sheet.createRow(rows);
row.createCell(0).setCellValue(DateUtils.formatMilliesTimestamp(t.end_time, YYYY_MM_DD_HH_MM_SS));
row.createCell(1).setCellValue(t.temp);
row.createCell(2).setCellValue(t.Hum);
row.createCell(3).setCellValue(t.pressurein);
row.createCell(4).setCellValue(t.pressureout);
row.createCell(5).setCellValue(t.pressure_yacha);
row.createCell(6).setCellValue(t.Hum20);
row.createCell(7).setCellValue(t.pressurein20);
row.createCell(8).setCellValue(t.sensor_id);
row.createCell(9).setCellValue(s.egg_type);
row.createCell(10).setCellValue(s.egg_id);
row.createCell(11).setCellValue(s.tupe_id);
row.createCell(12).setCellValue(t.tupe_use_times);
row.createCell(13).setCellValue(t.botelv);
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
workbook.write(fileOut);
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void write(TestRecordsTotal t, String timePerfix) {
List<Sensor> s = KJDB.getDefaultInstance().findAllByWhere(Sensor.class, "sensor_id = " + t.sensor_id + "");
if (s == null || s.size() == 0) {
Log.e(TAG, "write [t]:" + "save test record failed, no sensor id info" + t.sensor_id + "");
return;
}
write(t, s.get(0), timePerfix);
}
protected String getCellAsString(Row row, int c, FormulaEvaluator formulaEvaluator) {
String value = "";
try {
Cell cell = row.getCell(c);
CellValue cellValue = formulaEvaluator.evaluate(cell);
switch (cellValue.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
value = "" + cellValue.getBooleanValue();
break;
case Cell.CELL_TYPE_NUMERIC:
double numericValue = cellValue.getNumberValue();
if (HSSFDateUtil.isCellDateFormatted(cell)) {
double date = cellValue.getNumberValue();
SimpleDateFormat formatter =
new SimpleDateFormat("dd/MM/yy");
value = formatter.format(HSSFDateUtil.getJavaDate(date));
} else {
value = "" + numericValue;
}
break;
case Cell.CELL_TYPE_STRING:
value = "" + cellValue.getStringValue();
break;
default:
}
} catch (NullPointerException e) {
/* proper error handling should be here */
e.printStackTrace();
}
return value;
}
public void onWriteClick(TestRecordsTotal testRecordsTotal) {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("mysheet"));
for (int i = 0; i < 10; i++) {
Row row = sheet.createRow(i);
Cell cell = row.createCell(0);
cell.setCellValue(i);
}
String outFileName = "filetoshare.xlsx";
try {
File cacheDir = getSavePathFile();
File outFile = new File(cacheDir, outFileName);
OutputStream outputStream = new FileOutputStream(outFile.getAbsolutePath());
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
//share(outFileName, getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
}
//导出线程的状态
volatile boolean exportStatus = true;
public void onReadClick(File file, PersistHelper.ExportCallback exportCallback) {
exportStatus = true;
PersistHelper.resetDB();
int dataItems = 0;
int remain = dataItems;
Log.d(TAG, "onReadClick [view]:");
try {
InputStream stream = new FileInputStream(file);
XSSFWorkbook workbook = new XSSFWorkbook(stream);
int sheetsNums = workbook.getNumberOfSheets();
Log.d(TAG, "onReadClick [file]sheetsNums:" + sheetsNums);
dataItems = 0;
for (int i = 0; i < sheetsNums; i++) {
dataItems += workbook.getSheetAt(i).getPhysicalNumberOfRows() - 1;
}
Log.d(TAG, "onReadClick [file]dataItems:" + dataItems);
remain = dataItems;
exportCallback.exportProgress(dataItems, remain);
Calendar calendar = Calendar.getInstance();
for (int i = 0; i < sheetsNums; i++) {
if (!exportStatus) {
break;
}
Sensor s = new Sensor();
XSSFSheet sheet = workbook.getSheetAt(i);
int rowsCount = sheet.getPhysicalNumberOfRows();
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
for (int r = 1; r < rowsCount; r++) {
if (!exportStatus) {
break;
}
Row row = sheet.getRow(r);
int cellsCount = row.getPhysicalNumberOfCells();
TestRecordsTotal testRecordsTotal = new TestRecordsTotal();
testRecordsTotal.id = PersistHelper.generateNextTestId();
String et = getCellAsString(row, 0, formulaEvaluator);
//2019-03-05 14:52:42
calendar.set(
Integer.parseInt(et.substring(0, 4)),
Integer.parseInt(et.substring(5, 7)) - 1,
Integer.parseInt(et.substring(8, 10)),
Integer.parseInt(et.substring(11, 13)),
Integer.parseInt(et.substring(14, 16)),
Integer.parseInt(et.substring(17, 19)));
String te = getCellAsString(row, 1, formulaEvaluator);
testRecordsTotal.temp = Float.parseFloat(te);
String hum = getCellAsString(row, 2, formulaEvaluator);
testRecordsTotal.Hum = Float.parseFloat(hum);
String neiya = getCellAsString(row, 3, formulaEvaluator);
testRecordsTotal.pressurein = Float.parseFloat(neiya);
String waiya = getCellAsString(row, 4, formulaEvaluator);
testRecordsTotal.pressureout = Float.parseFloat(waiya);
String yacha = getCellAsString(row, 5, formulaEvaluator);
testRecordsTotal.pressure_yacha = Float.parseFloat(yacha);
String shidu20 = getCellAsString(row, 6, formulaEvaluator);
testRecordsTotal.Hum20 = Float.parseFloat(shidu20);
String yali20 = getCellAsString(row, 7, formulaEvaluator);
testRecordsTotal.pressurein20 = Float.parseFloat(yali20);
testRecordsTotal.end_time = calendar.getTimeInMillis();
calendar.setTimeInMillis(testRecordsTotal.end_time);
testRecordsTotal.day_t = calendar.get(Calendar.DAY_OF_YEAR) + calendar.get(Calendar.YEAR) * 1000;
String sensor_id = getCellAsString(row, 8, formulaEvaluator);
if (sensor_id.length() > 8) {
sensor_id = sensor_id.replace(".", "").substring(0, 8);
}
testRecordsTotal.sensor_id = Long.parseLong(sensor_id);
s.sensor_id = testRecordsTotal.sensor_id;
String danxing = getCellAsString(row, 9, formulaEvaluator);
s.egg_type = danxing;
String danhao = getCellAsString(row, 10, formulaEvaluator);
s.egg_id = danhao;
String tonghao = getCellAsString(row, 11, formulaEvaluator);
s.tupe_id = tonghao;
String tupeUsetimes = getCellAsString(row, 12, formulaEvaluator);
if (!TextUtils.isEmpty(tupeUsetimes)) {
if (tupeUsetimes.endsWith(".0")) {
tupeUsetimes = tupeUsetimes.replace(".0", "");
}
s.tv_tupe_use_times = tupeUsetimes;
testRecordsTotal.tupe_use_times = tupeUsetimes;
}
String botelv = getCellAsString(row, 13, formulaEvaluator);
testRecordsTotal.botelv = botelv;
if (KJDB.getDefaultInstance().findById(testRecordsTotal.id, TestRecordsTotal.class) != null) {
KJDB.getDefaultInstance().update(testRecordsTotal);
} else {
KJDB.getDefaultInstance().save(testRecordsTotal);
}
remain--;
exportCallback.exportProgress(dataItems, remain);
if (!exportStatus) {
break;
}
}
if (KJDB.getDefaultInstance().findById(s.id, Sensor.class) != null) {
KJDB.getDefaultInstance().update(s);
} else {
KJDB.getDefaultInstance().save(s);
}
}
stream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
exportCallback.finish(dataItems, remain);
}
}

+ 364
- 0
app/src/main/java/com/handset/serialportsensor/utils/ExcelUtils.java View File

@ -0,0 +1,364 @@
package com.handset.serialportsensor.utils;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import com.handset.serialportsensor.bean.Sensor;
import com.handset.serialportsensor.bean.TestRecordsTotal;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.kymjs.kjframe.KJDB;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
/**
* Created by zy on 2019/3/4.
*/
public class ExcelUtils {
private final static String TAG = "ExcelMa";
public static String getSavePath() {
String path = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "htjc" + File.separator + "sensor" + File.separator + "export" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
return path;
}
public static File getSavePathFile() {
String path = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "htjc" + File.separator + "sensor" + File.separator + "export" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
return dir;
}
public void createExcel() {
String name = getSavePath() + "workbook.xlsx";
Workbook wb = new XSSFWorkbook();
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(name);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
wb.write(fileOut);
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void stopExport() {
exportStatus = false;
}
public void write(List<TestRecordsTotal> testRecordsTotals, PersistHelper.ExportCallback exportCallback, String timePerfix) {
exportStatus = true;
int counts = testRecordsTotals.size();
int remain = counts;
for (int i = 0; i < counts; i++) {
if (!exportStatus) {
break;
}
remain = counts - i;
exportCallback.exportProgress(counts, remain);
write(testRecordsTotals.get(i), timePerfix);
remain = counts - i - 1;
exportCallback.exportProgress(counts, remain);
if (!exportStatus) {
break;
}
}
exportCallback.finish(counts, remain);
}
public void write(TestRecordsTotal t, Sensor s, String tiems) {
File cacheDir = getSavePathFile();
String sheetNama = t.sensor_id + "(" + tiems + ")";
String outFileName = "检测结果(" + tiems + ").xlsx";
File outFile = new File(cacheDir, outFileName);
InputStream stream = null;
try {
stream = new FileInputStream(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
XSSFWorkbook workbook = null;
try {
if (stream != null) {
workbook = new XSSFWorkbook(stream);
}
} catch (IOException e) {
e.printStackTrace();
}
if (workbook == null) {
workbook = new XSSFWorkbook();
Log.d(TAG, "write [t, s]:" + "create workbook");
}
XSSFSheet sheet = workbook.getSheet(sheetNama);
if (sheet == null) {
sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName(sheetNama));
Log.d(TAG, "write [t, s]:" + "create sheet" + sheetNama);
}
int rows = sheet.getPhysicalNumberOfRows();
Log.d(TAG, "write [t, s]rows:" + rows);
if (rows == 0) {
XSSFRow row = sheet.createRow(0);
row.createCell(0).setCellValue("采样时间戳");
row.createCell(1).setCellValue("高精度温度(℃)温度");
row.createCell(2).setCellValue("高精度湿度(%RH)");
row.createCell(3).setCellValue("高精度内压(kPa)");
row.createCell(4).setCellValue("高精度外压(kPa)");
row.createCell(5).setCellValue("差压(kPa");
row.createCell(6).setCellValue("20℃湿度(%RH)");
row.createCell(7).setCellValue("20℃压力(kPa)");
row.createCell(8).setCellValue("传感器编号");
row.createCell(9).setCellValue("弹型");
row.createCell(10).setCellValue("弹号");
row.createCell(11).setCellValue("筒号");
row.createCell(12).setCellValue("弹筒使用次数");
row.createCell(13).setCellValue("波特率");
rows++;
}
XSSFRow row = sheet.createRow(rows);
row.createCell(0).setCellValue(DateUtils.formatMilliesTimestamp(t.end_time, "yyyy-MM-dd HH:mm:ss"));
row.createCell(1).setCellValue(t.temp);
row.createCell(2).setCellValue(t.Hum);
row.createCell(3).setCellValue(t.pressurein);
row.createCell(4).setCellValue(t.pressureout);
row.createCell(5).setCellValue(t.pressure_yacha);
row.createCell(6).setCellValue(t.Hum20);
row.createCell(7).setCellValue(t.pressurein20);
row.createCell(8).setCellValue(t.sensor_id);
row.createCell(9).setCellValue(s.egg_type);
row.createCell(10).setCellValue(s.egg_id);
row.createCell(11).setCellValue(s.tupe_id);
row.createCell(12).setCellValue(t.tupe_use_times);
row.createCell(13).setCellValue(t.botelv);
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
workbook.write(fileOut);
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void write(TestRecordsTotal t, String timePerfix) {
List<Sensor> s = KJDB.getDefaultInstance().findAllByWhere(Sensor.class, "sensor_id = " + t.sensor_id + "");
if (s == null || s.size() == 0) {
Log.e(TAG, "write [t]:" + "save test record failed, no sensor id info" + t.sensor_id + "");
return;
}
write(t, s.get(0), timePerfix);
}
protected String getCellAsString(Row row, int c, FormulaEvaluator formulaEvaluator) {
String value = "";
try {
Cell cell = row.getCell(c);
CellValue cellValue = formulaEvaluator.evaluate(cell);
switch (cellValue.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
value = "" + cellValue.getBooleanValue();
break;
case Cell.CELL_TYPE_NUMERIC:
double numericValue = cellValue.getNumberValue();
if (HSSFDateUtil.isCellDateFormatted(cell)) {
double date = cellValue.getNumberValue();
SimpleDateFormat formatter =
new SimpleDateFormat("dd/MM/yy");
value = formatter.format(HSSFDateUtil.getJavaDate(date));
} else {
value = "" + numericValue;
}
break;
case Cell.CELL_TYPE_STRING:
value = "" + cellValue.getStringValue();
break;
default:
}
} catch (NullPointerException e) {
/* proper error handling should be here */
e.printStackTrace();
}
return value;
}
public void onWriteClick(TestRecordsTotal testRecordsTotal) {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("mysheet"));
for (int i = 0; i < 10; i++) {
Row row = sheet.createRow(i);
Cell cell = row.createCell(0);
cell.setCellValue(i);
}
String outFileName = "filetoshare.xlsx";
try {
File cacheDir = getSavePathFile();
File outFile = new File(cacheDir, outFileName);
OutputStream outputStream = new FileOutputStream(outFile.getAbsolutePath());
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
//share(outFileName, getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
}
//导出线程的状态
volatile boolean exportStatus = true;
public void onReadClick(File file, PersistHelper.ExportCallback exportCallback) {
exportStatus = true;
PersistHelper.resetDB();
int dataItems = 0;
int remain = dataItems;
Log.d(TAG, "onReadClick [view]:");
try {
InputStream stream = new FileInputStream(file);
XSSFWorkbook workbook = new XSSFWorkbook(stream);
int sheetsNums = workbook.getNumberOfSheets();
Log.d(TAG, "onReadClick [file]sheetsNums:" + sheetsNums);
dataItems = 0;
for (int i = 0; i < sheetsNums; i++) {
dataItems += workbook.getSheetAt(i).getPhysicalNumberOfRows() - 1;
}
Log.d(TAG, "onReadClick [file]dataItems:" + dataItems);
remain = dataItems;
exportCallback.exportProgress(dataItems, remain);
Calendar calendar = Calendar.getInstance();
for (int i = 0; i < sheetsNums; i++) {
if (!exportStatus) {
break;
}
Sensor s = new Sensor();
XSSFSheet sheet = workbook.getSheetAt(i);
int rowsCount = sheet.getPhysicalNumberOfRows();
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
for (int r = 1; r < rowsCount; r++) {
if (!exportStatus) {
break;
}
Row row = sheet.getRow(r);
int cellsCount = row.getPhysicalNumberOfCells();
TestRecordsTotal testRecordsTotal = new TestRecordsTotal();
testRecordsTotal.id = PersistHelper.generateNextTestId();
String et = getCellAsString(row, 0, formulaEvaluator);
//2019-03-05 14:52:42
calendar.set(
Integer.parseInt(et.substring(0, 4)),
Integer.parseInt(et.substring(5, 7)) - 1,
Integer.parseInt(et.substring(8, 10)),
Integer.parseInt(et.substring(11, 13)),
Integer.parseInt(et.substring(14, 16)),
Integer.parseInt(et.substring(17, 19)));
String te = getCellAsString(row, 1, formulaEvaluator);
testRecordsTotal.temp = Float.parseFloat(te);
String hum = getCellAsString(row, 2, formulaEvaluator);
testRecordsTotal.Hum = Float.parseFloat(hum);
String neiya = getCellAsString(row, 3, formulaEvaluator);
testRecordsTotal.pressurein = Float.parseFloat(neiya);
String waiya = getCellAsString(row, 4, formulaEvaluator);
testRecordsTotal.pressureout = Float.parseFloat(waiya);
String yacha = getCellAsString(row, 5, formulaEvaluator);
testRecordsTotal.pressure_yacha = Float.parseFloat(yacha);
String shidu20 = getCellAsString(row, 6, formulaEvaluator);
testRecordsTotal.Hum20 = Float.parseFloat(shidu20);
String yali20 = getCellAsString(row, 7, formulaEvaluator);
testRecordsTotal.pressurein20 = Float.parseFloat(yali20);
testRecordsTotal.end_time = calendar.getTimeInMillis();
calendar.setTimeInMillis(testRecordsTotal.end_time);
testRecordsTotal.day_t = calendar.get(Calendar.DAY_OF_YEAR) + calendar.get(Calendar.YEAR) * 1000;
String sensor_id = getCellAsString(row, 8, formulaEvaluator);
if (sensor_id.length() > 8) {
sensor_id = sensor_id.replace(".", "").substring(0, 8);
}
testRecordsTotal.sensor_id = Long.parseLong(sensor_id);
s.sensor_id = testRecordsTotal.sensor_id;
String danxing = getCellAsString(row, 9, formulaEvaluator);
s.egg_type = danxing;
String danhao = getCellAsString(row, 10, formulaEvaluator);
s.egg_id = danhao;
String tonghao = getCellAsString(row, 11, formulaEvaluator);
s.tupe_id = tonghao;
String tupeUsetimes = getCellAsString(row, 12, formulaEvaluator);
if (!TextUtils.isEmpty(tupeUsetimes)) {
if (tupeUsetimes.endsWith(".0")) {
tupeUsetimes = tupeUsetimes.replace(".0", "");
}
s.tv_tupe_use_times = tupeUsetimes;
testRecordsTotal.tupe_use_times = tupeUsetimes;
}
String botelv = getCellAsString(row, 13, formulaEvaluator);
testRecordsTotal.botelv = botelv;
if (KJDB.getDefaultInstance().findById(testRecordsTotal.id, TestRecordsTotal.class) != null) {
KJDB.getDefaultInstance().update(testRecordsTotal);
} else {
KJDB.getDefaultInstance().save(testRecordsTotal);
}
remain--;
exportCallback.exportProgress(dataItems, remain);
if (!exportStatus) {
break;
}
}
if (KJDB.getDefaultInstance().findById(s.id, Sensor.class) != null) {
KJDB.getDefaultInstance().update(s);
} else {
KJDB.getDefaultInstance().save(s);
}
}
stream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
exportCallback.finish(dataItems, remain);
}
}

+ 377
- 0
app/src/main/java/com/handset/serialportsensor/utils/PersistHelper.java View File

@ -0,0 +1,377 @@
package com.handset.serialportsensor.utils;
import android.content.Context;
import android.util.Log;
import android.util.SparseArray;
import com.handset.serialportsensor.bean.Sensor;
import com.handset.serialportsensor.bean.TestRecordsTotal;
import org.kymjs.kjframe.KJDB;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.List;
/**
* Created by zy on 2019/2/24.
*/
public class PersistHelper {
private static final String logTag = "HANDSET-JE002-EX";
private static Context sContext;
private static Sensor mSensor = null;
private static ExcelUtils excelUtils;
public static void init(Context context) {
sContext = context;
excelUtils = new ExcelUtils();
}
public static void generateSimulateData() {
KJDB.getDefaultInstance().deleteByWhere(Sensor.class, "1=1");
KJDB.getDefaultInstance().deleteByWhere(TestRecordsTotal.class, "1=1");
initSensor();
}
private static void initSensor() {
Sensor sensor = new Sensor();
sensor.id = 1;
sensor.egg_id = "EGG11234";
sensor.sensor_id = 19011111;
sensor.egg_type = "EGGA1234";
sensor.tupe_id = "TUPEA1234";
KJDB.getDefaultInstance().save(sensor);
sensor.id = 2;
sensor.egg_id = "EGG21234";
sensor.sensor_id = 19011112;
sensor.egg_type = "EGGB1234";
sensor.tupe_id = "TUPEB1234";
KJDB.getDefaultInstance().save(sensor);
TestRecordsTotal testRecordsTotal = new TestRecordsTotal();
long a = 315360000000L;
testRecordsTotal.end_time = System.currentTimeMillis() - a;
testRecordsTotal.Hum = 80;
testRecordsTotal.sensor_id = 19011111;
testRecordsTotal.pressure_yacha = 100;
testRecordsTotal.pressurein = 90;
testRecordsTotal.pressureout = 120;
testRecordsTotal.temp = 50;
testRecordsTotal.Hum20 = 90;
testRecordsTotal.pressurein20 = 20;
testRecordsTotal.tupe_use_times = "10";
int i = 1;
Calendar c = Calendar.getInstance();
for (; i < 5000; i++) {
testRecordsTotal.id = i;
testRecordsTotal.end_time += 24 * 3600000;
c.setTimeInMillis(testRecordsTotal.end_time);
testRecordsTotal.day_t = c.get(Calendar.DAY_OF_YEAR) + c.get(Calendar.YEAR) * 1000;
KJDB.getDefaultInstance().save(testRecordsTotal);
if (i % 100 == 0) {
Log.d(logTag, "initSensor []:" + i);
}
}
testRecordsTotal.sensor_id = 19011112;
for (; i < 10000; i++) {
testRecordsTotal.id = i;
testRecordsTotal.end_time += 24 * 3600000;
c.setTimeInMillis(testRecordsTotal.end_time);
testRecordsTotal.day_t = c.get(Calendar.DAY_OF_YEAR) + c.get(Calendar.YEAR) * 1000;
KJDB.getDefaultInstance().save(testRecordsTotal);
if (i % 100 == 0) {
Log.d(logTag, "initSensor []:" + i);
}
}
}
public static void resetDB() {
KJDB.getDefaultInstance().deleteByWhere(Sensor.class, "1=1");
KJDB.getDefaultInstance().deleteByWhere(TestRecordsTotal.class, "1=1");
SPUtils.getInstance(sContext).put("current_test_id", -1l);
}
public static long generateNextTestId() {
long currentTestId = SPUtils.getInstance(sContext).get("current_test_id", -1L);
long newId = currentTestId == -1 || currentTestId >= 10000000 ? 1 : currentTestId + 1;
TestRecordsTotal old = KJDB.getDefaultInstance().findById(newId, TestRecordsTotal.class);
if (old != null) {
KJDB.getDefaultInstance().delete(old);
}
SPUtils.getInstance(sContext).put("current_test_id", newId);
return newId;
}
private static long NextTestIdCC() {
long currentTestId = SPUtils.getInstance(sContext).get("current_test_id", -1l);
long newId = currentTestId - 1;
if (newId == -1 || newId == 0 || currentTestId >= 10000000) {
newId = 0;
}
TestRecordsTotal old = KJDB.getDefaultInstance().findById(currentTestId, TestRecordsTotal.class);
if (old != null) {
KJDB.getDefaultInstance().delete(old);
}
SPUtils.getInstance(sContext).put("current_test_id", newId);
return newId;
}
/**
* 生成下一个保存数据的Id
* <p>
* 考虑到测试Id保存的的上线是1000 000循环利用ID,超过后复写以前的数据
*/
public static long generateNextTestId(int idHigh1, byte idHigh2, byte idHigh3, byte idHigh4) {
if (sContext == null) {
return -1;
}
long newId = generateNextTestId();
TestRecordsTotal testRecordsTotal = new TestRecordsTotal();
testRecordsTotal.id = newId;
testRecordsTotal.botelv = sbotelv;
Log.d(logTag, "generateNextTestId [idHigh1, idHigh2, idHigh3, idHigh4]:" + newId);
KJDB.getDefaultInstance().save(testRecordsTotal);
if (mSensor == null) {
mSensor = new Sensor();
}
int[] values = ProtoUtils.getSensorNumber(idHigh1, idHigh2, idHigh3, idHigh4);
mSensor.sensor_id = values[1];
return newId;
}
public static void genItem(int sensorId) {
if (sContext == null) {
return;
}
long newId = generateNextTestId();
TestRecordsTotal testRecordsTotal = new TestRecordsTotal();
testRecordsTotal.id = newId;
testRecordsTotal.botelv = sbotelv;
Log.d(logTag, "generateNextTestId [idHigh1, idHigh2, idHigh3, idHigh4]:" + newId);
KJDB.getDefaultInstance().save(testRecordsTotal);
if (mSensor == null) {
mSensor = new Sensor();
}
mSensor.sensor_id = sensorId;
}
public static void genItem(int sensorId, String baudRate) {
if (sContext == null) {
return;
}
long newId = generateNextTestId();
TestRecordsTotal testRecordsTotal = new TestRecordsTotal();
testRecordsTotal.id = newId;
testRecordsTotal.botelv = baudRate;
Log.d(logTag, "generateNextTestId [idHigh1, idHigh2, idHigh3, idHigh4]:" + newId);
KJDB.getDefaultInstance().save(testRecordsTotal);
if (mSensor == null) {
mSensor = new Sensor();
}
mSensor.sensor_id = sensorId;
}
static String sbotelv = "38400";
public static void mateSuccess(String botelv) {
sbotelv = botelv;
}
public static long getCurrentTestId() {
if (sContext == null) {
return -1;
}
return SPUtils.getInstance(sContext).get("current_test_id", -1l);
}
public static TestRecordsTotal getCurrentTestRecordsTotal() {
if (sContext == null) {
return null;
}
long id = getCurrentTestId();
if (id == -1) {
return null;
}
return KJDB.getDefaultInstance().findById(id, TestRecordsTotal.class);
}
public static void saveEggID(String eggNumber) {
/*TestRecordsTotal testRecordsTotal = getCurrentTestRecordsTotal();
testRecordsTotal.egg_id = eggNumber;
KJDB.getDefaultInstance().update(testRecordsTotal);*/
mSensor.egg_id = eggNumber;
}
public static void saveEggType(String eggType) {
/*TestRecordsTotal testRecordsTotal = getCurrentTestRecordsTotal();
testRecordsTotal.egg_type = eggtype;
KJDB.getDefaultInstance().update(testRecordsTotal);*/
mSensor.egg_type = eggType;
}
public static void saveConeNo(String coneNo) {
/*TestRecordsTotal testRecordsTotal = getCurrentTestRecordsTotal();
testRecordsTotal.tupe_id = coneNumber;
KJDB.getDefaultInstance().update(testRecordsTotal);*/
mSensor.tupe_id = coneNo;
}
public static void saveConeUsedTimes(String usedTimes) {
TestRecordsTotal testRecordsTotal = getCurrentTestRecordsTotal();
testRecordsTotal.tupe_use_times = usedTimes;
mSensor.tv_tupe_use_times = usedTimes;
KJDB.getDefaultInstance().update(testRecordsTotal);
}
private static SparseArray<Item> sItemSparseArray = new SparseArray<>();
public static void save(float value, int type) {
Item i = sItemSparseArray.get(type);
if (i != null) {
i.count++;
i.sum += value;
i.average = i.sum / i.count;
} else {
Item item = new Item();
item.count = 1;
item.sum = value;
item.average = value;
sItemSparseArray.put(type, item);
}
}
public static class Item {
int count = 0;
float sum = 0;
float average = 0;
}
public static void endTest(boolean save) {
if (save) {
endTest();
} else {
NextTestIdCC();
//清楚所有单条记录
sItemSparseArray.clear();
sbotelv = "";
}
}
/*结束本次测试*/
public static void endTest() {
long id = getCurrentTestId();
if (id < 0) {
return;
}
TestRecordsTotal testRecordsTotal = getCurrentTestRecordsTotal();
if (testRecordsTotal == null) {
return;
}
/*温度*/
float temp = -1000;
/*湿度*/
float Hum = -1000;
/*内压*/
float pressurein = -1000;
/*外压*/
float pressureout = -1000;
/*压差*/
float pressure_yacha = -1000;
/*湿度*/
float Hum20 = -1000;
/*内压*/
float pressurein20 = -1000;
Item iItem41 = sItemSparseArray.get(41);
if (iItem41 != null) {
temp = iItem41.average;
}
testRecordsTotal.temp = f(temp);
Item iItem42 = sItemSparseArray.get(42);
if (iItem42 != null) {
pressurein = iItem42.average;
}
testRecordsTotal.pressurein = f(pressurein);
Item iItem43 = sItemSparseArray.get(43);
if (iItem43 != null) {
Hum = iItem43.average;
}
testRecordsTotal.Hum = f(Hum);
Item iItem44 = sItemSparseArray.get(44);
if (iItem44 != null) {
pressureout = iItem44.average;
}
testRecordsTotal.pressureout = f(pressureout);
Item iItem45 = sItemSparseArray.get(45);
if (iItem45 != null) {
pressure_yacha = iItem45.average;
}
testRecordsTotal.pressure_yacha = f(pressure_yacha);
Item iItem46 = sItemSparseArray.get(46);
if (iItem46 != null) {
Hum20 = iItem46.average;
}
testRecordsTotal.Hum20 = f(Hum20);
Item iItem47 = sItemSparseArray.get(47);
if (iItem47 != null) {
pressurein20 = iItem47.average;
}
testRecordsTotal.pressurein20 = f(pressurein20);
testRecordsTotal.end_time = System.currentTimeMillis();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(testRecordsTotal.end_time);
long startDatT = calendar.get(Calendar.DAY_OF_YEAR) + calendar.get(Calendar.YEAR) * 1000;
testRecordsTotal.day_t = startDatT;
List<Sensor> listSensor = KJDB.getDefaultInstance().findAllByWhere(Sensor.class,
"sensor_id=" + mSensor.sensor_id);
if (listSensor != null && listSensor.size() > 0) {
mSensor.id = listSensor.get(0).id;
KJDB.getDefaultInstance().update(mSensor);
} else {
KJDB.getDefaultInstance().save(mSensor);
}
testRecordsTotal.sensor_id = mSensor.sensor_id;
//更新execl信息
//mExeclMa.write(testRecordsTotal);
testRecordsTotal.tagBackup = 0;
KJDB.getDefaultInstance().update(testRecordsTotal);
//清楚所有单条记录
sItemSparseArray.clear();
sbotelv = "";
}
private static float f(float f) {
DecimalFormat df = new DecimalFormat("0.0");
String pressure1 = df.format(f);
try {
Float ff = Float.parseFloat(pressure1);
return ff;
} catch (NumberFormatException e) {
e.printStackTrace();
}
return f;
}
public interface ExportCallback {
void exportProgress(int counts, int remain);
void finish(int counts, int remain);
}
}

+ 25
- 0
app/src/main/java/com/handset/serialportsensor/utils/PixelUtils.java View File

@ -0,0 +1,25 @@
package com.handset.serialportsensor.utils;
import android.content.Context;
public class PixelUtils {
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
public static int sp2px(Context context, float spValue) {
final float fontScale =context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
public static int dp2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public static int px2dp(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue / scale + 0.5f);
}
}

+ 105
- 0
app/src/main/java/com/handset/serialportsensor/utils/ProtoUtils.java View File

@ -0,0 +1,105 @@
package com.handset.serialportsensor.utils;
import com.handset.serialportsensor.constant.Constant;
public class ProtoUtils {
public static final int HEADER_BYTE_NUM = 2;
public static final int ID_BYTE_NUM = 4;
public static final int COMMAND_BYTE_NUM = 2;
private static final int MAX_MANUFACTURER_NO = 2;
private static final int MIN_MANUFACTURER_NO = 0;
public static final int MAX_MANUFACTURER_INTERNAL_NO = 999;
private static final int MIN_MANUFACTURER_INTERNAL_NO = 1;
public static int getCommandValue(int[] values) {
return (values[1] >> 8);
}
public static byte getIdHigh1(int[] values) {
return (byte) ((values[0] >> 24) & 0xFF);
}
public static byte getIdHigh2(int[] values) {
return (byte) ((values[0] >> 16) & 0xFF);
}
public static byte getIdHigh3(int[] values) {
return (byte) ((values[0] >> 8) & 0xFF);
}
public static byte getIdHigh4(int[] values) {
return (byte) (values[0] & 0xFF);
}
public static byte getIdHigh1(int low) {
return (byte) ((low >> 24) & 0xFF);
}
public static byte getIdHigh2(int low) {
return (byte) (low >> 16 & 0xFF);
}
public static byte getIdHigh3(int high) {
return (byte) ((high >> 8) & 0xFF);
}
public static byte getIdHigh4(int high) {
return (byte) (high & 0xFF);
}
public static byte[] getByte4Id(String id) {
byte year = (byte) Integer.parseInt(id.substring(0, 2));
byte batch = (byte) Integer.parseInt(id.substring(2, 4));
Integer num = Integer.parseInt(id.substring(4, 8));
byte numHigh = (byte) (num >> 8 & 0xFF);
byte numLow = (byte) (num & 0xFF);
byte[] last = {year, batch, numHigh, numLow};
return last;
}
public static byte[] genSentCommand11Byte(byte command, byte idHigh1, byte idHigh2, byte idHigh3, byte idHigh4) {
byte[] bytes1 = {idHigh1, idHigh2, idHigh3, idHigh4, 0x00, command, 0x00};
int crc1021 = CRC16Utils.getCRC1021(bytes1);
byte low = (byte) (crc1021 & 0xff);
byte high = (byte) ((crc1021 >> 8) & 0xff);
byte[] getIdBuffer = {(byte) 0xDD, (byte) 0xDD, idHigh1, idHigh2, idHigh3, idHigh4, 0x00, command, 0x00, low, high};
return getIdBuffer;
}
public static byte[] genSentCommandSetId(byte idHigh1, byte idHigh2, byte idHigh3, byte idHigh4,
byte nidHigh1, byte nidHigh2, byte nidHigh3, byte nidHigh4) {
byte[] bytes1 = {idHigh1, idHigh2, idHigh3, idHigh4, 0x00, Constant.Command.COMMAND_50, 0x04, nidHigh1, nidHigh2, nidHigh3, nidHigh4};
int crc1021 = CRC16Utils.getCRC1021(bytes1);
byte low = (byte) (crc1021 & 0xff);
byte high = (byte) ((crc1021 >> 8) & 0xff);
byte[] getIdBuffer = {(byte) 0xDD, (byte) 0xDD, idHigh1, idHigh2, idHigh3, idHigh4, 0x00, Constant.Command.COMMAND_50, 0x04,
nidHigh1, nidHigh2, nidHigh3, nidHigh4, low, high};
return getIdBuffer;
}
public static int[] getNumber(byte idHigh1, byte idHigh2) {
int id = (idHigh2 << 8) + idHigh1;
int interId = id % 1000;//厂家内部ID(0x0041-0x2fff) 0x6042
int number = id / 1000;//厂家编号(0-4)
if (interId >= MIN_MANUFACTURER_INTERNAL_NO) {
if (number >= MIN_MANUFACTURER_NO && number <= MAX_MANUFACTURER_NO) {
return new int[]{number, interId};
}
}
return null;
}
public static int[] getSensorNumber(int idHigh1, byte idHigh2, byte idHigh3, byte idHigh4) {
int mId = Utils.byteArray2Int(new byte[]{idHigh3, idHigh4});
int id = (idHigh1 * 100 + idHigh2) * 10000 + mId;
int number = mId / 1000;//厂家编号(0-4)
return new int[]{number, id};
}
}

+ 303
- 0
app/src/main/java/com/handset/serialportsensor/utils/SPUtils.java View File

@ -0,0 +1,303 @@
/*
ShengDao Android Client, PreferencesManager
Copyright (c) 2014 ShengDao Tech Company Limited
*/
package com.handset.serialportsensor.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.text.TextUtils;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
/**
* [PreferencesManager管理类提供get和put方法来重写SharedPreferences所提供的方法更为实用和便捷]
*
* @author huxinwu
* @version 1.0
* @date 2014-3-5
**/
@SuppressWarnings("ALL")
public class SPUtils {
private final String tag = SPUtils.class.getSimpleName();
private Context mContext;
private SharedPreferences preferences;
private String DATA_URL = "/data/data/";
private String SHARED_PREFS = "/shared_prefs";
private static String shareName = "SHARE_DATA";
public static final String THEME = "Theme";
public static final String LANG = "Lang";
private static SPUtils instance;
/**
* 构造方法
*
* @param context
*/
private SPUtils(Context context) {
this(context, shareName);
}
/**
* 构造方法
*
* @param context
* @param shareName
*/
private SPUtils(Context context, String shareName) {
mContext = context;
preferences = context.getSharedPreferences(shareName,
Context.MODE_PRIVATE);
}
/**
* 得到单例模式的PreferencesManager对象
*
* @param context 上下文
* @return
*/
public static SPUtils getInstance(Context context) {
return getInstance(context, shareName);
}
/**
* 得到单例模式的PreferencesManager对象
*
* @param context 上下文
* @param shareName 文件名称
* @return
*/
public static SPUtils getInstance(Context context,
String shareName) {
if (instance == null) {
synchronized (SPUtils.class) {
if (instance == null) {
instance = new SPUtils(context, shareName);
}
}
}
return instance;
}
public void put(String key, boolean value) {
Editor edit = preferences.edit();
if (edit != null) {
edit.putBoolean(key, value);
edit.commit();
}
}
public void put(String key, String value) {
Editor edit = preferences.edit();
if (edit != null) {
edit.putString(key, value);
edit.commit();
}
}
public void put(String key, int value) {
Editor edit = preferences.edit();
if (edit != null) {
edit.putInt(key, value);
edit.commit();
}
}
public void put(String key, float value) {
Editor edit = preferences.edit();
if (edit != null) {
edit.putFloat(key, value);
edit.commit();
}
}
public void put(String key, long value) {
Editor edit = preferences.edit();
if (edit != null) {
edit.putLong(key, value);
edit.commit();
}
}
public void put(String key, Set<String> value) {
Editor edit = preferences.edit();
if (edit != null) {
edit.putStringSet(key, value);
edit.commit();
}
}
/**
* 直接存放对象反射将根据对象的属性作为key并将对应的值保存
*
* @param t
*/
@SuppressWarnings("rawtypes")
public <T> void put(T t) {
try {
String methodName = "";
String saveValue = "";
String fieldName = "";
Editor edit = preferences.edit();
Class cls = t.getClass();
if (edit != null) {
Method[] methods = cls.getDeclaredMethods();
Field[] fields = cls.getDeclaredFields();
for (Method method : methods) {
methodName = method.getName();
for (Field f : fields) {
fieldName = f.getName();
if (methodName.toLowerCase().contains(fieldName.toLowerCase())) {
Object value = method.invoke(t);
if (value != null && !TextUtils.isEmpty(String.valueOf(value))) {
saveValue = String.valueOf(value);
}
edit.putString(fieldName, String.valueOf(saveValue));
break;
}
}
}
edit.commit();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public String get(String key) {
return preferences.getString(key, "");
}
public String get(String key, String defValue) {
return preferences.getString(key, defValue);
}
public boolean get(String key, boolean defValue) {
return preferences.getBoolean(key, defValue);
}
public int get(String key, int defValue) {
return preferences.getInt(key, defValue);
}
public float get(String key, float defValue) {
return preferences.getFloat(key, defValue);
}
public long get(String key, long defValue) {
return preferences.getLong(key, defValue);
}
public Set<String> get(String key, Set<String> defValue) {
return preferences.getStringSet(key, defValue);
}
/**
* 获取整个对象跟put(T t)对应使用 利用反射得到对象的属性然后从preferences获取
*
* @param cls
* @return
*/
public <T> T get(Class<T> cls) {
T obj = null;
String fieldName = "";
try {
obj = cls.newInstance();
Field[] fields = cls.getDeclaredFields();
for (Field f : fields) {
fieldName = f.getName();
if (!"serialVersionUID".equals(fieldName)) {
f.setAccessible(true);
f.set(obj, get(f.getName()));
}
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return obj;
}
public int getTheme(int defThemeId) {
return instance.get(THEME, defThemeId);
}
public void setTheme(int themeId) {
instance.put(THEME, themeId);
}
public String getLanguage(String defLang) {
return instance.get(LANG, defLang);
}
public void setLang(String Language) {
instance.put(LANG, Language);
}
public void clearAll() {
try {
String fileName = shareName + ".xml";
StringBuilder path = new StringBuilder(DATA_URL).append(mContext.getPackageName()).append(SHARED_PREFS);
File file = new File(path.toString(), fileName);
if (file.exists()) {
file.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将对象以 json字符串的形式存到share preference里
*
* @param key
* @param objeat
*/
/*public void put(String key, Object objeat) {
Gson gson = new Gson();
String json = gson.toJson(objeat);
Editor edit = preferences.edit();
if (edit != null) {
edit.putString(key, json);
edit.commit();
}
}*/
/**
* 将json字符串转成对象返回
*
* @param key
* @param cls
* @param <T>
* @return
*/
/*public <T> T get(String key, Class<T> cls) {
//Slog.d("SmartHomePrefs", "setWatchesPhone ");
String json = preferences.getString(key, null);
Gson gson = new Gson();
return gson.fromJson(json, cls);
}*/
}

+ 323
- 0
app/src/main/java/com/handset/serialportsensor/utils/Slog.java View File

@ -0,0 +1,323 @@
package com.handset.serialportsensor.utils;
import android.app.Activity;
import android.content.Context;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.util.Log;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* log 输出保存
* Created by Jeremy on 2015-09-17.
*/
@SuppressWarnings("ALL")
public final class Slog {
public static boolean DEBUG = true;
public static boolean SHOW_ACTIVITY_STATE = true;
private static String LOG_FILE_FIRST_NAME = "com_htjc_sensor_";
private final static String LOG_FILE_END_NAME = "_log.txt";
private static int sLogLevel = 5;
public static final int VERBOSE_L = 5;
public static final int DEBUG_L = 4;
public static final int INFO_L = 3;
public static final int WARN_L = 2;
public static final int ERROR_L = 1;
private static int SDCARD_LOG_FILE_SAVE_NUM = 7;// sd卡中日志文件的最多保存个数
private static final String ERROR_TYPE = "ERROR";
private static final String WARN_TYPE = "WARNING";
private static final String INFO_TYPE = "INFO";
private static final String DEBUG_TYPE = "DEBUG";
private static final String VERBOSE_TYPE = "VERBOSE";
private static String sPath;
private static Context sContext;
private static boolean isSaveLog = false;
public static void init(Context context) {
sContext = context;
LOG_FILE_FIRST_NAME = context.getPackageName().replace(".", "_") + "_";
}
/*use init(Context context) instead
* */
@Deprecated
public static void init(Context context, String com, String pkgId) {
sContext = context;
LOG_FILE_FIRST_NAME = pkgId.replace(".", "_") + "_";
}
public static void setDebug(boolean debug, boolean showActivityStatus) {
DEBUG = debug;
SHOW_ACTIVITY_STATE = showActivityStatus;
}
public static void enableSaveLog(boolean isSaveLog) {
Slog.isSaveLog = isSaveLog;
}
public static String getLogPath() {
return getSavePath();
}
private Slog() {
}
public static void i(String tag, String msg) {
if (DEBUG) {
Log.i(tag, msg);
send("i", tag, msg);
}
}
public static void v(String tag, String msg) {
if (DEBUG) {
Log.v(tag, msg);
send("v", tag, msg);
}
}
public static void d(String tag, String msg) {
if (DEBUG) {
Log.d(tag, msg);
send("d", tag, msg);
}
}
public static void e(String tag, String msg) {
if (DEBUG) {
Log.e(tag, msg);
send("e", tag, msg);
}
}
public static void save(String tag, String msg) {
if (DEBUG) {
Log.d(tag, msg);
saveOP("d", tag, msg);
}
}
public static final void state(String packName, String state) {
if (SHOW_ACTIVITY_STATE)
Log.d(packName, state);
}
public static void send(String e, String tag, String msg) {
if (!isSaveLog) {
return;
}
String logmsg = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) +
" " + e + " " + tag + " " + msg + "";
writeLogToFile(getLogPath(), e, tag, logmsg);
delFile(getLogPath());
}
/**
* 保存操作日志的log
*/
public static void saveOP(String e, String tag, String msg) {
if (!isSaveLog) {
return;
}
String logmsg = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " " + msg + "";
writeLogToFileOP(getSavePathOP(), e, tag, logmsg);
delFile(getSavePathOP());
}
/**
* 打开日志文件并写入日志
*
* @return
**/
private static void writeLogToFileOP(String path, String type, String tag, String text) {// 新建或打开日志文件
try {
String needWriteFile = new SimpleDateFormat("yyyy_MM_dd").format(new Date());
File file = getFileOP(path, needWriteFile);
FileWriter filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据不进行覆盖
BufferedWriter bufWriter = new BufferedWriter(filerWriter);
String needWriteMessage = new String(text.getBytes(), "utf-8") + "\"\n" + "\n";
bufWriter.write(needWriteMessage);
bufWriter.newLine();
bufWriter.close();
filerWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 打开日志文件并写入日志
*
* @return
**/
private static void writeLogToFile(String path, String type, String tag, String text) {// 新建或打开日志文件
try {
String needWriteFile = new SimpleDateFormat("yyyy_MM_dd").format(new Date());
File file = getFile(path, needWriteFile);
FileWriter filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据不进行覆盖
BufferedWriter bufWriter = new BufferedWriter(filerWriter);
String needWriteMessage = new String(text.getBytes(), "utf-8") + "\"\n" + "\n";
bufWriter.write(needWriteMessage);
bufWriter.newLine();
bufWriter.close();
filerWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 删除多余的日志文件,只保留SDCARD_LOG_FILE_SAVE_NUM个
*/
public static void delFile(String path) {// 删除日志文件
List<File> files = getFileSort(path);
if (files != null) {
for (int i = 0; i < files.size(); i++) {
if (i >= SDCARD_LOG_FILE_SAVE_NUM && files.get(i).exists()) {
files.get(i).delete();
}
}
}
}
public static File getFile(String savepath, String time) {
File savePath = new File(savepath);
if (!savePath.exists()) {
savePath.mkdirs();
}
File file = new File(savePath, LOG_FILE_FIRST_NAME + time
+ LOG_FILE_END_NAME);
return file;
}
public static File getFileOP(String savepath, String time) {
File savePath = new File(savepath);
if (!savePath.exists()) {
savePath.mkdirs();
}
File file = new File(savePath, time
+ LOG_FILE_END_NAME);
return file;
}
/**
* 获取目录下所有文件
*
* @param realpath
* @param files
* @return
*/
public static List<File> getFiles(String realpath, List<File> files) {
File realFile = new File(realpath);
if (realFile.isDirectory()) {
File[] subfiles = realFile.listFiles();
if (subfiles != null) {
for (File file : subfiles) {
if (file.isDirectory()) {
getFiles(file.getAbsolutePath(), files);
} else {
files.add(file);
}
}
}
}
return files;
}
public static List<File> getOperateLogFiles() {
return getFileSort(getSavePathOP());
}
/**
* 获取目录下所有文件(按时间倒序排序)
*
* @return
*/
public static List<File> getFileSort(String savePath) {
File save = new File(savePath);
if (!save.exists()) {
return null;
}
List<File> list = getFiles(savePath, new ArrayList<File>());
if (list != null && list.size() > 0) {
Collections.sort(list, new Comparator<File>() {
@Override
public int compare(File file, File newFile) {
if (file.lastModified() > newFile.lastModified()) {
return -1;
} else if (file.lastModified() == newFile.lastModified()) {
return 0;
} else {
return 1;
}
}
});
}
return list;
}
public static String getSavePath() {
return Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "htjc" + File.separator + "sensor" + File.separator + "applog/";
}
public static String getSavePathOP() {
return Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "htjc" + File.separator + "sensor" + File.separator + "operatelog/";
}
public static class StorageList {
private Context mContext;
private StorageManager mStorageManager;
private Method mMethodGetPaths;
public StorageList(Context context) {
mContext = context;
if (mContext != null) {
mStorageManager = (StorageManager) mContext
.getSystemService(Activity.STORAGE_SERVICE);
try {
mMethodGetPaths = mStorageManager.getClass()
.getMethod("getVolumePaths");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
public String[] getVolumePaths() {
String[] paths = null;
try {
paths = (String[]) mMethodGetPaths.invoke(mStorageManager);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return paths;
}
}
}

+ 159
- 0
app/src/main/java/com/handset/serialportsensor/utils/SpUtil.java View File

@ -0,0 +1,159 @@
package com.handset.serialportsensor.utils;
import android.content.Context;
import android.content.SharedPreferences;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
/**
* Created by yxm on 16-6-23.
*/
public class SpUtil {
/**
* 保存在手机里面的文件名
*/
public static final String FILE_NAME = "share_data";
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*/
public static void put(Context context, String key, Object object) {
put(context, FILE_NAME, key, object);
}
public static void put(Context context, String spName, String key, Object object) {
SharedPreferences sp = context.getSharedPreferences(spName,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
editor.putInt(key, (Integer) object);
} else if (object instanceof Boolean) {
editor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float) {
editor.putFloat(key, (Float) object);
} else if (object instanceof Long) {
editor.putLong(key, (Long) object);
} else {
editor.putString(key, object.toString());
}
SharedPreferencesCompat.apply(editor);
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*/
public static Object get(Context context, String key, Object defaultObject) {
return get(context, FILE_NAME, key, defaultObject);
}
public static Object get(Context context, String spName, String key, Object defaultObject) {
SharedPreferences sp = context.getSharedPreferences(spName,
Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sp.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
return sp.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float) {
return sp.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
/**
* 移除某个key值已经对应的值
*/
public static void remove(Context context, String key) {
remove(context, FILE_NAME, key);
}
public static void remove(Context context, String spName, String key) {
SharedPreferences sp = context.getSharedPreferences(spName,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}
/**
* 清除所有数据
*/
public static void clear(Context context) {
clear(context, FILE_NAME);
}
public static void clear(Context context, String spName) {
SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}
/**
* 查询某个key是否已经存在
*/
public static boolean contains(Context context, String key) {
return contains(context, FILE_NAME, key);
}
public static boolean contains(Context context, String spName, String key) {
SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
return sp.contains(key);
}
/**
* 返回所有的键值对
*/
public static Map getAll(Context context) {
return getAll(context, FILE_NAME);
}
public static Map getAll(Context context, String spName) {
SharedPreferences sp = context.getSharedPreferences(spName,
Context.MODE_PRIVATE);
return sp.getAll();
}
/**
* 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
*/
private static class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();
/**
* 反射查找apply的方法
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private static Method findApplyMethod() {
try {
Class clz = SharedPreferences.Editor.class;
return clz.getMethod("apply");
} catch (NoSuchMethodException e) {
}
return null;
}
/**
* 如果找到则使用apply执行,否则使用commit
*/
public static void apply(SharedPreferences.Editor editor) {
try {
if (sApplyMethod != null) {
sApplyMethod.invoke(editor);
return;
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
editor.commit();
}
}
}

+ 30
- 0
app/src/main/java/com/handset/serialportsensor/utils/SplitUtils.java View File

@ -0,0 +1,30 @@
package com.handset.serialportsensor.utils;
import android.util.Log;
import com.google.common.base.Splitter;
import com.handset.serialportlib.ByteUtils;
import java.util.Collections;
public class SplitUtils {
private static final String logTag = "HANDSET-JE002-EX";
public static Iterable<String> split(String raw) {
try {
if (raw.length() == 22) {
return Splitter.fixedLength(22).split(raw);
} else if (raw.length() == 28) {
return Splitter.fixedLength(28).split(raw);
} else if(raw.length() > 28){
byte[] bytes = ByteUtils.hexStrToBytes(raw);
int len = bytes[8] & 0xff;
int resLen = 18 + len * 2 + 4;
Log.i(logTag, "split len: " + len + ", resLen: " + resLen);
return Splitter.fixedLength(resLen).split(raw);
} else return Collections.emptyList();
} catch (Exception e) {
return Collections.emptyList();
}
}
}

+ 36
- 0
app/src/main/java/com/handset/serialportsensor/utils/StatusBarUtils.java View File

@ -0,0 +1,36 @@
package com.handset.serialportsensor.utils;
import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.ColorRes;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class StatusBarUtils {
public static void setStatusColor(Activity activity, boolean isTranslate, boolean isDarkText, @ColorRes int bgColor) {
//如果系统为6.0及以上就可以使用Android自带的方式
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Window window = activity.getWindow();
View decorView = window.getDecorView();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); //可有可无
decorView.setSystemUiVisibility((isTranslate ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : 0) | (isDarkText ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0));
window.setStatusBarColor(isTranslate ? Color.TRANSPARENT : ContextCompat.getColor(activity, bgColor)); //Android5.0就可以用
}
}
public static void setTranslucentStatus(Activity activity) {
// 5.0以上系统状态栏透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
}

+ 169
- 0
app/src/main/java/com/handset/serialportsensor/utils/ToastHelper.java View File

@ -0,0 +1,169 @@
package com.handset.serialportsensor.utils;
import android.app.AlertDialog;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.activity.BaseActivity;
public class ToastHelper {
public interface OnDialogClickListener {
void onOKClickListener(View view);
void onCancelClickListener(View view);
}
public interface OnDialogSubmitClickListener {
void onOKClickListener(View view);
}
public static AlertDialog showSubmitDialog(final String title, int icon, String content, int btnBgColor, String ok, BaseActivity context, final OnDialogSubmitClickListener listener) {
AlertDialog dialog = showSubmitDialogNoShow(title, icon, content, btnBgColor, ok, context, listener);
context.showDialog(dialog);
return dialog;
}
private static AlertDialog showSubmitDialogNoShow(final String title, int icon, String content, int btnBgColor, String ok, BaseActivity context, final OnDialogSubmitClickListener listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View view = View.inflate(context, R.layout.dialog_btl_recognition_error, (null));
final AlertDialog dialog = builder.create();
dialog.setView(view);
TextView tvTitle = view.findViewById(R.id.tv_title);
tvTitle.setText(title);
ImageView ivImg = view.findViewById(R.id.iv_img);
ivImg.setImageResource(icon);
TextView tvContent = view.findViewById(R.id.tv_content);
tvContent.setText(content);
Button btnConfirm = view.findViewById(R.id.btn_confirm);
btnConfirm.setBackgroundColor(btnBgColor);
if (!TextUtils.isEmpty(ok)) {
btnConfirm.setText(ok);
}
btnConfirm.setOnClickListener((View view2) -> {
dialog.dismiss();
listener.onOKClickListener(view2);
});
return dialog;
}
public static AlertDialog showChooseDialogNoShow(final String title, int icon, String content, int btnBgColor, String confirm, String cancel, BaseActivity context, final OnDialogClickListener listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View view = View.inflate(context, R.layout.dialog_stop_test, (null));
final AlertDialog dialog = builder.create();
dialog.setView(view);
TextView tvTitle = view.findViewById(R.id.tv_title);
tvTitle.setText(title);
ImageView ivImg = view.findViewById(R.id.iv_img);
ivImg.setImageResource(icon);
TextView tvContent = view.findViewById(R.id.tv_content);
tvContent.setText(content);
Button btnConfirm = view.findViewById(R.id.btn_confirm);
btnConfirm.setBackgroundColor(btnBgColor);
if (!TextUtils.isEmpty(confirm)) {
btnConfirm.setText(confirm);
}
btnConfirm.setOnClickListener((View view2) -> {
dialog.dismiss();
listener.onOKClickListener(view2);
});
Button btnCancel = view.findViewById(R.id.btn_cancel);
if (!TextUtils.isEmpty(cancel)) {
btnCancel.setText(cancel);
}
btnCancel.setOnClickListener((View view3) -> {
dialog.dismiss();
listener.onCancelClickListener(view3);
});
return dialog;
}
public static AlertDialog showTipDialog(BaseActivity context, int imgRes, int tips) {
return showTipDialog(context, imgRes, tips, (false));
}
public static AlertDialog showTipDialogAnimation(BaseActivity context, int imgRes, int tips) {
return showTipDialog(context, imgRes, tips, (true));
}
public static AlertDialog showTipDialogNoShow(BaseActivity context, int imgRes, int tips) {
return showTipDialogNoShow(context, imgRes, tips, (false));
}
private static AlertDialog showTipDialog(BaseActivity context, int imgRes, int tips, boolean showAnimation) {
AlertDialog dialog = showTipDialogNoShow(context, imgRes, tips, showAnimation);
context.showDialog(dialog);
return dialog;
}
private static AlertDialog showTipDialogNoShow(BaseActivity context, int imgRes, int tips, boolean showAnimation) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View view = View.inflate(context, R.layout.dialog_tips_layout, (null));
final AlertDialog dialog = builder.create();
if (dialog.getWindow() != null) {
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
}
dialog.setView(view);
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(false);
ImageView ivImg = view.findViewById(R.id.iv_loading);
if (imgRes != 0) {
ivImg.setVisibility(View.VISIBLE);
ivImg.setImageResource(imgRes);
} else {
ivImg.setVisibility(View.GONE);
}
if (showAnimation) {
Animation animation = AnimationUtils.loadAnimation(context, R.anim.rotate_anim);
animation.setInterpolator(new LinearInterpolator());
ivImg.startAnimation(animation);
}
TextView tvTip = view.findViewById(R.id.tv_loading);
tvTip.setText(tips);
return dialog;
}
public static void showResetSensorDialog(BaseActivity context, final OnDialogClickListener listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View view = View.inflate(context, R.layout.dialog_chuchang, (null));
final AlertDialog dialog = builder.create();
dialog.setView(view);
Button btnCancel = view.findViewById(R.id.btn_cancel);
Button btnConfirm = view.findViewById(R.id.btn_confirm);
btnCancel.setOnClickListener((View view2) -> {
dialog.dismiss();
listener.onCancelClickListener(view2);
});
btnConfirm.setOnClickListener((View view3) -> {
dialog.dismiss();
listener.onOKClickListener(view3);
});
context.showDialog(dialog);
}
public static void showSaveSensorDialog(BaseActivity context, final OnDialogClickListener listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View view = View.inflate(context, R.layout.dialog_save_alert, (null));
final AlertDialog dialog = builder.create();
dialog.setCancelable(false);
dialog.setView(view);
Button btnCancel = view.findViewById(R.id.btn_cancel);
Button btnConfirm = view.findViewById(R.id.btn_confirm);
btnCancel.setOnClickListener((View view2) -> {
dialog.dismiss();
listener.onCancelClickListener(view2);
});
btnConfirm.setOnClickListener((View view3) -> {
dialog.dismiss();
listener.onOKClickListener(view3);
});
context.showDialog(dialog);
}
}

+ 203
- 0
app/src/main/java/com/handset/serialportsensor/utils/Utils.java View File

@ -0,0 +1,203 @@
package com.handset.serialportsensor.utils;
import android.content.Context;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigInteger;
public class Utils {
private static final String path = "/sys/class/peijian_dev/function/PeijianPowerEn";
private static final String path1 = "/sys/class/peijian_dev/function/pogo_wake";
private final static String TAG = "Util";
public static void initBLNStatus(char status) {
setBLNStatus(status, path);
setBLNStatus(status, path1);
}
private static void setBLNStatus(char status, String path) {
File file = new File(path);
FileOutputStream fos;
try {
if (!file.exists()) {
return;
}
fos = new FileOutputStream(file);
fos.write(status);
fos.close();
} catch (Exception e) {
Log.e("setBLNStatus", "setBLNStatus error: ", e);
}
}
//低位在前高位在后
public static byte[] intToByte(int num) {
byte[] bytes = new byte[4];
bytes[0] = (byte) ((num >> 24) & 0xff);
bytes[1] = (byte) ((num >> 16) & 0xff);
bytes[2] = (byte) ((num >> 8) & 0xff);
bytes[3] = (byte) (num & 0xff);
return bytes;
}
public static byte[] addBytes(byte[] data1, byte[] data2) {
byte[] data = new byte[data1.length + data2.length];
System.arraycopy(data1, 0, data, 0, data1.length);
System.arraycopy(data2, 0, data, data1.length, data2.length);
return data;
}
public static byte[] addCheckBytes(byte[] byteCommand, int data) {
byte[] bytes2 = Utils.intToByte(data);//data
byte[] bytes3 = Utils.addBytes(byteCommand, bytes2);
int crc1021Egg = CRC16Utils.getCRC1021(bytes3);
byte[] bytes4 = Utils.intToByte(crc1021Egg);
return Utils.addBytes(bytes3, bytes4);
}
//根据ID获取厂家编号和厂家内部ID
public static int[] getNumber(int id) {
//id 厂家ID (number)*0x3000+(interId)
int b = 0x3000;
int low = 0x0041;
int high = 0x2fff;
int interId = id % b;//厂家内部ID(0x0041-0x2fff) 0x6042
int number = id / b;//厂家编号(0-4)
if (interId >= low && interId <= high) {
if (number >= 0 && number <= 4) {
return new int[]{number, interId};
}
}
return null;
}
//低位在前高位在后
public static byte[] convertStringToHex(String str) {
char[] ch = str.toCharArray();
byte[] hex = new byte[ch.length];
for (int i = 0; i < ch.length; i++) {
hex[i] = (byte) ch[i];
}
return hex;
}
public static byte[] convertStringToHexDesc(String str) {
char[] ch = str.toCharArray();
byte[] hex = new byte[ch.length];
for (int i = 0; i < ch.length; i++) {
hex[i] = (byte) ch[ch.length - i - 1];
}
return hex;
}
public static String convertHexToString(String hex) {
StringBuilder sb = new StringBuilder();
StringBuilder temp = new StringBuilder();
for (int i = 0; i < hex.length() - 1; i += 2) {
//grab the hex in pairs
String output = hex.substring(i, (i + 2));
//convert hex to decimal
int decimal = Integer.parseInt(output, 16);
//convert the decimal to character
sb.append((char) decimal);
temp.append(decimal);
}
return sb.toString();
}
public static int dp2px(Context context, float dpValue) {
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
public static byte[] getCrcByte(byte[] command, String data) {
byte[] hex = Utils.convertStringToHex(data);
byte[] bytes2 = Utils.addBytes(command, hex);
int crc1021 = CRC16Utils.getCRC1021(bytes2);
byte low = (byte) (crc1021 & 0xff);
byte high = (byte) ((crc1021 >> 8) & 0xff);
byte[] getBaudBuffer = new byte[bytes2.length + 4];
getBaudBuffer[0] = (byte) 0xDD;
getBaudBuffer[1] = (byte) 0xDD;
for (int i = 0; i < bytes2.length; i++) {
getBaudBuffer[i + 2] = bytes2[i];
}
getBaudBuffer[getBaudBuffer.length - 2] = low;
getBaudBuffer[getBaudBuffer.length - 1] = high;
return getBaudBuffer;
}
public static byte[] getCrcByte(byte[] command) {
int crc1021 = CRC16Utils.getCRC1021(command);
byte low = (byte) (crc1021 & 0xff);
byte high = (byte) ((crc1021 >> 8) & 0xff);
byte[] getBaudBuffer = new byte[command.length + 4];
getBaudBuffer[0] = (byte) 0xDD;
getBaudBuffer[1] = (byte) 0xDD;
for (int i = 0; i < command.length; i++) {
getBaudBuffer[i + 2] = command[i];
}
getBaudBuffer[getBaudBuffer.length - 2] = low;
getBaudBuffer[getBaudBuffer.length - 1] = high;
return getBaudBuffer;
}
public static String byteArrayToString(byte[] b) {
StringBuilder hexBuilder = new StringBuilder();
for (byte aB : b) {
String hexString = Integer.toHexString(aB & 0xFF);
if (hexString.length() < 2) {
hexBuilder.append(0);
}
hexBuilder.append(hexString);
}
BigInteger bigInteger = new BigInteger(hexBuilder.toString(), 16);
String s = bigInteger.toString(10);
return s;
}
public final static int getInt(byte[] buf, boolean asc, int len) {
if (buf == null) {
throw new IllegalArgumentException("byte array is null!");
}
if (len > 4) {
throw new IllegalArgumentException("byte array size > 4 !");
}
int r = 0;
if (asc)
for (int i = len - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
else
for (int i = 0; i < len; i++) {
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
return r;
}
public final static int byteArray2Int(byte[] buf) {
return getInt(buf, false, 2);
}
public static String getSensorNoShow(String raw) {
if(raw.length() < 8) {
return raw;
}
StringBuilder sb = new StringBuilder(raw);
sb.deleteCharAt(4);
return sb.toString();
}
}

+ 169
- 0
app/src/main/java/com/handset/serialportsensor/view/AutoLoadMoreListView.java View File

@ -0,0 +1,169 @@
package com.handset.serialportsensor.view;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.handset.serialportsensor.R;
/**
* 目前很多App的ListView都有在分页显示时自动加载更多内容的功能
* 1 每次只显示一页内容
* 2 用户滚动到底部的时候则会出现一行正在加载的提示并开始加载
* 3 如果全部内容都加载完成了则滚动到底部不会出现提示
* <p>
* AutoLoadMoreListView在标准ListView的基础上进行了简单的封装来实现这个功能
* 1 正在加载的提示是一个footer默认实现是文字加旋转动画
* 2 可以指定footer的高度背景颜色文字等属性也可以替换为自定义的layout
* 3 footer是否显示由调用者决定
* 4 当滚动到底部的时候通过回调通知应用执行加载加载完成后要告知加载完成
*/
public class AutoLoadMoreListView extends ListView implements AbsListView.OnScrollListener {
private View mLoadStatus;
private View mLoadMoreView;
//控制moreView的显示是否显示是由调用者来决定的
private boolean mShowLoadMore;
private AutoLoadMoreListener mLoadMoreListener;
//是否正在执行加载更多的动作防止重复调用
private boolean mDoingLoadMore;
public AutoLoadMoreListView(Context context) {
super(context);
init(null, 0);
}
public AutoLoadMoreListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public AutoLoadMoreListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
mLoadMoreView = LayoutInflater.from(getContext()).inflate(R.layout.simple_auto_load_more, null);
mLoadStatus = LayoutInflater.from(getContext()).inflate(R.layout.simple_auto_load_more, null);
setOnScrollListener(this);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//检查是否要通知App去做加载更多
if (mShowLoadMore && (!mDoingLoadMore)
&& mLoadMoreListener != null
&& (firstVisibleItem + visibleItemCount) >= totalItemCount) {
mDoingLoadMore = true;
mLoadMoreListener.onLoadMoreBegin(this);
}
}
/**
* 设置是否显示加载更多footer
*
* @param show
*/
public void setShowLoadMore(boolean show) {
if (show == mShowLoadMore) {
return;
}
updateFoot("");
mShowLoadMore = show;
if (mShowLoadMore) {
this.addFooterView(mLoadMoreView);
} else {
this.removeFooterView(mLoadMoreView);
}
}
public void setLoadMoreListener(AutoLoadMoreListener listener) {
mLoadMoreListener = listener;
}
/**
* App设置是否加载更多动作已经完成
* 只有本次加载完成了当滚动到底部的时候才能再次发起加载
*/
public void loadMoreComplete() {
mDoingLoadMore = false;
updateFoot("数据已经全部加载");
}
/**
* 设置默认的加载更多footer的属性
*
* @param height 高度 px
* @param bgColor 背景颜色
* @param textSize 文字大小 sp
* @param textColor 文字颜色
*/
public void setupDefaultLoadMoreView(int height, int bgColor, int textSize, int textColor) {
mLoadMoreView.setBackgroundColor(bgColor);
View v = mLoadMoreView.findViewById(R.id.auto_load_more_container);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) v
.getLayoutParams();
lp.height = height;
v.setLayoutParams(lp);
TextView textView = mLoadMoreView.findViewById(R.id.auto_load_more_text);
textView.setTextSize(textSize);
textView.setTextColor(textColor);
}
boolean showFootStatus = false;
public void updateFoot(String s) {
if (TextUtils.isEmpty(s)) {
if (showFootStatus) {
this.removeFooterView(mLoadStatus);
}
showFootStatus = false;
} else {
if (!showFootStatus) {
this.addFooterView(mLoadStatus);
}
TextView textView = mLoadStatus.findViewById(R.id.auto_load_more_text);
textView.setText(s);
showFootStatus = true;
}
}
/**
* 设置自定义的加载更多footer
*
* @param view
*/
public void setCustomLoadMoreView(View view) {
mLoadMoreView = view;
}
/**
* 在android4.2.2的机器上遇到一个问题调用addFooterView的时候报
* ListDataBindingAdapter cannot be cast to android.widget.HeaderViewListAdapter
* 在网上查找后得知在Api18以下的机器Wrapping做得不太好可以用如下方法来规避
*
* @param adapter 适配器
*/
@Override
public void setAdapter(ListAdapter adapter) {
this.addFooterView(mLoadMoreView);
super.setAdapter(adapter);
this.removeFooterView(mLoadMoreView);
}
}

+ 9
- 0
app/src/main/java/com/handset/serialportsensor/view/AutoLoadMoreListener.java View File

@ -0,0 +1,9 @@
package com.handset.serialportsensor.view;
/**
* Created by LiGang on 2016/4/30.
*/
public interface AutoLoadMoreListener {
//通知App Listview已经滚动到底部开始加载下一页数据
void onLoadMoreBegin(final AutoLoadMoreListView listView);
}

+ 61
- 0
app/src/main/java/com/handset/serialportsensor/view/ExportProgressDialog.java View File

@ -0,0 +1,61 @@
package com.handset.serialportsensor.view;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.activity.BaseActivity;
import com.handset.serialportsensor.utils.ToastHelper;
/**
* Created by zy on 2019/3/7.
*/
public class ExportProgressDialog {
private TextView tvContent;
private Button mButton;
public AlertDialog mAlertDialog;
private String ss;
public AlertDialog showExportDialogNoShow(BaseActivity context, final ToastHelper.OnDialogSubmitClickListener listener, int count, int remain, String ss, String title) {
this.ss = ss;
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View view = View.inflate(context, R.layout.dialog_exporting_test_data, (null));
mAlertDialog = builder.create();
mAlertDialog.setView(view);
mAlertDialog.setCancelable(false);
tvContent = view.findViewById(R.id.content);
String text = (count == 0 && remain == 0) ? (ss + "······") : (ss + "(" + (count - remain) + "/" + count + ")······");
tvContent.setText(text);
((TextView) (view.findViewById(R.id.title))).setText(title);
mButton = view.findViewById(R.id.btn_confirm);
mButton.setOnClickListener((View view2) -> {
mAlertDialog.dismiss();
listener.onOKClickListener(view2);
});
return mAlertDialog;
}
public boolean update(Activity activity, final int count, final int remain) {
if (mAlertDialog == null) {
return false;
}
activity.runOnUiThread(() -> {
if (tvContent != null) {
String text = ss + "(" + (count - remain) + "/" + count + ")······";
tvContent.setText(text);
}
if (mButton != null) {
mButton.setText(remain == 0 ? R.string.finished : R.string.cancel);
}
});
return true;
}
}

+ 26
- 0
app/src/main/java/com/handset/serialportsensor/view/LinearLayoutManagerCus.java View File

@ -0,0 +1,26 @@
package com.handset.serialportsensor.view;
import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
/**
* Created by zy on 2019/2/27.
*/
public class LinearLayoutManagerCus extends LinearLayoutManager {
public LinearLayoutManagerCus(Context context) {
super(context);
}
@Override
public RecyclerView.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
return super.generateLayoutParams(lp);
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams((-1), (-2));
}
}

+ 379
- 0
app/src/main/java/com/handset/serialportsensor/widget/DashBoard.java View File

@ -0,0 +1,379 @@
package com.handset.serialportsensor.widget;
import android.animation.ArgbEvaluator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.utils.PixelUtils;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import static android.graphics.Paint.Style.STROKE;
//@SuppressWarnings(value = "unused")
public class DashBoard extends View {
private static final String logTag = "HANDSET-JE002-EX";
private Paint paint;
//最外层圆环的颜色
private int circleColor;
//圆环进度的颜色
private int progressCircleColor;
//圆环的厚度即大小
private float circleThickness;
//最上面字体的颜色
//private int topTextColor;
//第二行字体的颜色
private int secondTextColor;
//第三行字体的颜色
private int thirdTextColor;
//RoundProgress开始的颜色决定RoundProgress的渐变区间
private int progressStartColor;
//RoundProgress结束的颜色决定RoundProgress的渐变区间
private int ProgressEndColor;
//进度的最大值默认是1000
private double maxProgress;
//当前的进度默认0
private double currentProgress;
//第二行字
private String secondText;
//第三行字
private String thirdText = "kg";
//最上面的字的大小
//private float topTextSize;
//第二行字的大小
private float secondTextSize;
//第三行字的大小
private float thirdTextSize;
//最外层圆的半径
private int outerFirstCircleRadius;
//文字颜色是否argb变化
private boolean progressArgbColor;
//小圆是否可用
private boolean smallCircleEnable;
private boolean customArc;
private int startArc;
private int center;
private Float valueFloor;
private Float valueCeiling;
private int textPaintStroke;
private ArgbEvaluator mArgbEvaluator;
private boolean showOutText;
protected Paint textStartPaint = new TextPaint();
protected Paint textEndPaint = new TextPaint();
protected RectF ringRect = new RectF();
private float textStartSize;
private float textEndSize;
public String textStart;
public String textEnd;
private int textStartColor;
private int textEndColor;
private Context context;
private int circlePadding;
public DashBoard(Context context) {
this(context, (null));
this.context = context;
}
public DashBoard(Context context, AttributeSet attrs) {
this(context, attrs, (0));
this.context = context;
}
public DashBoard(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
paint = new Paint();
mArgbEvaluator = new ArgbEvaluator();
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DashBoard);
//获取自定义属性和默认值
circleColor = typedArray.getColor(R.styleable.DashBoard_circleColor, context.getResources().getColor(R.color.dashboard_gray));
progressCircleColor = typedArray.getColor(R.styleable.DashBoard_progressCircleColor, context.getResources().getColor(R.color.dashboard_normal_end));
progressStartColor = typedArray.getColor(R.styleable.DashBoard_progressStartColor, getResources().getColor(R.color.dashboard_normal_start));
ProgressEndColor = typedArray.getColor(R.styleable.DashBoard_progressEndColor, getResources().getColor(R.color.dashboard_normal_end));
circleThickness = typedArray.getDimension(R.styleable.DashBoard_circleThickness, PixelUtils.dp2px(context, 10));
secondTextColor = typedArray.getColor(R.styleable.DashBoard_secondTextColor, Color.BLACK);
thirdTextColor = typedArray.getColor(R.styleable.DashBoard_thirdTextColor, Color.BLACK);
secondText = typedArray.getString(R.styleable.DashBoard_secondText);
maxProgress = typedArray.getInt(R.styleable.DashBoard_maxProgress, 100);
currentProgress = typedArray.getInt(R.styleable.DashBoard_currentProgress, 0);
customArc = typedArray.getBoolean(R.styleable.DashBoard_customArc, false);
startArc = typedArray.getInt(R.styleable.DashBoard_startArc, 0);
showOutText = typedArray.getBoolean(R.styleable.DashBoard_showOutText, false);
textStartSize = typedArray.getDimension(R.styleable.DashBoard_textStartSize, PixelUtils.sp2px(context, 10));
textEndSize = typedArray.getDimension(R.styleable.DashBoard_textEndSize, PixelUtils.sp2px(context, 10));
textStartColor = typedArray.getColor(R.styleable.DashBoard_textStartColor, context.getResources().getColor(R.color.dashboard_normal_end));
textEndColor = typedArray.getColor(R.styleable.DashBoard_textEndColor, context.getResources().getColor(R.color.dashboard_normal_end));
textStart = typedArray.getString(R.styleable.DashBoard_textStart);
textEnd = typedArray.getString(R.styleable.DashBoard_textEnd);
valueFloor = typedArray.getFloat(R.styleable.DashBoard_valueFloor, (0.0f));
valueCeiling = typedArray.getFloat(R.styleable.DashBoard_valueCeiling, (0.0f));
//设置第三行文字的默认文字
String defaultThirdText = typedArray.getString(R.styleable.DashBoard_thirdText);
if (defaultThirdText != null) {
thirdText = defaultThirdText;
}
secondTextSize = typedArray.getDimension(R.styleable.DashBoard_secondTextSize, PixelUtils.sp2px(context, 45));
thirdTextSize = typedArray.getDimension(R.styleable.DashBoard_thirdTextSize, PixelUtils.sp2px(context, 16));
//控制颜色渐变的开关
progressArgbColor = typedArray.getBoolean(R.styleable.DashBoard_progressArgbColor, false);
smallCircleEnable = typedArray.getBoolean(R.styleable.DashBoard_smallCircleEnable, true);
typedArray.recycle();
circlePadding = PixelUtils.dp2px(context, 18);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
//第1步画出最外层的圆环
drawOuterFirstCircle(canvas);
//第2步画出圆弧
drawArc(canvas);
//第3步画出三行文字
drawText(canvas);
if (showOutText) {
textStartPaint.setColor(textStartColor);
textStartPaint.setTextSize(textStartSize);
textStartPaint.setAntiAlias(true);
textEndPaint.setColor(textEndColor);
textEndPaint.setTextSize(textEndSize);
textEndPaint.setAntiAlias(true);
}
float delta = circleThickness;
int padding = PixelUtils.dp2px(getContext(), 10);
ringRect.set(delta + padding,
delta + padding,
width - delta - padding,
height - delta - padding);
float ringWidth = ringRect.right - ringRect.left;
//第5步画出外面的文字
if (showOutText && !TextUtils.isEmpty(textStart) && !TextUtils.isEmpty(textEnd)) {
int endArc = startArc + (int) currentProgress;
int startPadding = (int) textStartPaint.measureText(textEnd) / 2 + PixelUtils.dp2px(getContext(), 6);
if (startArc <= 0 || startArc >= 180) {
startPadding = 0;
}
int endPadding = (int) textEndPaint.measureText(textStart) / 3 + PixelUtils.dp2px(getContext(), 2);
if (endArc > 180) {
endPadding = 0 - endPadding;
}
canvas.drawText(textStart, ringWidth / 2.0f + (ringWidth - circlePadding) / 2 * sin(endArc) + endPadding, ringRect.top + ringWidth / 2 - ringWidth / 2 * cos(endArc), textStartPaint);
canvas.drawText(textEnd, ringWidth / 2.0f + (ringWidth - circlePadding) / 2 * sin(startArc) + startPadding, ringRect.top + ringWidth / 2 - ringWidth / 2 * cos(startArc), textEndPaint);
}
}
/**
* 绘制最外层的圆
*
* @param canvas 画笔
*/
private void drawOuterFirstCircle(Canvas canvas) {
//设置圆的颜色
paint.setColor(circleColor);
//设置只绘制边框
paint.setStyle(STROKE);
//设置圆的宽度
paint.setStrokeWidth(circleThickness / 2);
//消除锯齿
paint.setAntiAlias(true);
//画出圆
canvas.drawCircle(center, center, outerFirstCircleRadius, paint);
}
private void drawText(Canvas canvas) {
paint.setStrokeWidth(textPaintStroke);
paint.setStyle(Paint.Style.FILL);
//画出第二行文本
paint.setTextSize(secondTextSize);
paint.setColor(secondTextColor);
float textWidth2 = paint.measureText(secondText);
canvas.drawText(secondText, center - textWidth2 / 2, center - secondTextSize / 4, paint); //画出卡路里数值
//画出第三行文本
paint.setTextSize(thirdTextSize);
paint.setColor(thirdTextColor);
if (thirdText != null) {
float textWidth3 = paint.measureText(thirdText);
canvas.drawText(thirdText, center - textWidth3 / 2, center + (float) outerFirstCircleRadius / 4 + thirdTextSize / 2, paint); //画出卡路里单位
}
}
private void drawArc(Canvas canvas) {
paint.setStrokeWidth(circleColor);
paint.setStyle(STROKE);
if (smallCircleEnable) {
paint.setStrokeCap(Paint.Cap.BUTT);
} else {
paint.setStrokeCap(Paint.Cap.ROUND);
}
paint.setAntiAlias(true);
//设置圆弧宽度
paint.setStrokeWidth(circleThickness + 1);
RectF oval2 = new RectF(center - outerFirstCircleRadius, center - outerFirstCircleRadius, center + outerFirstCircleRadius, center + outerFirstCircleRadius); //用于定义的圆弧的形状和大小的界限
double progress;
//这里画圆环的时候第二个参数为开始角度0表示右边中线90表示底部-outerFirstCircleRadius
if (currentProgress < maxProgress) {
progress = currentProgress;
drawArcByColor(canvas, oval2, progress);
} else {
progress = maxProgress;
drawArcByColor(canvas, oval2, progress);
}
}
private void drawArcByColor(Canvas canvas, RectF oval2, double progress) {
for (int i = 0; i < progress / maxProgress * 360; i++) {
if (progressArgbColor) {//如果颜色渐变 则改变色值
progressCircleColor = (Integer) mArgbEvaluator.evaluate(i / 360f, progressStartColor, ProgressEndColor);//颜色插值器level 11以上才可以用
secondTextColor = ProgressEndColor;
}
paint.setAntiAlias(true);
paint.setColor(progressCircleColor);
if (customArc) {
if (i < maxProgress * 360) {
canvas.drawArc(oval2, (float) (-90 + i + startArc), 1.35f, false, paint);
}
} else {
if (i < maxProgress * 360) {
canvas.drawArc(oval2, (float) (-90 + i), 1.35f, false, paint);
}
}
}
}
/**
* 当控件的宽高发生变化的时候调用的方法
* 在这里得到控件的宽高,避免在onDraw的时候多次初始化
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//获取圆心的坐标对于自身控件而言是1/2
center = getMeasuredWidth() / 2;
//原本是半径是等于中心点但是由于设置画笔宽度的时候这个宽度会根据当前的半径往外部和内部各扩展1/2
//所以在设置半径是需要减去圆环宽度的一半
//这里减去整个圆环厚度是因为想让圆环距离本控件有左右间距故意为之
outerFirstCircleRadius = (int) (center - circleThickness - PixelUtils.dp2px(context, 18));
//文字不用太大
textPaintStroke = 1;
}
public float sin(int i) {
return (float) Math.sin(i * Math.PI / 180);
}
public float cos(int i) {
return (float) Math.cos(i * Math.PI / 180);
}
public void setTextStart(String textStart) {
this.textStart = textStart;
this.invalidate();
}
public void setTextEnd(String textEnd) {
this.textEnd = textEnd;
this.invalidate();
}
private final static String FLOAT_TYPE = "0.00";
public void setSecondText(Float value) {
BigDecimal tmp = new BigDecimal(value);
BigDecimal floor = new BigDecimal(valueFloor);
BigDecimal ceiling = new BigDecimal(valueCeiling);
if (!(tmp.compareTo(floor) < 0 || tmp.compareTo(ceiling) > 0)) {
this.secondText = new DecimalFormat(FLOAT_TYPE).format(value);
invalidate();
return;
}
Log.w(logTag, ("item: " + thirdText + ", value: " + value + " exceed!"));
}
public void setSecondText(Float value, boolean isNormal) {
Log.i(logTag, "value: " + value);
BigDecimal tmp = new BigDecimal(value);
BigDecimal floor = new BigDecimal(valueFloor);
BigDecimal ceiling = new BigDecimal(valueCeiling);
if (!(tmp.compareTo(floor) < 0 || tmp.compareTo(ceiling) > 0)) {
this.secondText = new DecimalFormat(FLOAT_TYPE).format(value);
setProgressStartColor(getResources().getColor(isNormal ? R.color.progress_normal_start : R.color.progress_err_end));
setProgressEndColor(getResources().getColor(isNormal ? R.color.progress_normal_end : R.color.progress_err_end));
invalidate();
return;
}
Log.w(logTag, ("item: " + thirdText + ", value: " + value + " exceed!"));
}
public void setSecondText(String value) {
this.secondText = value;
setProgressStartColor(getResources().getColor(R.color.progress_normal_start));
setProgressEndColor(getResources().getColor( R.color.progress_normal_end ));
invalidate();
}
/**
* 控制RoundProgress颜色渐变
* @param progressCircleColor startColor
*/
public void setProgressStartColor(int progressCircleColor) {
this.progressStartColor = progressCircleColor;
}
/**
* 控制RoundProgress颜色渐变
* @param progressCircleColor endColor
*/
public void setProgressEndColor(int progressCircleColor) {
this.ProgressEndColor = progressCircleColor;
}
}

+ 12
- 0
app/src/main/res/anim/rotate_anim.xml View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:toDegrees="360">
</rotate>

+ 34
- 0
app/src/main/res/drawable-v24/ic_launcher_foreground.xml View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
android:width="108dp">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
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="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>

BIN
app/src/main/res/drawable-xxhdpi/ic_launcher_c.png View File

Before After
Width: 144  |  Height: 144  |  Size: 16 KiB

BIN
app/src/main/res/drawable-xxhdpi/icon.png View File

Before After
Width: 144  |  Height: 144  |  Size: 7.4 KiB

BIN
app/src/main/res/drawable-xxhdpi/loading.png View File

Before After
Width: 30  |  Height: 30  |  Size: 394 B

+ 7
- 0
app/src/main/res/drawable/background_red.xml View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ff0000"/><!-- 填充的颜色 -->
</shape>

+ 23
- 0
app/src/main/res/drawable/background_sharp.xml View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="9dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp"
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"/><!-- 设置圆角半径 -->
<!-- 间隔 -->
<!--<padding-->
<!--android:left="16dp"-->
<!--android:top="2dp"-->
<!--android:right="16dp"-->
<!--android:bottom="2dp"/>&lt;!&ndash; 各方向的间隔 &ndash;&gt;-->
<!-- 填充 -->
<solid
android:color="@android:color/white"/><!-- 填充的颜色 -->
</shape>

+ 23
- 0
app/src/main/res/drawable/background_sharp_circle.xml View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 圆角 -->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:radius="9dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp"/><!-- 设置圆角半径 -->
<!-- 间隔 -->
<!--<padding-->
<!--android:left="16dp"-->
<!--android:top="2dp"-->
<!--android:right="16dp"-->
<!--android:bottom="2dp"/>&lt;!&ndash; 各方向的间隔 &ndash;&gt;-->
<stroke
android:width="1px"
android:color="#999999"/>
<solid android:color="@color/white"/>
</shape>

+ 18
- 0
app/src/main/res/drawable/background_toast.xml View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 圆角 -->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:radius="9dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" /><!-- 设置圆角半径 -->
<size
android:width="120dp"
android:height="120dp" />
<!-- 填充 -->
<solid android:color="@android:color/white" /><!-- 填充的颜色 -->
</shape>

+ 5
- 0
app/src/main/res/drawable/bg_loading_dialog.xml View File

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

BIN
app/src/main/res/drawable/bg_my_send.9.png View File

Before After
Width: 59  |  Height: 106  |  Size: 596 B

+ 19
- 0
app/src/main/res/drawable/bg_read_btn_starting.xml View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="20dp"/><!-- 设置圆角半径 -->
<!-- 间隔 -->
<padding
android:left="2dp"
android:top="2dp"
android:right="2dp"
android:bottom="2dp"/><!-- 各方向的间隔 -->
<!-- 填充 -->
<solid
android:color="@color/status_green"/><!-- 填充的颜色 -->
</shape>

+ 23
- 0
app/src/main/res/drawable/bg_start_btn.xml View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="9dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp"
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"/><!-- 设置圆角半径 -->
<!-- 间隔 -->
<padding
android:left="2dp"
android:top="2dp"
android:right="2dp"
android:bottom="2dp"/><!-- 各方向的间隔 -->
<!-- 填充 -->
<solid
android:color="#5a9ecd"/><!-- 填充的颜色 -->
</shape>

+ 19
- 0
app/src/main/res/drawable/bg_start_btn_new.xml View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="20dp" /><!-- 设置圆角半径 -->
<!-- 间隔 -->
<padding
android:left="2dp"
android:top="2dp"
android:right="2dp"
android:bottom="2dp"/><!-- 各方向的间隔 -->
<!-- 填充 -->
<solid
android:color="@color/primaryBlue"/><!-- 填充的颜色 -->
</shape>

+ 23
- 0
app/src/main/res/drawable/bg_stop_btn.xml View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="9dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp"
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"/><!-- 设置圆角半径 -->
<!-- 间隔 -->
<padding
android:left="2dp"
android:top="2dp"
android:right="2dp"
android:bottom="2dp"/><!-- 各方向的间隔 -->
<!-- 填充 -->
<solid
android:color="#9d9d9d"/><!-- 填充的颜色 -->
</shape>

+ 19
- 0
app/src/main/res/drawable/bg_stop_btn_new.xml View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="20dp"/><!-- 设置圆角半径 -->
<!-- 间隔 -->
<padding
android:left="2dp"
android:top="2dp"
android:right="2dp"
android:bottom="2dp"/><!-- 各方向的间隔 -->
<!-- 填充 -->
<solid
android:color="@color/progress_err_end"/><!-- 填充的颜色 -->
</shape>

+ 6
- 0
app/src/main/res/drawable/checkbox_style_abnormal.xml View File

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

+ 6
- 0
app/src/main/res/drawable/checkbox_style_normal.xml View File

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

+ 23
- 0
app/src/main/res/drawable/chuanganqistate_background.xml View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 圆角 -->
<corners
android:radius="9dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp"
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"/><!-- 设置圆角半径 -->
<!-- 间隔 -->
<!--<padding-->
<!--android:left="16dp"-->
<!--android:top="2dp"-->
<!--android:right="16dp"-->
<!--android:bottom="2dp"/>&lt;!&ndash; 各方向的间隔 &ndash;&gt;-->
<!-- 填充 -->
<solid
android:color="#e3e3e3"/><!-- 填充的颜色 -->
</shape>

+ 171
- 0
app/src/main/res/drawable/ic_launcher_background.xml View File

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

BIN
app/src/main/res/drawable/ic_msg_left.9.png View File

Before After
Width: 39  |  Height: 35  |  Size: 478 B

BIN
app/src/main/res/drawable/ic_msg_right.9.png View File

Before After
Width: 39  |  Height: 35  |  Size: 483 B

+ 12
- 0
app/src/main/res/drawable/login_btn_bg.xml View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 圆角 -->
<corners
android:radius="19dp"/><!-- 设置圆角半径 -->
<stroke
android:width="1px"
android:color="@color/white"/>
</shape>

+ 9
- 0
app/src/main/res/drawable/login_btn_bg_rc.xml View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 圆角 -->
<corners
android:radius="5dp"/><!-- 设置圆角半径 -->
<solid android:color="@color/white"/>
</shape>

+ 12
- 0
app/src/main/res/drawable/login_edittext_bg.xml View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 圆角 -->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" /><!-- 设置圆角半径 -->
<solid android:color="#5a2b2b2d" /><!-- 填充的颜色 -->
</shape>

+ 12
- 0
app/src/main/res/drawable/logout_btn_bg.xml View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 圆角 -->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" /><!-- 设置圆角半径 -->
<solid android:color="@color/gray_bg" /><!-- 填充的颜色 -->
</shape>

+ 33
- 0
app/src/main/res/drawable/progressloading.xml View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2012 GitHub Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<rotate
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" >
<bitmap
android:antialias="true"
android:filter="true"
android:src="@drawable/loading" />
</rotate>
</item>
</layer-list>

+ 14
- 0
app/src/main/res/drawable/seekbar_custom.xml View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/background"
android:drawable="@mipmap/seekbar_gray"></item>
<item android:id="@+id/background_01">
<scale android:drawable="@mipmap/seekbar_gray" />
</item>
<item android:id="@+id/background_02">
<scale android:drawable="@mipmap/seekbar_gray" />
</item>
</layer-list>

+ 14
- 0
app/src/main/res/drawable/seekbar_custom_blue.xml View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/background"
android:drawable="@mipmap/seekbar_blue"></item>
<item android:id="@+id/background_01">
<scale android:drawable="@mipmap/seekbar_blue" />
</item>
<item android:id="@+id/background_02">
<scale android:drawable="@mipmap/seekbar_blue" />
</item>
</layer-list>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save