初始版本
This commit is contained in:
1
app/.gitignore
vendored
Normal file
1
app/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
||||
189
app/build.gradle
Normal file
189
app/build.gradle
Normal file
@ -0,0 +1,189 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'kotlin-android-extensions'
|
||||
id("kotlin-kapt") // Only for Kotlin projects.
|
||||
id("io.objectbox") // Add after other plugins.
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.qidian.zhongkesmart"
|
||||
minSdkVersion 24
|
||||
// minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
// targetSdkVersion 31
|
||||
versionCode 1
|
||||
versionName "1.0.1"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
// ndk {
|
||||
// //选择要添加的对应 cpu 类型的 .so 库。
|
||||
// abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86'
|
||||
// // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
|
||||
// }
|
||||
ndk {
|
||||
rootProject.ext.ndkAbis.each { abi ->
|
||||
abiFilter(abi)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
jniLibs.srcDir 'libs'
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
flatDir { dirs 'libs' }
|
||||
mavenCentral()
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias 'key0'
|
||||
keyPassword '123456'
|
||||
storeFile file('../zksmart.jks')
|
||||
storePassword '123456'
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
debug {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.all {
|
||||
def createTime = new Date().format("MMddHHmm", TimeZone.getTimeZone("GMT+08:00"))
|
||||
//只处理生产版本
|
||||
if (buildType.name == 'release') {
|
||||
// app包名称
|
||||
outputFileName = "app_zksmart_release" + defaultConfig.versionName + "_" + defaultConfig.versionCode + "_" + createTime + ".apk"
|
||||
} else {
|
||||
outputFileName = "app_zksmart_test" + defaultConfig.versionName + "_" + defaultConfig.versionCode + "_" + createTime + ".apk"
|
||||
}
|
||||
}
|
||||
}
|
||||
/* buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}*/
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
|
||||
packagingOptions {
|
||||
pickFirst 'lib/arm64-v8a/libc++_shared.so'
|
||||
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
|
||||
}
|
||||
|
||||
def appKey = "72eed074506376b102a91e6a80ef9a71"
|
||||
|
||||
// app key for code
|
||||
defaultConfig {
|
||||
buildConfigField "String", "APP_KEY", "\"${appKey}\""
|
||||
}
|
||||
// base server url
|
||||
defaultConfig {
|
||||
buildConfigField "String", "BASE_URL", "\"https://yiyong.netease.im/\""
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
// check for updates every build
|
||||
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation 'androidx.core:core-ktx:1.3.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.2.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
||||
implementation files('libs\\core_3.0.1.jar')
|
||||
implementation files('libs\\QWeather_Public_Android_V4.10.jar')
|
||||
|
||||
testImplementation 'junit:junit:4.+'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
implementation 'com.android.support:support-v4:28.0.0'
|
||||
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-26'
|
||||
//状态栏
|
||||
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
|
||||
implementation 'net.idik:slimadapter:2.1.2'
|
||||
|
||||
def aar = ['FlycoDialog-1.3.2']
|
||||
aar.each { implementation(name: it, ext: 'aar') }
|
||||
|
||||
// implementation 'cn.yipianfengye.android:zxing-library:2.2'
|
||||
implementation 'pub.devrel:easypermissions:3.0.0'
|
||||
//chart
|
||||
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
|
||||
//验证码样式
|
||||
implementation 'com.jacktuotuo.customview:verificationcodeview:1.0.5'
|
||||
//eventbus 事件分发
|
||||
implementation 'org.greenrobot:eventbus:3.1.1'
|
||||
// implementation 'com.squareup.okhttp3:okhttp:3.10.0'
|
||||
//网络okgo
|
||||
implementation 'com.lzy.net:okgo:3.0.4'
|
||||
//json
|
||||
implementation 'com.alibaba:fastjson:1.2.76'
|
||||
// implementation 'com.google.code.gson:gson:2.8.8'
|
||||
api 'io.reactivex.rxjava2:rxjava:2.2.9'
|
||||
api 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
||||
//蓝牙连接
|
||||
// implementation 'com.inuker.bluetooth:library:1.4.0'
|
||||
// api project(":lib-zxing")
|
||||
// implementation project(path: ':FlycoDialog_Lib')
|
||||
implementation 'com.vise.xiaoyaoyou:viselog:1.1.2'
|
||||
/*蓝牙BLE*/
|
||||
implementation 'com.vise.xiaoyaoyou:xsnow:2.1.3'
|
||||
//eventbus 事件分发
|
||||
implementation 'org.greenrobot:eventbus:3.1.1'
|
||||
implementation 'com.makeramen:roundedimageview:2.3.0'
|
||||
|
||||
implementation 'com.hyman:flowlayout-lib:1.1.2'
|
||||
implementation 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
|
||||
|
||||
//高德地图-天气预报需要
|
||||
implementation files('libs\\AMap2DMap_6.0.0_AMapSearch_9.2.0_AMapLocation_6.1.0_20220414.jar')
|
||||
compile 'com.squareup.okhttp3:okhttp:3.12.12'
|
||||
compile 'com.google.code.gson:gson:2.6.2'
|
||||
|
||||
implementation 'com.tencent.bugly:crashreport:latest.release' //其中latest.release指代最新Bugly SDK版本号,也可以指定明确的版本号,例如2.1.9
|
||||
implementation 'com.tencent.bugly:nativecrashreport:latest.release' //其中latest.release指代最新Bugly NDK版本号,也可以指定明确的版本号,例如3.0
|
||||
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
|
||||
api 'com.squareup.okhttp3:logging-interceptor:3.12.12'
|
||||
implementation 'com.blankj:utilcodex:1.30.5'
|
||||
api 'com.netease.yunxin.kit:call-ui:1.6.1'
|
||||
implementation 'com.jakewharton:butterknife:10.1.0'
|
||||
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
|
||||
|
||||
implementation 'no.nordicsemi.android:dfu:1.11.1'
|
||||
// Manually add objectbox-android-objectbrowser only for debug builds,
|
||||
// and objectbox-android for release builds.
|
||||
// debugImplementation("io.objectbox:objectbox-android-objectbrowser:$objectboxVersion")
|
||||
}
|
||||
// Apply the plugin after the dependencies block so it picks up
|
||||
// and does not add objectbox-android.
|
||||
apply plugin: 'io.objectbox'
|
||||
Binary file not shown.
BIN
app/libs/QWeather_Public_Android_V4.10.jar
Normal file
BIN
app/libs/QWeather_Public_Android_V4.10.jar
Normal file
Binary file not shown.
BIN
app/libs/core_3.0.1.jar
Normal file
BIN
app/libs/core_3.0.1.jar
Normal file
Binary file not shown.
146
app/objectbox-models/default.json
Normal file
146
app/objectbox-models/default.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
|
||||
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
|
||||
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
|
||||
"entities": [
|
||||
{
|
||||
"id": "1:8870068616457392677",
|
||||
"lastPropertyId": "18:2692014094612841667",
|
||||
"name": "DeviceInfo",
|
||||
"properties": [
|
||||
{
|
||||
"id": "1:6521131736238904230",
|
||||
"name": "id",
|
||||
"type": 6,
|
||||
"flags": 1
|
||||
},
|
||||
{
|
||||
"id": "2:5321779084544836486",
|
||||
"name": "mac",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "3:5565654943114914994",
|
||||
"name": "name",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "4:4477724591133570579",
|
||||
"name": "type",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "5:5761568316025382114",
|
||||
"name": "time",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "6:6210103608815305678",
|
||||
"name": "power",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "7:1468224017784560265",
|
||||
"name": "hVersion",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "8:5321966599309179601",
|
||||
"name": "fVersion",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "9:2980799595530192890",
|
||||
"name": "frequency",
|
||||
"type": 5
|
||||
},
|
||||
{
|
||||
"id": "10:8084290042726521451",
|
||||
"name": "model1Init",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"id": "11:9202164223710450367",
|
||||
"name": "model1Time",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "12:5769566883528611402",
|
||||
"name": "model1Threshold",
|
||||
"type": 5
|
||||
},
|
||||
{
|
||||
"id": "13:955728021080652231",
|
||||
"name": "model2Init",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"id": "14:691873319222183189",
|
||||
"name": "model2Time",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "15:8657884220131345907",
|
||||
"name": "model2Threshold",
|
||||
"type": 5
|
||||
},
|
||||
{
|
||||
"id": "16:6172923985060486493",
|
||||
"name": "isOnline",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"id": "17:5915524316767102281",
|
||||
"name": "isBind",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"id": "18:2692014094612841667",
|
||||
"name": "updateTime",
|
||||
"type": 9
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
},
|
||||
{
|
||||
"id": "2:8894725199741668450",
|
||||
"lastPropertyId": "4:8713898675265447700",
|
||||
"name": "ActionInfo",
|
||||
"properties": [
|
||||
{
|
||||
"id": "1:2646917254676249586",
|
||||
"name": "id",
|
||||
"type": 6,
|
||||
"flags": 1
|
||||
},
|
||||
{
|
||||
"id": "2:8087768899070666486",
|
||||
"name": "mac",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "3:6810165371149848163",
|
||||
"name": "data",
|
||||
"type": 23
|
||||
},
|
||||
{
|
||||
"id": "4:8713898675265447700",
|
||||
"name": "time",
|
||||
"type": 9
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
],
|
||||
"lastEntityId": "2:8894725199741668450",
|
||||
"lastIndexId": "0:0",
|
||||
"lastRelationId": "0:0",
|
||||
"lastSequenceId": "0:0",
|
||||
"modelVersion": 5,
|
||||
"modelVersionParserMinimum": 5,
|
||||
"retiredEntityUids": [],
|
||||
"retiredIndexUids": [],
|
||||
"retiredPropertyUids": [],
|
||||
"retiredRelationUids": [],
|
||||
"version": 1
|
||||
}
|
||||
21
app/proguard-rules.pro
vendored
Normal file
21
app/proguard-rules.pro
vendored
Normal 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
|
||||
@ -0,0 +1,24 @@
|
||||
package com.qidian.zhongkesmart
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.qidian.zhongkesmart", appContext.packageName)
|
||||
}
|
||||
}
|
||||
175
app/src/main/AndroidManifest.xml
Normal file
175
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.qidian.zhongkesmart">
|
||||
<!-- android:sharedUserId="android.uid.system" -->
|
||||
<!-- 网络权限 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.INTERNET" /> <!-- 震动权限 -->
|
||||
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" /> <!-- 摄像头权限 -->
|
||||
<uses-permission android:name="android.permission.CAMERA" /> <!-- 自动聚焦权限 -->
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 以下是使用wifi访问网络所需的权限 -->
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 蓝牙 -->
|
||||
<!-- 允许应用程序连接到配对的蓝牙设备 -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" /> <!-- 需要能够发现和配对附近的蓝牙设备 -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- 允许应用程序发现和配对蓝牙设备 -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- 需要能够连接到配对的蓝牙设备 -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 允许应用程序在没有用户交互的情况下配对蓝牙设备,并允许或禁止电话簿访问或消息访问 -->
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH_PRIVILEGED"
|
||||
tools:ignore="ProtectedPermissions" /> <!-- 需要能够向附近的蓝牙设备做广告 Android 12 -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||
<uses-permission android:name="com.google.android.things.permission.MANAGE_BLUETOOTH" /> <!-- 获得定位 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 高德地图 -->
|
||||
<!-- 用于进行网络定位 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 用于访问GPS定位 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 用于获取运营商信息,用于支持提供运营商信息相关的接口 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 用于访问网络,网络定位需要上网 -->
|
||||
<uses-permission android:name="android.permission.INTERNET" /> <!-- 用于读取手机当前的状态 -->
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 用于写入缓存数据到扩展存储卡 -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 用于申请调用A-GPS模块 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 如果设置了target >= 28 如果需要启动后台定位则必须声明这个权限 -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- 如果您的应用需要后台定位权限,且有可能运行在Android Q设备上,并且设置了target>28,必须增加这个权限声明 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <!-- 控制呼吸灯,振动器等,用于新消息提醒 -->
|
||||
<uses-permission android:name="android.permission.FLASHLIGHT" />
|
||||
<!-- Required to run keep-alive service when targeting API 28 or higher -->
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" /> <!-- 8.0+系统需要 -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- 下面的 uses-permission 一起加入到你的 AndroidManifest 文件中。 -->
|
||||
<permission
|
||||
android:name="com.netease.yunxin.nertc.demo.permission.RECEIVE_MSG"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<uses-permission android:name="com.netease.yunxin.nertc.demo.permission.RECEIVE_MSG" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth_le"
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:name=".base.AppApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.ZhongKeSmart">
|
||||
<activity android:name=".activity.ModelInitActivity"></activity>
|
||||
<activity android:name=".activity.BluetoothActivity" />
|
||||
<activity android:name=".activity.SettingModeActivity" />
|
||||
<activity android:name=".activity.ConnectModeActivity" />
|
||||
<activity android:name=".activity.HomeActivity" />
|
||||
<activity
|
||||
android:name="com.netease.yunxin.nertc.ui.p2p.P2PCallActivity"
|
||||
android:screenOrientation="landscape"
|
||||
tools:replace="screenOrientation" />
|
||||
<activity
|
||||
android:name=".activity.SelectCallUserActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.StandByActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.SetSeconedActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.InfoActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.SettingActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.SetLockActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.SmartAnalysisActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.MyEquipmentDetailsActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.MyEquipmentActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.ServiceActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.WiFiActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<!--
|
||||
<activity
|
||||
android:name=".activity.CaptureActivity"
|
||||
android:screenOrientation="landscape"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"/>
|
||||
-->
|
||||
<activity
|
||||
android:name="com.qidian.zxing.lib_zxing.activity.CaptureActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
<activity
|
||||
android:name=".activity.LaunchActivity"
|
||||
android:exported="true"
|
||||
android:screenOrientation="landscape">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<!-- Launcher -->
|
||||
<category android:name="android.intent.category.HOME" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="com.qidian.zhongkesmart.fileProvider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<receiver android:name=".receiver.WifiReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.wifi.RSSI_CHANGED" />
|
||||
<action android:name="android.net.wifi.STATE_CHANGE" />
|
||||
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
|
||||
</intent-filter>
|
||||
</receiver> <!-- 蓝牙相关 -->
|
||||
<service android:name="com.inuker.bluetooth.library.BluetoothService" /> <!-- 高德相关 -->
|
||||
<service
|
||||
android:name=".bluetooth.dfu.DfuService"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.amap.api.v2.apikey"
|
||||
android:value="d110918de47390779d61a19d63254b30" />
|
||||
|
||||
<service android:name="com.amap.api.location.APSService" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
BIN
app/src/main/assets/SDK1702_d_1.0.4.zip
Normal file
BIN
app/src/main/assets/SDK1702_d_1.0.4.zip
Normal file
Binary file not shown.
BIN
app/src/main/assets/SDK1702_l_1.0.1.zip
Normal file
BIN
app/src/main/assets/SDK1702_l_1.0.1.zip
Normal file
Binary file not shown.
BIN
app/src/main/ic_launcher-playstore.png
Normal file
BIN
app/src/main/ic_launcher-playstore.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
407
app/src/main/java/com/qidian/baseble/ViseBle.java
Normal file
407
app/src/main/java/com/qidian/baseble/ViseBle.java
Normal file
@ -0,0 +1,407 @@
|
||||
package com.qidian.baseble;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.qidian.baseble.ble.BluetoothDeviceManager;
|
||||
import com.qidian.baseble.callback.IConnectCallback;
|
||||
import com.qidian.baseble.callback.scan.IScanCallback;
|
||||
import com.qidian.baseble.callback.scan.ScanCallback;
|
||||
import com.qidian.baseble.callback.scan.SingleFilterScanCallback;
|
||||
import com.qidian.baseble.common.BleConfig;
|
||||
import com.qidian.baseble.common.ConnectState;
|
||||
import com.qidian.baseble.core.DeviceMirror;
|
||||
import com.qidian.baseble.core.DeviceMirrorPool;
|
||||
import com.qidian.baseble.exception.TimeoutException;
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
import com.qidian.baseble.model.BluetoothLeDeviceStore;
|
||||
import com.vise.log.ViseLog;
|
||||
|
||||
/**
|
||||
* @Description: BLE设备操作入口
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/8/1 22:24.
|
||||
*/
|
||||
public class ViseBle {
|
||||
private Context context;//上下文
|
||||
private BluetoothManager bluetoothManager;//蓝牙管理
|
||||
private BluetoothAdapter bluetoothAdapter;//蓝牙适配器
|
||||
private DeviceMirrorPool deviceMirrorPool;//设备连接池
|
||||
private DeviceMirror lastDeviceMirror;//上次操作设备镜像
|
||||
|
||||
private static ViseBle instance;//入口操作管理
|
||||
private static BleConfig bleConfig = BleConfig.getInstance();
|
||||
|
||||
/**
|
||||
* 单例方式获取蓝牙通信入口
|
||||
*
|
||||
* @return 返回ViseBluetooth
|
||||
*/
|
||||
public static ViseBle getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (ViseBle.class) {
|
||||
if (instance == null) {
|
||||
instance = new ViseBle();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ViseBle() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置对象,可进行相关配置的修改
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static BleConfig config() {
|
||||
return bleConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @param context 上下文
|
||||
*/
|
||||
public void init(Context context) {
|
||||
if (this.context == null && context != null) {
|
||||
this.context = context.getApplicationContext();
|
||||
bluetoothManager = (BluetoothManager) this.context.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
bluetoothAdapter = bluetoothManager.getAdapter();
|
||||
deviceMirrorPool = new DeviceMirrorPool();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始扫描
|
||||
*
|
||||
* @param scanCallback 自定义回调
|
||||
*/
|
||||
public void startScan(ScanCallback scanCallback) {
|
||||
if (scanCallback == null) {
|
||||
throw new IllegalArgumentException("this ScanCallback is Null!");
|
||||
}
|
||||
scanCallback.setScan(true).scan();
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止扫描
|
||||
*
|
||||
* @param scanCallback 自定义回调
|
||||
*/
|
||||
public void stopScan(ScanCallback scanCallback) {
|
||||
if (scanCallback == null) {
|
||||
throw new IllegalArgumentException("this ScanCallback is Null!");
|
||||
}
|
||||
scanCallback.setScan(false).removeHandlerMsg().scan();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定扫描
|
||||
*/
|
||||
public void startScanByDevice(BluetoothLeDevice mBluetoothLeDevice) {
|
||||
ScanCallback scanCallback = new ScanCallback(new IScanCallback() {
|
||||
@Override
|
||||
public void onDeviceFound(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (!TextUtils.isEmpty(bluetoothLeDevice.getAddress())) {
|
||||
if (mBluetoothLeDevice.getAddress().equals(bluetoothLeDevice.getAddress())) {
|
||||
Log.i(
|
||||
"BlueTooth==",
|
||||
"periodScanCallback:发现指定设备"+bluetoothLeDevice.getAddress());
|
||||
if (!BluetoothDeviceManager.getInstance().isConnected(bluetoothLeDevice)) {
|
||||
BluetoothDeviceManager.getInstance().connect(bluetoothLeDevice);
|
||||
}
|
||||
}
|
||||
Log.i(
|
||||
"BlueTooth==",
|
||||
"periodScanCallback:发现设备"+bluetoothLeDevice.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanFinish(BluetoothLeDeviceStore bluetoothLeDeviceStore) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanTimeout() {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
scanCallback.setScan(true).scan();
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接设备
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
* @param connectCallback
|
||||
*/
|
||||
public void connect(BluetoothLeDevice bluetoothLeDevice, IConnectCallback connectCallback) {
|
||||
if (bluetoothLeDevice == null || connectCallback == null) {
|
||||
ViseLog.e("This bluetoothLeDevice or connectCallback is null.");
|
||||
return;
|
||||
}
|
||||
if (deviceMirrorPool != null && !deviceMirrorPool.isContainDevice(bluetoothLeDevice)) {
|
||||
DeviceMirror deviceMirror = new DeviceMirror(bluetoothLeDevice);
|
||||
if (lastDeviceMirror != null && !TextUtils.isEmpty(lastDeviceMirror.getUniqueSymbol())
|
||||
&& lastDeviceMirror.getUniqueSymbol().equals(deviceMirror.getUniqueSymbol())) {
|
||||
deviceMirror = lastDeviceMirror;//防止重复创建设备镜像
|
||||
}
|
||||
deviceMirror.connect(connectCallback);
|
||||
lastDeviceMirror = deviceMirror;
|
||||
} else {
|
||||
ViseLog.i("This device is connected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接指定mac地址的设备
|
||||
*
|
||||
* @param mac 设备mac地址
|
||||
* @param connectCallback 连接回调
|
||||
*/
|
||||
public void connectByMac(String mac, final IConnectCallback connectCallback) {
|
||||
if (mac == null || connectCallback == null) {
|
||||
ViseLog.e("This mac or connectCallback is null.");
|
||||
return;
|
||||
}
|
||||
startScan(new SingleFilterScanCallback(new IScanCallback() {
|
||||
@Override
|
||||
public void onDeviceFound(BluetoothLeDevice bluetoothLeDevice) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanFinish(final BluetoothLeDeviceStore bluetoothLeDeviceStore) {
|
||||
if (bluetoothLeDeviceStore.getDeviceList().size() > 0) {
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
connect(bluetoothLeDeviceStore.getDeviceList().get(0), connectCallback);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
connectCallback.onConnectFailure(new TimeoutException());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanTimeout() {
|
||||
connectCallback.onConnectFailure(new TimeoutException());
|
||||
}
|
||||
|
||||
}).setDeviceMac(mac));
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接指定设备名称的设备
|
||||
*
|
||||
* @param name 设备名称
|
||||
* @param connectCallback 连接回调
|
||||
*/
|
||||
public void connectByName(String name, final IConnectCallback connectCallback) {
|
||||
if (name == null || connectCallback == null) {
|
||||
ViseLog.e("This name or connectCallback is null.");
|
||||
return;
|
||||
}
|
||||
startScan(new SingleFilterScanCallback(new IScanCallback() {
|
||||
@Override
|
||||
public void onDeviceFound(BluetoothLeDevice bluetoothLeDevice) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanFinish(final BluetoothLeDeviceStore bluetoothLeDeviceStore) {
|
||||
if (bluetoothLeDeviceStore.getDeviceList().size() > 0) {
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
connect(bluetoothLeDeviceStore.getDeviceList().get(0), connectCallback);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
connectCallback.onConnectFailure(new TimeoutException());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanTimeout() {
|
||||
connectCallback.onConnectFailure(new TimeoutException());
|
||||
}
|
||||
|
||||
}).setDeviceName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接池中的设备镜像,如果没有连接则返回空
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
* @return
|
||||
*/
|
||||
public DeviceMirror getDeviceMirror(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (deviceMirrorPool != null) {
|
||||
return deviceMirrorPool.getDeviceMirror(bluetoothLeDevice);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该设备连接状态
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
* @return
|
||||
*/
|
||||
public ConnectState getConnectState(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (deviceMirrorPool != null) {
|
||||
return deviceMirrorPool.getConnectState(bluetoothLeDevice);
|
||||
}
|
||||
return ConnectState.CONNECT_DISCONNECT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断该设备是否已连接
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
* @return
|
||||
*/
|
||||
public boolean isConnect(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (deviceMirrorPool != null) {
|
||||
return deviceMirrorPool.isContainDevice(bluetoothLeDevice);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 判断该设备是否已连接
|
||||
* 只允许连接一个
|
||||
* 2022
|
||||
* @return
|
||||
*/
|
||||
public boolean isConnectDevice() {
|
||||
if (deviceMirrorPool != null) {
|
||||
return deviceMirrorPool.isConnectDevice();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开某一个设备
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
*/
|
||||
public void disconnect(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (deviceMirrorPool != null) {
|
||||
deviceMirrorPool.disconnect(bluetoothLeDevice);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开所有设备
|
||||
*/
|
||||
public void disconnect() {
|
||||
if (deviceMirrorPool != null) {
|
||||
deviceMirrorPool.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除资源,在退出应用时调用
|
||||
*/
|
||||
public void clear() {
|
||||
if (deviceMirrorPool != null) {
|
||||
deviceMirrorPool.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Context
|
||||
*
|
||||
* @return 返回Context
|
||||
*/
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取蓝牙管理
|
||||
*
|
||||
* @return 返回蓝牙管理
|
||||
*/
|
||||
public BluetoothManager getBluetoothManager() {
|
||||
return bluetoothManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取蓝牙适配器
|
||||
*
|
||||
* @return 返回蓝牙适配器
|
||||
*/
|
||||
public BluetoothAdapter getBluetoothAdapter() {
|
||||
return bluetoothAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备镜像池
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public DeviceMirrorPool getDeviceMirrorPool() {
|
||||
return deviceMirrorPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前连接失败重试次数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getConnectRetryCount() {
|
||||
if (lastDeviceMirror == null) {
|
||||
return 0;
|
||||
}
|
||||
return lastDeviceMirror.getConnectRetryCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前读取数据失败重试次数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getReadDataRetryCount() {
|
||||
if (lastDeviceMirror == null) {
|
||||
return 0;
|
||||
}
|
||||
return lastDeviceMirror.getReadDataRetryCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前使能数据失败重试次数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getReceiveDataRetryCount() {
|
||||
if (lastDeviceMirror == null) {
|
||||
return 0;
|
||||
}
|
||||
return lastDeviceMirror.getReceiveDataRetryCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前写入数据失败重试次数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getWriteDataRetryCount() {
|
||||
if (lastDeviceMirror == null) {
|
||||
return 0;
|
||||
}
|
||||
return lastDeviceMirror.getWriteDataRetryCount();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,819 @@
|
||||
package com.qidian.baseble.ble;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.qidian.baseble.ViseBle;
|
||||
import com.qidian.baseble.callback.IBleCallback;
|
||||
import com.qidian.baseble.callback.IConnectCallback;
|
||||
import com.qidian.baseble.common.PropertyType;
|
||||
import com.qidian.baseble.core.BluetoothGattChannel;
|
||||
import com.qidian.baseble.core.DeviceMirror;
|
||||
import com.qidian.baseble.core.DeviceMirrorPool;
|
||||
import com.qidian.baseble.exception.BleException;
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
import com.qidian.baseble.utils.HexUtil;
|
||||
import com.qidian.zhongkesmart.config.EventCode;
|
||||
import com.qidian.zhongkesmart.model.ActionInfo;
|
||||
import com.qidian.zhongkesmart.model.DeviceInfo;
|
||||
import com.qidian.zhongkesmart.utils.DataServer;
|
||||
import com.qidian.zhongkesmart.utils.EventBusUtil;
|
||||
import com.qidian.zhongkesmart.utils.ObjectBoxUtils;
|
||||
import com.qidian.zhongkesmart.utils.TimeUtil;
|
||||
import com.qidian.zhongkesmart.utils.Utils;
|
||||
import com.vise.log.ViseLog;
|
||||
import com.vise.xsnow.event.BusManager;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.qidian.baseble.utils.HexUtil.GetTempTime;
|
||||
import static com.qidian.baseble.utils.HexUtil.addBytes;
|
||||
import static com.qidian.baseble.utils.HexUtil.byteArrayToInt;
|
||||
import static com.qidian.baseble.utils.HexUtil.byteToInt;
|
||||
import static com.qidian.baseble.utils.HexUtil.byte_String;
|
||||
import static com.qidian.baseble.utils.HexUtil.decodeHex;
|
||||
import static com.qidian.baseble.utils.HexUtil.int2ByteArray;
|
||||
|
||||
|
||||
public class BluetoothDeviceManager {
|
||||
private static BluetoothDeviceManager instance;
|
||||
private DeviceMirrorPool mDeviceMirrorPool;
|
||||
private ScanEvent scanEvent = new ScanEvent();
|
||||
private ConnectEvent connectEvent = new ConnectEvent();
|
||||
private CallbackDataEvent callbackDataEvent = new CallbackDataEvent();
|
||||
private NotifyDataEvent notifyDataEvent = new NotifyDataEvent();
|
||||
|
||||
private final String TAG = "BlueTooth==";
|
||||
private BluetoothLeDevice mDevice;
|
||||
private Map<String, byte[]> deviceAction = new HashMap<>();
|
||||
private DeviceInfo deviceInfo;
|
||||
private List<DeviceInfo> list;
|
||||
//动作学习时间
|
||||
private String timeString = "";
|
||||
/**
|
||||
* 连接回调
|
||||
*/
|
||||
private IConnectCallback connectCallback = new IConnectCallback() {
|
||||
|
||||
@Override
|
||||
public void onConnectSuccess(final DeviceMirror deviceMirror) {
|
||||
Log.i("BlueTooth==", "connectCallback:Connect Success");
|
||||
BusManager.getBus().post(connectEvent.setDeviceMirror(deviceMirror).setSuccess(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectFailure(BleException exception) {
|
||||
Log.i("BlueTooth==", "connectCallback:onConnectFailure");
|
||||
BusManager.getBus().post(connectEvent.setSuccess(false).setDisconnected(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(boolean isActive) {
|
||||
Log.i("BlueTooth==", "connectCallback:Disconnect");
|
||||
BusManager.getBus().post(connectEvent.setSuccess(false).setDisconnected(true));
|
||||
}
|
||||
};
|
||||
|
||||
public synchronized void close() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收数据回调
|
||||
*/
|
||||
private IBleCallback receiveCallback = new IBleCallback() {
|
||||
@Override
|
||||
public void onSuccess(final byte[] data, BluetoothGattChannel bluetoothGattInfo, BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
mDevice = bluetoothLeDevice;
|
||||
Log.i("BlueTooth==", "notify success:" + HexUtil.encodeHexStr(data));
|
||||
ViseLog.i("notify success:" + HexUtil.encodeHexStr(data));
|
||||
// BusManager.getBus().post(notifyDataEvent.setData(data)
|
||||
// .setBluetoothLeDevice(bluetoothLeDevice)
|
||||
// .setBluetoothGattChannel(bluetoothGattInfo));
|
||||
deviceProcess(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(BleException exception) {
|
||||
if (exception == null) {
|
||||
return;
|
||||
}
|
||||
ViseLog.i("notify fail:" + exception.getDescription());
|
||||
Log.i("BlueTooth==", "notify fail");
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 操作数据回调
|
||||
*/
|
||||
private IBleCallback bleCallback = new IBleCallback() {
|
||||
@Override
|
||||
public void onSuccess(final byte[] data, BluetoothGattChannel bluetoothGattInfo, BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
Log.i("BlueTooth==", "bleCallback success" +data);
|
||||
Log.i("BlueTooth==", "bleCallback success" + HexUtil.bytesToHex(data));
|
||||
if(data.length>10) {
|
||||
String sVer = new String(data);
|
||||
Log.i("BlueTooth==", "bleCallback success" + sVer);
|
||||
}
|
||||
ViseLog.i("callback success:" + HexUtil.encodeHexStr(data));
|
||||
BusManager.getBus().post(callbackDataEvent.setData(data).setSuccess(true)
|
||||
.setBluetoothLeDevice(bluetoothLeDevice)
|
||||
.setBluetoothGattChannel(bluetoothGattInfo));
|
||||
if (bluetoothGattInfo != null && (bluetoothGattInfo.getPropertyType() == PropertyType.PROPERTY_INDICATE
|
||||
|| bluetoothGattInfo.getPropertyType() == PropertyType.PROPERTY_NOTIFY)) {
|
||||
DeviceMirror deviceMirror = mDeviceMirrorPool.getDeviceMirror(bluetoothLeDevice);
|
||||
if (deviceMirror != null) {
|
||||
deviceMirror.setNotifyListener(bluetoothGattInfo.getGattInfoKey(), receiveCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(BleException exception) {
|
||||
Log.i("BlueTooth==", "bleCallback fail");
|
||||
if (exception == null) {
|
||||
return;
|
||||
}
|
||||
ViseLog.i("BlueTooth==callback fail:" + exception.getDescription());
|
||||
BusManager.getBus().post(callbackDataEvent.setSuccess(false));
|
||||
}
|
||||
};
|
||||
|
||||
private BluetoothDeviceManager() {
|
||||
|
||||
}
|
||||
|
||||
public static BluetoothDeviceManager getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (BluetoothDeviceManager.class) {
|
||||
if (instance == null) {
|
||||
instance = new BluetoothDeviceManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void init(Context context) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
//蓝牙相关配置修改
|
||||
ViseBle.config()
|
||||
.setScanTimeout(-1) //扫描超时时间,-1设置为永久扫描
|
||||
.setScanRepeatInterval(10*60*1000)//扫描间隔
|
||||
.setConnectTimeout(8 * 1000)//连接超时时间
|
||||
.setOperateTimeout(5 * 1000)//设置数据操作超时时间
|
||||
.setConnectRetryCount(0)//设置连接失败重试次数
|
||||
.setConnectRetryInterval(1000)//设置连接失败重试间隔时间
|
||||
.setOperateRetryCount(0)//设置数据操作失败重试次数
|
||||
.setOperateRetryInterval(1000)//设置数据操作失败重试间隔时间
|
||||
.setMaxConnectCount(1);//设置最大连接设备数量
|
||||
//蓝牙信息初始化,全局唯一,必须在应用初始化时调用
|
||||
ViseBle.getInstance().init(context.getApplicationContext());
|
||||
mDeviceMirrorPool = ViseBle.getInstance().getDeviceMirrorPool();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void connect(BluetoothLeDevice bluetoothLeDevice) {
|
||||
ViseBle.getInstance().connect(bluetoothLeDevice, connectCallback);
|
||||
}
|
||||
|
||||
public void connect(String macStr) {
|
||||
ViseBle.getInstance().connectByMac(macStr, connectCallback);
|
||||
}
|
||||
|
||||
|
||||
public void connect(String macStr, IConnectCallback connectCallback) {
|
||||
ViseBle.getInstance().connectByMac(macStr, connectCallback);
|
||||
}
|
||||
public void connect(BluetoothLeDevice bluetoothLeDevice, IConnectCallback connectCallback) {
|
||||
ViseBle.getInstance().connect(bluetoothLeDevice, connectCallback);
|
||||
}
|
||||
public void disconnect(BluetoothLeDevice bluetoothLeDevice) {
|
||||
ViseBle.getInstance().disconnect(bluetoothLeDevice);
|
||||
}
|
||||
public void disconnect() {
|
||||
ViseBle.getInstance().disconnect();
|
||||
}
|
||||
|
||||
public boolean isConnected(BluetoothLeDevice bluetoothLeDevice) {
|
||||
return ViseBle.getInstance().isConnect(bluetoothLeDevice);
|
||||
}
|
||||
|
||||
public boolean isConnectedDevice() {
|
||||
return ViseBle.getInstance().isConnectDevice();
|
||||
}
|
||||
|
||||
public void bindChannel(BluetoothLeDevice bluetoothLeDevice, PropertyType propertyType, UUID serviceUUID,
|
||||
UUID characteristicUUID, UUID descriptorUUID) {
|
||||
DeviceMirror deviceMirror = mDeviceMirrorPool.getDeviceMirror(bluetoothLeDevice);
|
||||
if (deviceMirror != null) {
|
||||
BluetoothGattChannel bluetoothGattChannel = new BluetoothGattChannel.Builder()
|
||||
.setBluetoothGatt(deviceMirror.getBluetoothGatt())
|
||||
.setPropertyType(propertyType)
|
||||
.setServiceUUID(serviceUUID)
|
||||
.setCharacteristicUUID(characteristicUUID)
|
||||
.setDescriptorUUID(descriptorUUID)
|
||||
.builder();
|
||||
deviceMirror.bindChannel(bleCallback, bluetoothGattChannel);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void write(final BluetoothLeDevice bluetoothLeDevice, byte[] data,final String ml) {
|
||||
if (dataInfoQueue != null) {
|
||||
dataInfoQueue.clear();
|
||||
dataInfoQueue = splitPacketFor20Byte(data);
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
send(bluetoothLeDevice,ml);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void read(BluetoothLeDevice bluetoothLeDevice) {
|
||||
DeviceMirror deviceMirror = mDeviceMirrorPool.getDeviceMirror(bluetoothLeDevice);
|
||||
if (deviceMirror != null) {
|
||||
deviceMirror.readData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void registerNotify(BluetoothLeDevice bluetoothLeDevice, boolean isIndicate) {
|
||||
DeviceMirror deviceMirror = mDeviceMirrorPool.getDeviceMirror(bluetoothLeDevice);
|
||||
if (deviceMirror != null) {
|
||||
deviceMirror.registerNotify(isIndicate);
|
||||
}
|
||||
}
|
||||
|
||||
//发送队列,提供一种简单的处理方式,实际项目场景需要根据需求优化
|
||||
private Queue<byte[]> dataInfoQueue = new LinkedList<>();
|
||||
|
||||
private void send(final BluetoothLeDevice bluetoothLeDevice,final String ml) {
|
||||
if (dataInfoQueue != null && !dataInfoQueue.isEmpty()) {
|
||||
DeviceMirror deviceMirror = mDeviceMirrorPool.getDeviceMirror(bluetoothLeDevice);
|
||||
if (dataInfoQueue.peek() != null && deviceMirror != null) {
|
||||
deviceMirror.writeData(dataInfoQueue.poll(),ml);
|
||||
}
|
||||
if (dataInfoQueue.peek() != null) {
|
||||
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
send(bluetoothLeDevice,ml);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据分包
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
private Queue<byte[]> splitPacketFor20Byte(byte[] data) {
|
||||
Queue<byte[]> dataInfoQueue = new LinkedList<>();
|
||||
if (data != null) {
|
||||
int index = 0;
|
||||
do {
|
||||
byte[] surplusData = new byte[data.length - index];
|
||||
byte[] currentData;
|
||||
System.arraycopy(data, index, surplusData, 0, data.length - index);
|
||||
if (surplusData.length <= 20) {
|
||||
currentData = new byte[surplusData.length];
|
||||
System.arraycopy(surplusData, 0, currentData, 0, surplusData.length);
|
||||
index += surplusData.length;
|
||||
} else {
|
||||
currentData = new byte[20];
|
||||
System.arraycopy(data, index, currentData, 0, 20);
|
||||
index += 20;
|
||||
}
|
||||
dataInfoQueue.offer(currentData);
|
||||
} while (index < data.length);
|
||||
}
|
||||
return dataInfoQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备数据处理流程
|
||||
* @param data
|
||||
*/
|
||||
private void deviceProcess(byte[] data) {
|
||||
String newHex = Integer.toHexString(data[1]& 0xFF);
|
||||
Log.i(TAG, "DeviceProcess:" + newHex);
|
||||
String mac = "";
|
||||
String formatMac = "";
|
||||
switch (data[1]) {
|
||||
case 0x01:
|
||||
String hVer = new String(new byte[]{data[2], data[3], data[4], data[5],
|
||||
data[6], data[7], data[8], data[9],
|
||||
data[10], data[11], data[12], data[13]});
|
||||
mac = byte_String(data[19]) + byte_String(data[18]) +
|
||||
byte_String(data[17]) +
|
||||
byte_String(data[16]) +
|
||||
byte_String(data[15]) +
|
||||
byte_String(data[14]);
|
||||
Log.i(TAG, mac+"的硬件版本号:" + hVer);
|
||||
formatMac = Utils.formatMac(mac,":");
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(formatMac);
|
||||
if(list!=null&&list.size()>0){
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setHVersion(hVer);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}else{
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(formatMac);
|
||||
deviceInfo.setHVersion(hVer);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
// ObjectBoxUtils.INSTANCE.updateData(deviceInfo,DeviceInfo.class);
|
||||
case 0x02:
|
||||
String sVer = new String(new byte[]{data[2], data[3], data[4], data[5],
|
||||
data[6], data[7], data[8], data[9],
|
||||
data[10], data[11], data[12], data[13]});
|
||||
mac = byte_String(data[19]) + byte_String(data[18]) +
|
||||
byte_String(data[17]) +
|
||||
byte_String(data[16]) +
|
||||
byte_String(data[15]) +
|
||||
byte_String(data[14]);
|
||||
Log.i(TAG, mac+"的软件版本号:" + sVer);
|
||||
formatMac = Utils.formatMac(mac,":");
|
||||
if(deviceInfo!=null&&deviceInfo.getMac().equals(formatMac)){
|
||||
deviceInfo.setFVersion(sVer);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
// list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac,":"));
|
||||
// if(list!=null&&list.size()>0){
|
||||
// deviceInfo = list.get(0);
|
||||
// deviceInfo.setFVersion(sVer);
|
||||
// deviceInfo.setOnline(true);
|
||||
// deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
// }else{
|
||||
// deviceInfo = new DeviceInfo();
|
||||
// deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
// deviceInfo.setFVersion(sVer);
|
||||
// deviceInfo.setOnline(true);
|
||||
// deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
// }
|
||||
// ObjectBoxUtils.INSTANCE.updateData(deviceInfo,DeviceInfo.class);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
int frequency = byteArrayToInt(new byte[]{data[4], data[5]});
|
||||
int model1Threshold = byteArrayToInt(new byte[]{data[6], data[7]});
|
||||
int model2Threshold = byteArrayToInt(new byte[]{data[8], data[9]});
|
||||
int power = byteToInt(data[10]);
|
||||
mac = byte_String(data[19]) + byte_String(data[18]) +
|
||||
byte_String(data[17]) +
|
||||
byte_String(data[16]) +
|
||||
byte_String(data[15]) +
|
||||
byte_String(data[14]);
|
||||
Log.i(TAG, mac+"频率:" +frequency+",模型1阈值:"+model1Threshold+",模型2阈值:"+model2Threshold+",电量:"+power);
|
||||
formatMac = Utils.formatMac(mac,":");
|
||||
if(deviceInfo!=null&&deviceInfo.getMac().equals(formatMac)){
|
||||
deviceInfo.setFrequency(frequency);
|
||||
deviceInfo.setModel1Threshold(model1Threshold);
|
||||
deviceInfo.setModel2Threshold(model2Threshold);
|
||||
deviceInfo.setPower(power+"");
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
// list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac,":"));
|
||||
// if(list!=null&&list.size()>0){
|
||||
// deviceInfo = list.get(0);
|
||||
// deviceInfo.setFrequency(frequency);
|
||||
// deviceInfo.setPower(power+"");
|
||||
// deviceInfo.setOnline(true);
|
||||
// deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
// }else{
|
||||
// deviceInfo = new DeviceInfo();
|
||||
// deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
// deviceInfo.setFrequency(frequency);
|
||||
// deviceInfo.setPower(power+"");
|
||||
// deviceInfo.setOnline(true);
|
||||
// deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
// }
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo,DeviceInfo.class);
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
mac = byte_String(data[19]) + byte_String(data[18]) +
|
||||
byte_String(data[17]) +
|
||||
byte_String(data[16]) +
|
||||
byte_String(data[15]) +
|
||||
byte_String(data[14]);
|
||||
int value = byteArrayToInt(new byte[]{data[5], data[6]});
|
||||
int flag = byteToInt(data[2]);
|
||||
BusManager.getBus().post(new DeviceSettingEvent(new byte[]{data[2],data[3],data[4]},mac,4));
|
||||
switch (data[3]){
|
||||
case 0x00:
|
||||
int type = byteToInt(data[4]);
|
||||
switch (type){
|
||||
case 1:
|
||||
Log.i(TAG, mac+"频率设置成功");
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac,":"));
|
||||
if(list!=null&&list.size()>0){
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setFrequency(value);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}else{
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
deviceInfo.setFrequency(value);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo,DeviceInfo.class);
|
||||
break;
|
||||
case 255:
|
||||
switch (flag) {
|
||||
case 0:
|
||||
Log.i(TAG, mac+"算法模型1学习成功");
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac,":"));
|
||||
if(list!=null&&list.size()>0){
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setModel1Init(true);
|
||||
deviceInfo.setModel1Time(timeString);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}else{
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
deviceInfo.setModel1Init(true);
|
||||
deviceInfo.setModel1Time(timeString);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo,DeviceInfo.class);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 254:
|
||||
Log.i(TAG, mac+"算法模型1阈值设置成功");
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac,":"));
|
||||
if(list!=null&&list.size()>0){
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setModel1Threshold(value);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}else{
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
deviceInfo.setModel1Threshold(value);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo,DeviceInfo.class);
|
||||
break;
|
||||
case 253:
|
||||
switch (flag) {
|
||||
case 0:
|
||||
Log.i(TAG, mac+"算法模型2学习成功");
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac,":"));
|
||||
if(list!=null&&list.size()>0){
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setModel2Init(true);
|
||||
deviceInfo.setModel2Time(timeString);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}else{
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
deviceInfo.setModel2Init(true);
|
||||
deviceInfo.setModel2Time(timeString);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo,DeviceInfo.class);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 252:
|
||||
Log.i(TAG, mac+"算法模型2阈值设置成功");
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac,":"));
|
||||
if(list!=null&&list.size()>0){
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setModel2Threshold(value);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}else{
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
deviceInfo.setModel2Threshold(value);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo,DeviceInfo.class);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case (byte)0xFC:
|
||||
Log.i(TAG, mac+"设备忙碌");
|
||||
break;
|
||||
case (byte)0xFB:
|
||||
Log.i(TAG, mac+"保存参数失败");
|
||||
break;
|
||||
case (byte)0xFA:
|
||||
Log.i(TAG, mac+"算法模型学习失败");
|
||||
break;
|
||||
case (byte) 0xF9:
|
||||
Log.i(TAG, mac+"指令无效");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
mac = byte_String(data[19]) + byte_String(data[18]) +
|
||||
byte_String(data[17]) +
|
||||
byte_String(data[16]) +
|
||||
byte_String(data[15]) +
|
||||
byte_String(data[14]);
|
||||
BusManager.getBus().post(new DeviceSettingEvent(new byte[]{data[2],data[3],data[4]},mac,5));
|
||||
switch (data[4]){
|
||||
case 0x00:
|
||||
int type = byteToInt(data[3]);
|
||||
switch (type){
|
||||
case 0:
|
||||
Log.i(TAG, mac+"正常工作成功");
|
||||
break;
|
||||
case 1:
|
||||
Log.i(TAG, mac+"强制休眠成功");
|
||||
break;
|
||||
case 2:
|
||||
int flag1 = byteToInt(data[2]);
|
||||
switch (flag1) {
|
||||
case 0:
|
||||
Log.i(TAG, mac + "结束模型验证成功");
|
||||
break;
|
||||
case 1:
|
||||
Log.i(TAG, mac + "开启模型验证成功");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
Log.i(TAG, mac+"开启模型2验证成功");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case (byte)0xFC:
|
||||
Log.i(TAG, mac+"设备忙碌");
|
||||
break;
|
||||
case (byte)0xFB:
|
||||
Log.i(TAG, mac+"保存参数失败");
|
||||
break;
|
||||
case (byte)0xFA:
|
||||
Log.i(TAG, mac+"算法模型学习失败");
|
||||
break;
|
||||
case (byte) 0xF9:
|
||||
Log.i(TAG, mac+"指令无效");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
// if(!Arrays.equals(lastAction,new byte[]{data[4], data[5]})||System.currentTimeMillis()-lastTime>3000) {
|
||||
// lastAction = new byte[]{data[4], data[5]};
|
||||
// lastTime = System.currentTimeMillis();
|
||||
mac = byte_String(data[19]) + byte_String(data[18]) +
|
||||
byte_String(data[17]) +
|
||||
byte_String(data[16]) +
|
||||
byte_String(data[15]) +
|
||||
byte_String(data[14]);
|
||||
String realMac = Utils.formatMac(mac, ":");
|
||||
// if (!deviceAction.containsKey(realMac)||(!Arrays.equals(deviceAction.get(realMac), new byte[]{data[4], data[5]})&&System.currentTimeMillis()-deviceTime.get(realMac)>10000)) {
|
||||
// deviceAction.put(realMac,new byte[]{data[4], data[5]});
|
||||
// deviceTime.put(realMac,System.currentTimeMillis());
|
||||
if (!deviceAction.containsKey(realMac)||!Arrays.equals(deviceAction.get(realMac), new byte[]{data[2], data[3]})){
|
||||
deviceAction.put(realMac,new byte[]{data[2], data[3]});
|
||||
int cActionDataIndex = byteArrayToInt(new byte[]{data[2], data[3]});
|
||||
int cActionIndex = byteArrayToInt(new byte[]{data[4], data[5]});
|
||||
byte[] actionData = new byte[]{data[4], data[5]};
|
||||
int power6 = byteToInt(data[6]);
|
||||
Log.i(TAG, mac + ",动作数据=" + cActionIndex + ",index="+cActionDataIndex);
|
||||
if (DataServer.INSTANCE.getNBlueToothVerifyMac().equals(Utils.formatMac(mac, ":"))) {
|
||||
if (DataServer.INSTANCE.getConnectMode() == 2) {
|
||||
//如果收到DataServer.nBlueToothVerifyMac的贴件数据,说明贴件唤醒成功
|
||||
EventBusUtil.sendEvent(new EventBusUtil.MessageEvent(EventCode.DEVICE_WAKE_UP_SUCCEED));
|
||||
}
|
||||
if(!Arrays.equals(actionData,new byte[]{0x00, 0x00})) {
|
||||
BusManager.getBus().post(new DeviceSettingEvent(new byte[]{data[4], data[5]}, mac, 6));
|
||||
}
|
||||
}
|
||||
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac, ":"));
|
||||
if (list != null && list.size() > 0) {
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
deviceInfo.setPower(power6+"");
|
||||
//贴件已绑定,才保存数据
|
||||
if(deviceInfo.isBind()){
|
||||
if(!Arrays.equals(actionData,new byte[]{0x00, 0x00})) {
|
||||
ActionInfo actionInfo = new ActionInfo();
|
||||
actionInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
actionInfo.setData(actionData);
|
||||
actionInfo.setTime(TimeUtil.INSTANCE.getNowTime());
|
||||
ObjectBoxUtils.INSTANCE.addData(actionInfo, ActionInfo.class);
|
||||
EventBusUtil.sendEvent(new EventBusUtil.MessageEvent(EventCode.PUSHDATA_NEWGET, mac));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
deviceInfo.setPower(power6+"");
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo, DeviceInfo.class);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
timeString = byte_String(data[3]) + byte_String(data[4]) + "-" +
|
||||
byte_String(data[5]) + "-" +
|
||||
byte_String(data[6]) + " " +
|
||||
byte_String(data[7]) + ":" +
|
||||
byte_String(data[8]) + ":" + byte_String(data[9]);
|
||||
mac = byte_String(data[19]) + byte_String(data[18]) +
|
||||
byte_String(data[17]) +
|
||||
byte_String(data[16]) +
|
||||
byte_String(data[15]) +
|
||||
byte_String(data[14]);
|
||||
BusManager.getBus().post(new DeviceSettingEvent(new byte[]{data[2],data[3],data[4]},mac,4));
|
||||
int type = byteToInt(data[2]);
|
||||
if(timeString!=null&&!timeString.startsWith("0000")){
|
||||
switch (type) {
|
||||
case 255:
|
||||
Log.i(TAG, mac + "模型1学习时间:" + timeString);
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac, ":"));
|
||||
if (list != null && list.size() > 0) {
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setModel1Init(true);
|
||||
deviceInfo.setModel1Time(timeString);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
} else {
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
deviceInfo.setModel1Init(true);
|
||||
deviceInfo.setModel1Time(timeString);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo, DeviceInfo.class);
|
||||
break;
|
||||
case 253:
|
||||
Log.i(TAG, mac + "模型2学习时间:" + timeString);
|
||||
list = ObjectBoxUtils.INSTANCE.getDeviceByMac(Utils.formatMac(mac, ":"));
|
||||
if (list != null && list.size() > 0) {
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setModel2Init(true);
|
||||
deviceInfo.setModel2Time(timeString);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
} else {
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(Utils.formatMac(mac, ":"));
|
||||
deviceInfo.setModel2Init(true);
|
||||
deviceInfo.setModel2Time(timeString);
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo, DeviceInfo.class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param flag
|
||||
* 1开始 0结束
|
||||
* @param type
|
||||
** 1-频率
|
||||
* * 252-算法模型2阈值
|
||||
* *253-算法模型2学习
|
||||
* *254-算法模型1阈值
|
||||
* * 255-算法模型1学习
|
||||
* @param value
|
||||
*/
|
||||
public void setParam(String mac,boolean flag, int type,int value){
|
||||
byte[] head = new byte[]{(byte) 0x90, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
if(flag){
|
||||
head[2] = 0x01;
|
||||
}else{
|
||||
head[2] = 0x00;
|
||||
}
|
||||
head[3] = int2ByteArray(type)[3];
|
||||
head[4] =int2ByteArray(value)[2];
|
||||
head[5] = int2ByteArray(value)[3];
|
||||
byte[] last = decodeHex(Utils.reverseMac(mac));
|
||||
|
||||
byte[] result = addBytes(head, last);
|
||||
write(mDevice,result,"设置参数");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param flag
|
||||
* 1开始 0结束
|
||||
* @param type
|
||||
** 1-频率
|
||||
* * 252-算法模型2阈值
|
||||
* *253-算法模型2学习
|
||||
* *254-算法模型1阈值
|
||||
* * 255-算法模型1学习
|
||||
* @param value
|
||||
*/
|
||||
public void setParamTime(String mac,boolean flag, int type,int value,Date date){
|
||||
byte[] head = new byte[]{(byte) 0x90, 0x14, 0x00, 0x00, 0x00, 0x00};
|
||||
if(flag){
|
||||
head[2] = 0x01;
|
||||
}else{
|
||||
head[2] = 0x00;
|
||||
}
|
||||
head[3] = int2ByteArray(type)[3];
|
||||
head[4] =int2ByteArray(value)[2];
|
||||
head[5] = int2ByteArray(value)[3];
|
||||
timeString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
|
||||
String timeShort = new SimpleDateFormat("yyyyMMddHHmmss").format(date);
|
||||
byte[] time = GetTempTime(timeShort);
|
||||
byte[] last = decodeHex(Utils.reverseMac(mac));
|
||||
byte[] res = addBytes(head,time);
|
||||
byte[] resul = addBytes(res,new byte[]{0x00});
|
||||
byte[] result = addBytes(resul, last);
|
||||
write(mDevice,result,"设置参数");
|
||||
}
|
||||
|
||||
/**
|
||||
*0-正常工作
|
||||
* 1-强制休眠
|
||||
* 2-开启模型1验证
|
||||
* 3-开启模型2验证
|
||||
* @param mac
|
||||
* @param flag
|
||||
* @param type
|
||||
*/
|
||||
public void setMode(String mac,boolean flag, int type){
|
||||
byte[] head = new byte[]{(byte) 0x90, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
if(flag){
|
||||
head[2] = 0x01;
|
||||
}else{
|
||||
head[2] = 0x00;
|
||||
}
|
||||
head[3] = int2ByteArray(type)[3];
|
||||
byte[] last = decodeHex(Utils.reverseMac(mac));
|
||||
|
||||
byte[] result = addBytes(head, last);
|
||||
write(mDevice,result,"设置工作模式");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type
|
||||
** 1-频率
|
||||
* *253-算法模型2学习
|
||||
* * 255-算法模型1学习
|
||||
*/
|
||||
public void getTime(String mac, int type){
|
||||
byte[] head = new byte[]{(byte) 0x90, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
head[2] = int2ByteArray(type)[3];
|
||||
byte[] last = decodeHex(Utils.reverseMac(mac));
|
||||
byte[] result = addBytes(head, last);
|
||||
write(mDevice,result,"获取模型学习时间");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.qidian.baseble.ble;
|
||||
|
||||
|
||||
import com.qidian.baseble.core.BluetoothGattChannel;
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
import com.vise.xsnow.event.IEvent;
|
||||
|
||||
public class CallbackDataEvent implements IEvent {
|
||||
private byte[] data;
|
||||
private boolean isSuccess;
|
||||
private BluetoothLeDevice bluetoothLeDevice;
|
||||
private BluetoothGattChannel bluetoothGattChannel;
|
||||
|
||||
public CallbackDataEvent setSuccess(boolean success) {
|
||||
isSuccess = success;
|
||||
return this;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public CallbackDataEvent setData(byte[] data) {
|
||||
this.data = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
public BluetoothLeDevice getBluetoothLeDevice() {
|
||||
return bluetoothLeDevice;
|
||||
}
|
||||
|
||||
public CallbackDataEvent setBluetoothLeDevice(BluetoothLeDevice bluetoothLeDevice) {
|
||||
this.bluetoothLeDevice = bluetoothLeDevice;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BluetoothGattChannel getBluetoothGattChannel() {
|
||||
return bluetoothGattChannel;
|
||||
}
|
||||
|
||||
public CallbackDataEvent setBluetoothGattChannel(BluetoothGattChannel bluetoothGattChannel) {
|
||||
this.bluetoothGattChannel = bluetoothGattChannel;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
37
app/src/main/java/com/qidian/baseble/ble/ConnectEvent.java
Normal file
37
app/src/main/java/com/qidian/baseble/ble/ConnectEvent.java
Normal file
@ -0,0 +1,37 @@
|
||||
package com.qidian.baseble.ble;
|
||||
|
||||
import com.qidian.baseble.core.DeviceMirror;
|
||||
import com.vise.xsnow.event.IEvent;
|
||||
|
||||
public class ConnectEvent implements IEvent {
|
||||
private boolean isSuccess;
|
||||
private boolean isDisconnected;
|
||||
private DeviceMirror deviceMirror;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
public ConnectEvent setSuccess(boolean success) {
|
||||
isSuccess = success;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isDisconnected() {
|
||||
return isDisconnected;
|
||||
}
|
||||
|
||||
public ConnectEvent setDisconnected(boolean disconnected) {
|
||||
isDisconnected = disconnected;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeviceMirror getDeviceMirror() {
|
||||
return deviceMirror;
|
||||
}
|
||||
|
||||
public ConnectEvent setDeviceMirror(DeviceMirror deviceMirror) {
|
||||
this.deviceMirror = deviceMirror;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.qidian.baseble.ble;
|
||||
|
||||
import com.vise.xsnow.event.IEvent;
|
||||
|
||||
public class DeviceSettingEvent implements IEvent {
|
||||
private byte[] data;
|
||||
private String mac;
|
||||
private int flag;
|
||||
|
||||
public DeviceSettingEvent() {
|
||||
}
|
||||
|
||||
public DeviceSettingEvent(byte[] data, String mac, int flag) {
|
||||
this.data = data;
|
||||
this.mac = mac;
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getMac() {
|
||||
return mac;
|
||||
}
|
||||
|
||||
public void setMac(String mac) {
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
public int getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setFlag(int flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package com.qidian.baseble.ble;
|
||||
|
||||
import com.qidian.baseble.core.BluetoothGattChannel;
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
import com.vise.xsnow.event.IEvent;
|
||||
|
||||
public class NotifyDataEvent implements IEvent {
|
||||
private byte[] data;
|
||||
private BluetoothLeDevice bluetoothLeDevice;
|
||||
private BluetoothGattChannel bluetoothGattChannel;
|
||||
public String name;
|
||||
|
||||
public NotifyDataEvent() {
|
||||
}
|
||||
|
||||
public NotifyDataEvent(String o) {
|
||||
name = o;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public NotifyDataEvent setData(byte[] data) {
|
||||
this.data = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BluetoothLeDevice getBluetoothLeDevice() {
|
||||
return bluetoothLeDevice;
|
||||
}
|
||||
|
||||
public NotifyDataEvent setBluetoothLeDevice(BluetoothLeDevice bluetoothLeDevice) {
|
||||
this.bluetoothLeDevice = bluetoothLeDevice;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BluetoothGattChannel getBluetoothGattChannel() {
|
||||
return bluetoothGattChannel;
|
||||
}
|
||||
|
||||
public NotifyDataEvent setBluetoothGattChannel(BluetoothGattChannel bluetoothGattChannel) {
|
||||
this.bluetoothGattChannel = bluetoothGattChannel;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
30
app/src/main/java/com/qidian/baseble/ble/ScanDataEvent.java
Normal file
30
app/src/main/java/com/qidian/baseble/ble/ScanDataEvent.java
Normal file
@ -0,0 +1,30 @@
|
||||
package com.qidian.baseble.ble;
|
||||
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
import com.vise.xsnow.event.IEvent;
|
||||
|
||||
public class ScanDataEvent implements IEvent {
|
||||
private byte[] data;
|
||||
private BluetoothLeDevice bluetoothLeDevice;
|
||||
|
||||
public ScanDataEvent() {
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public ScanDataEvent setData(byte[] data) {
|
||||
this.data = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BluetoothLeDevice getBluetoothLeDevice() {
|
||||
return bluetoothLeDevice;
|
||||
}
|
||||
|
||||
public ScanDataEvent setBluetoothLeDevice(BluetoothLeDevice bluetoothLeDevice) {
|
||||
this.bluetoothLeDevice = bluetoothLeDevice;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
20
app/src/main/java/com/qidian/baseble/ble/ScanDevice.java
Normal file
20
app/src/main/java/com/qidian/baseble/ble/ScanDevice.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.qidian.baseble.ble;
|
||||
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
import com.vise.xsnow.event.IEvent;
|
||||
|
||||
public class ScanDevice implements IEvent {
|
||||
private BluetoothLeDevice bluetoothLeDevice;
|
||||
|
||||
public ScanDevice() {
|
||||
}
|
||||
|
||||
public BluetoothLeDevice getBluetoothLeDevice() {
|
||||
return bluetoothLeDevice;
|
||||
}
|
||||
|
||||
public ScanDevice setBluetoothLeDevice(BluetoothLeDevice bluetoothLeDevice) {
|
||||
this.bluetoothLeDevice = bluetoothLeDevice;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
40
app/src/main/java/com/qidian/baseble/ble/ScanEvent.java
Normal file
40
app/src/main/java/com/qidian/baseble/ble/ScanEvent.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.qidian.baseble.ble;
|
||||
|
||||
import com.qidian.baseble.model.BluetoothLeDeviceStore;
|
||||
import com.vise.xsnow.event.IEvent;
|
||||
|
||||
public class ScanEvent implements IEvent {
|
||||
private boolean isScanTimeout;
|
||||
private boolean isScanFinish;
|
||||
private BluetoothLeDeviceStore bluetoothLeDeviceStore;
|
||||
|
||||
public ScanEvent() {
|
||||
}
|
||||
|
||||
public boolean isScanTimeout() {
|
||||
return isScanTimeout;
|
||||
}
|
||||
|
||||
public ScanEvent setScanTimeout(boolean scanTimeout) {
|
||||
isScanTimeout = scanTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isScanFinish() {
|
||||
return isScanFinish;
|
||||
}
|
||||
|
||||
public ScanEvent setScanFinish(boolean scanFinish) {
|
||||
isScanFinish = scanFinish;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BluetoothLeDeviceStore getBluetoothLeDeviceStore() {
|
||||
return bluetoothLeDeviceStore;
|
||||
}
|
||||
|
||||
public ScanEvent setBluetoothLeDeviceStore(BluetoothLeDeviceStore bluetoothLeDeviceStore) {
|
||||
this.bluetoothLeDeviceStore = bluetoothLeDeviceStore;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.qidian.baseble.callback;
|
||||
|
||||
import com.qidian.baseble.core.BluetoothGattChannel;
|
||||
import com.qidian.baseble.exception.BleException;
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
|
||||
/**
|
||||
* @Description: 操作数据回调
|
||||
* @author: <a href="http://xiaoyaoyou1212.360doc.com">DAWI</a>
|
||||
* @date: 2017/10/17 19:42
|
||||
*/
|
||||
public interface IBleCallback {
|
||||
void onSuccess(byte[] data, BluetoothGattChannel bluetoothGattChannel, BluetoothLeDevice bluetoothLeDevice);
|
||||
|
||||
void onFailure(BleException exception);
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.qidian.baseble.callback;
|
||||
|
||||
import com.qidian.baseble.core.DeviceMirror;
|
||||
import com.qidian.baseble.exception.BleException;
|
||||
|
||||
/**
|
||||
* @Description: 连接设备回调
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/8/1 23:00.
|
||||
*/
|
||||
public interface IConnectCallback {
|
||||
//连接成功
|
||||
void onConnectSuccess(DeviceMirror deviceMirror);
|
||||
|
||||
//连接失败
|
||||
void onConnectFailure(BleException exception);
|
||||
|
||||
//连接断开
|
||||
void onDisconnect(boolean isActive);
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.qidian.baseble.callback;
|
||||
|
||||
import com.qidian.baseble.exception.BleException;
|
||||
|
||||
/**
|
||||
* @Description: 获取信号值回调
|
||||
* @author: <a href="http://xiaoyaoyou1212.360doc.com">DAWI</a>
|
||||
* @date: 2017/10/19 15:19
|
||||
*/
|
||||
public interface IRssiCallback {
|
||||
void onSuccess(int rssi);
|
||||
|
||||
void onFailure(BleException exception);
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.qidian.baseble.callback.scan;
|
||||
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
import com.qidian.baseble.model.BluetoothLeDeviceStore;
|
||||
|
||||
/**
|
||||
* @Description: 扫描回调
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/9/10 18:14.
|
||||
*/
|
||||
public interface IScanCallback {
|
||||
//发现设备
|
||||
void onDeviceFound(BluetoothLeDevice bluetoothLeDevice);
|
||||
|
||||
//扫描完成
|
||||
void onScanFinish(BluetoothLeDeviceStore bluetoothLeDeviceStore);
|
||||
|
||||
//扫描超时
|
||||
void onScanTimeout();
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.qidian.baseble.callback.scan;
|
||||
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
|
||||
/**
|
||||
* @Description: 扫描过滤接口,根据需要实现过滤规则
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/9/10 18:19.
|
||||
*/
|
||||
public interface IScanFilter {
|
||||
BluetoothLeDevice onFilter(BluetoothLeDevice bluetoothLeDevice);
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.qidian.baseble.callback.scan;
|
||||
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 指定设备集合进行过滤,一般用设备名称和Mac地址集合
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/9/12 22:50.
|
||||
*/
|
||||
public class ListFilterScanCallback extends ScanCallback {
|
||||
private List<String> deviceNameList;//指定设备名称集合
|
||||
private List<String> deviceMacList;//指定设备Mac地址集合
|
||||
|
||||
public ListFilterScanCallback(IScanCallback scanCallback) {
|
||||
super(scanCallback);
|
||||
}
|
||||
|
||||
public ListFilterScanCallback setDeviceNameList(List<String> deviceNameList) {
|
||||
this.deviceNameList = deviceNameList;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ListFilterScanCallback setDeviceMacList(List<String> deviceMacList) {
|
||||
this.deviceMacList = deviceMacList;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluetoothLeDevice onFilter(BluetoothLeDevice bluetoothLeDevice) {
|
||||
BluetoothLeDevice tempDevice = null;
|
||||
if (deviceNameList != null && deviceNameList.size() > 0) {
|
||||
for (String deviceName : deviceNameList) {
|
||||
if (bluetoothLeDevice != null && bluetoothLeDevice.getName() != null && deviceName != null
|
||||
&& deviceName.equalsIgnoreCase(bluetoothLeDevice.getName().trim())) {
|
||||
tempDevice = bluetoothLeDevice;
|
||||
}
|
||||
}
|
||||
} else if (deviceMacList != null && deviceMacList.size() > 0) {
|
||||
for (String deviceMac : deviceMacList) {
|
||||
if (bluetoothLeDevice != null && bluetoothLeDevice.getAddress() != null && deviceMac != null
|
||||
&& deviceMac.equalsIgnoreCase(bluetoothLeDevice.getAddress().trim())) {
|
||||
tempDevice = bluetoothLeDevice;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempDevice;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package com.qidian.baseble.callback.scan;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Description: 根据正则过滤扫描设备,这里设置的是根据一定信号范围内指定正则设备名称的过滤
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/9/12 22:19.
|
||||
*/
|
||||
public class RegularFilterScanCallback extends ScanCallback {
|
||||
private Pattern pattern;
|
||||
private Matcher matcher;
|
||||
private String regularDeviceName;//正则表达式表示的设备名称
|
||||
private int deviceRssi;//设备的信号
|
||||
|
||||
public RegularFilterScanCallback(IScanCallback scanCallback) {
|
||||
super(scanCallback);
|
||||
pattern = Pattern.compile("^[\\x00-\\xff]*$");
|
||||
}
|
||||
|
||||
public RegularFilterScanCallback setRegularDeviceName(String regularDeviceName) {
|
||||
this.regularDeviceName = regularDeviceName;
|
||||
if (!TextUtils.isEmpty(this.regularDeviceName)) {
|
||||
pattern = Pattern.compile(this.regularDeviceName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RegularFilterScanCallback setDeviceRssi(int deviceRssi) {
|
||||
this.deviceRssi = deviceRssi;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluetoothLeDevice onFilter(BluetoothLeDevice bluetoothLeDevice) {
|
||||
BluetoothLeDevice tempDevice = null;
|
||||
String tempName = bluetoothLeDevice.getName();
|
||||
int tempRssi = bluetoothLeDevice.getRssi();
|
||||
if (!TextUtils.isEmpty(tempName)) {
|
||||
matcher = pattern.matcher(tempName);
|
||||
if (this.deviceRssi < 0) {
|
||||
if (matcher.matches() && tempRssi >= this.deviceRssi) {
|
||||
tempDevice = bluetoothLeDevice;
|
||||
}
|
||||
} else {
|
||||
if (matcher.matches()) {
|
||||
tempDevice = bluetoothLeDevice;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempDevice;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,203 @@
|
||||
package com.qidian.baseble.callback.scan;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.qidian.baseble.ViseBle;
|
||||
import com.qidian.baseble.common.BleConfig;
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
import com.qidian.baseble.model.BluetoothLeDeviceStore;
|
||||
import com.qidian.baseble.utils.HexUtil;
|
||||
import com.qidian.zhongkesmart.config.EventCode;
|
||||
import com.qidian.zhongkesmart.model.ActionInfo;
|
||||
import com.qidian.zhongkesmart.model.DeviceInfo;
|
||||
import com.qidian.zhongkesmart.utils.DataServer;
|
||||
import com.qidian.zhongkesmart.utils.EventBusUtil;
|
||||
import com.qidian.zhongkesmart.utils.ObjectBoxUtils;
|
||||
import com.qidian.zhongkesmart.utils.TimeUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.qidian.baseble.utils.HexUtil.byteArrayToInt;
|
||||
import static com.qidian.baseble.utils.HexUtil.byteToInt;
|
||||
|
||||
/**
|
||||
* @Description: 扫描设备回调
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/8/1 22:58.
|
||||
*/
|
||||
public class ScanCallback implements BluetoothAdapter.LeScanCallback, IScanFilter {
|
||||
protected Handler handler = new Handler(Looper.myLooper());
|
||||
protected boolean isScan = true;//是否开始扫描
|
||||
protected boolean isScanning = false;//是否正在扫描
|
||||
protected BluetoothLeDeviceStore bluetoothLeDeviceStore;//用来存储扫描到的设备
|
||||
protected IScanCallback scanCallback;//扫描结果回调
|
||||
private Map<String, byte[]> deviceAction = new HashMap<>();
|
||||
|
||||
public ScanCallback(IScanCallback scanCallback) {
|
||||
this.scanCallback = scanCallback;
|
||||
if (scanCallback == null) {
|
||||
throw new NullPointerException("this scanCallback is null!");
|
||||
}
|
||||
bluetoothLeDeviceStore = new BluetoothLeDeviceStore();
|
||||
}
|
||||
|
||||
public ScanCallback setScan(boolean scan) {
|
||||
isScan = scan;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isScanning() {
|
||||
return isScanning;
|
||||
}
|
||||
|
||||
public void scan() {
|
||||
if (isScan) {
|
||||
if (isScanning) {
|
||||
return;
|
||||
}
|
||||
Log.i("BlueTooth==","开始扫描");
|
||||
bluetoothLeDeviceStore.clear();
|
||||
if (BleConfig.getInstance().getScanTimeout() > 0) {
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
isScanning = false;
|
||||
|
||||
if (ViseBle.getInstance().getBluetoothAdapter() != null) {
|
||||
ViseBle.getInstance().getBluetoothAdapter().stopLeScan(ScanCallback.this);
|
||||
}
|
||||
|
||||
if (bluetoothLeDeviceStore.getDeviceMap() != null
|
||||
&& bluetoothLeDeviceStore.getDeviceMap().size() > 0) {
|
||||
scanCallback.onScanFinish(bluetoothLeDeviceStore);
|
||||
} else {
|
||||
scanCallback.onScanTimeout();
|
||||
}
|
||||
}
|
||||
}, BleConfig.getInstance().getScanTimeout());
|
||||
}else if (BleConfig.getInstance().getScanRepeatInterval() > 0){
|
||||
//如果超时时间设置为一直扫描(即 <= 0),则判断是否设置重复扫描间隔
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
isScanning = false;
|
||||
if (ViseBle.getInstance().getBluetoothAdapter() != null) {
|
||||
ViseBle.getInstance().getBluetoothAdapter().stopLeScan(ScanCallback.this);
|
||||
}
|
||||
|
||||
// if (bluetoothLeDeviceStore.getDeviceMap() != null
|
||||
// && bluetoothLeDeviceStore.getDeviceMap().size() > 0) {
|
||||
// scanCallback.onScanFinish(bluetoothLeDeviceStore);
|
||||
// } else {
|
||||
// scanCallback.onScanTimeout();
|
||||
// }
|
||||
isScanning = true;
|
||||
if (ViseBle.getInstance().getBluetoothAdapter() != null) {
|
||||
ViseBle.getInstance().getBluetoothAdapter().startLeScan(ScanCallback.this);
|
||||
}
|
||||
handler.postDelayed(this,BleConfig.getInstance().getScanRepeatInterval());
|
||||
}
|
||||
}, BleConfig.getInstance().getScanRepeatInterval());
|
||||
}
|
||||
isScanning = true;
|
||||
if (ViseBle.getInstance().getBluetoothAdapter() != null) {
|
||||
ViseBle.getInstance().getBluetoothAdapter().startLeScan(ScanCallback.this);
|
||||
}
|
||||
} else {
|
||||
isScanning = false;
|
||||
if (ViseBle.getInstance().getBluetoothAdapter() != null) {
|
||||
Log.i("BlueTooth==","结束扫描");
|
||||
ViseBle.getInstance().getBluetoothAdapter().stopLeScan(ScanCallback.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ScanCallback removeHandlerMsg() {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
bluetoothLeDeviceStore.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeScan(BluetoothDevice bluetoothDevice, int rssi, byte[] scanRecord) {
|
||||
BluetoothLeDevice bluetoothLeDevice = new BluetoothLeDevice(bluetoothDevice, rssi, scanRecord, System.currentTimeMillis());
|
||||
BluetoothLeDevice filterDevice = onFilter(bluetoothLeDevice);
|
||||
if (filterDevice != null) {
|
||||
if (DataServer.INSTANCE.getConnectMode() == 1) {
|
||||
if (filterDevice.getName() != null && filterDevice.getName().startsWith("TJ")) {
|
||||
bluetoothLeDeviceStore.addDevice(filterDevice);
|
||||
scanCallback.onDeviceFound(filterDevice);
|
||||
// Log.i(
|
||||
// "BlueTooth==",
|
||||
// "广播包数据" + HexUtil.encodeHexStr(scanRecord));
|
||||
if (scanRecord.length > 21 && scanRecord[15] == (byte) 0x90 && scanRecord[16] == (byte) 0x07) {
|
||||
byte[] scanResult = new byte[9];
|
||||
System.arraycopy(scanRecord, 15, scanResult, 0, 9);
|
||||
//同一个设备,不同的动作
|
||||
//if (!deviceAction.containsKey(bluetoothDevice.getAddress())||(!Arrays.equals(deviceAction.get(bluetoothDevice.getAddress()), new byte[]{scanResult[7], scanResult[8]})&&System.currentTimeMillis()-deviceTime.get(bluetoothDevice.getAddress())>10000)) {
|
||||
//deviceTime.put(bluetoothDevice.getAddress(),System.currentTimeMillis());
|
||||
|
||||
|
||||
if (!deviceAction.containsKey(bluetoothDevice.getAddress())||!Arrays.equals(deviceAction.get(bluetoothDevice.getAddress()), new byte[]{scanResult[2], scanResult[3]})){
|
||||
deviceAction.put(bluetoothDevice.getAddress(),new byte[]{scanResult[2], scanResult[3]});
|
||||
int power = byteToInt(scanResult[6]);
|
||||
int cActionDataIndex = byteArrayToInt(new byte[]{scanResult[2], scanResult[3]});
|
||||
Log.i(
|
||||
"BlueTooth==",
|
||||
bluetoothDevice.getAddress()+"的广播包数据" + HexUtil.encodeHexStr(scanResult)+ " index="+cActionDataIndex);
|
||||
List<DeviceInfo> list = ObjectBoxUtils.INSTANCE.getDeviceByMac(bluetoothDevice.getAddress());
|
||||
DeviceInfo deviceInfo;
|
||||
if (list != null && list.size() > 0) {
|
||||
deviceInfo = list.get(0);
|
||||
deviceInfo.setPower(power + "");
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
//贴件已绑定,才保存数据
|
||||
if (deviceInfo.isBind()) {
|
||||
byte[] actionData = new byte[]{scanResult[7], scanResult[8]};
|
||||
if (!Arrays.equals(actionData, new byte[]{0x00, 0x00})) {
|
||||
ActionInfo actionInfo = new ActionInfo();
|
||||
actionInfo.setMac(bluetoothDevice.getAddress());
|
||||
actionInfo.setData(actionData);
|
||||
actionInfo.setTime(TimeUtil.INSTANCE.getNowTime());
|
||||
ObjectBoxUtils.INSTANCE.addData(actionInfo, ActionInfo.class);
|
||||
EventBusUtil.sendEvent(new EventBusUtil.MessageEvent(EventCode.PUSHDATA_NEWGET, bluetoothDevice.getAddress()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo.setMac(bluetoothDevice.getAddress());
|
||||
deviceInfo.setPower(power + "");
|
||||
deviceInfo.setOnline(true);
|
||||
deviceInfo.setUpdateTime(TimeUtil.INSTANCE.getNowTime());
|
||||
}
|
||||
ObjectBoxUtils.INSTANCE.updateData(deviceInfo, DeviceInfo.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (filterDevice.getName() != null && filterDevice.getName().startsWith("ZJ")) {
|
||||
bluetoothLeDeviceStore.addDevice(filterDevice);
|
||||
scanCallback.onDeviceFound(filterDevice);
|
||||
Log.i(
|
||||
"BlueTooth==",
|
||||
"periodScanCallback:发现设备" + filterDevice.getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluetoothLeDevice onFilter(BluetoothLeDevice bluetoothLeDevice) {
|
||||
return bluetoothLeDevice;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package com.qidian.baseble.callback.scan;
|
||||
|
||||
import com.qidian.baseble.ViseBle;
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* @Description: 设置扫描指定的单个设备,一般是设备名称和Mac地址
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/9/12 22:16.
|
||||
*/
|
||||
public class SingleFilterScanCallback extends ScanCallback {
|
||||
private AtomicBoolean hasFound = new AtomicBoolean(false);
|
||||
private String deviceName;//指定设备名称
|
||||
private String deviceMac;//指定设备Mac地址
|
||||
|
||||
public SingleFilterScanCallback(IScanCallback scanCallback) {
|
||||
super(scanCallback);
|
||||
}
|
||||
|
||||
public ScanCallback setDeviceName(String deviceName) {
|
||||
this.deviceName = deviceName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SingleFilterScanCallback setDeviceMac(String deviceMac) {
|
||||
this.deviceMac = deviceMac;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluetoothLeDevice onFilter(BluetoothLeDevice bluetoothLeDevice) {
|
||||
BluetoothLeDevice tempDevice = null;
|
||||
if (!hasFound.get()) {
|
||||
if (bluetoothLeDevice != null && bluetoothLeDevice.getAddress() != null && deviceMac != null
|
||||
&& deviceMac.equalsIgnoreCase(bluetoothLeDevice.getAddress().trim())) {
|
||||
hasFound.set(true);
|
||||
isScanning = false;
|
||||
removeHandlerMsg();
|
||||
ViseBle.getInstance().stopScan(SingleFilterScanCallback.this);
|
||||
tempDevice = bluetoothLeDevice;
|
||||
bluetoothLeDeviceStore.addDevice(bluetoothLeDevice);
|
||||
scanCallback.onScanFinish(bluetoothLeDeviceStore);
|
||||
} else if (bluetoothLeDevice != null && bluetoothLeDevice.getName() != null && deviceName != null
|
||||
&& deviceName.equalsIgnoreCase(bluetoothLeDevice.getName().trim())) {
|
||||
hasFound.set(true);
|
||||
isScanning = false;
|
||||
removeHandlerMsg();
|
||||
ViseBle.getInstance().stopScan(SingleFilterScanCallback.this);
|
||||
tempDevice = bluetoothLeDevice;
|
||||
bluetoothLeDeviceStore.addDevice(bluetoothLeDevice);
|
||||
scanCallback.onScanFinish(bluetoothLeDeviceStore);
|
||||
}
|
||||
}
|
||||
return tempDevice;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.qidian.baseble.callback.scan;
|
||||
|
||||
import android.os.ParcelUuid;
|
||||
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @Description: 根据指定uuid过滤设备
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/9/12 23:20.
|
||||
*/
|
||||
public class UuidFilterScanCallback extends ScanCallback {
|
||||
private UUID uuid;//设备uuid
|
||||
|
||||
public UuidFilterScanCallback(IScanCallback scanCallback) {
|
||||
super(scanCallback);
|
||||
}
|
||||
|
||||
public UuidFilterScanCallback setUuid(String uuid) {
|
||||
this.uuid = UUID.fromString(uuid);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UuidFilterScanCallback setUuid(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluetoothLeDevice onFilter(BluetoothLeDevice bluetoothLeDevice) {
|
||||
BluetoothLeDevice tempDevice = null;
|
||||
if (bluetoothLeDevice != null && bluetoothLeDevice.getDevice() != null
|
||||
&& bluetoothLeDevice.getDevice().getUuids() != null
|
||||
&& bluetoothLeDevice.getDevice().getUuids().length > 0) {
|
||||
for (ParcelUuid parcelUuid : bluetoothLeDevice.getDevice().getUuids()) {
|
||||
if (uuid != null && uuid == parcelUuid.getUuid()) {
|
||||
tempDevice = bluetoothLeDevice;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempDevice;
|
||||
}
|
||||
}
|
||||
223
app/src/main/java/com/qidian/baseble/common/BleConfig.java
Normal file
223
app/src/main/java/com/qidian/baseble/common/BleConfig.java
Normal file
@ -0,0 +1,223 @@
|
||||
package com.qidian.baseble.common;
|
||||
|
||||
import static com.qidian.baseble.common.BleConstant.DEFAULT_CONN_TIME;
|
||||
import static com.qidian.baseble.common.BleConstant.DEFAULT_MAX_CONNECT_COUNT;
|
||||
import static com.qidian.baseble.common.BleConstant.DEFAULT_OPERATE_TIME;
|
||||
import static com.qidian.baseble.common.BleConstant.DEFAULT_RETRY_COUNT;
|
||||
import static com.qidian.baseble.common.BleConstant.DEFAULT_RETRY_INTERVAL;
|
||||
import static com.qidian.baseble.common.BleConstant.DEFAULT_SCAN_REPEAT_INTERVAL;
|
||||
import static com.qidian.baseble.common.BleConstant.DEFAULT_SCAN_TIME;
|
||||
|
||||
/**
|
||||
* @Description: 蓝牙通信相关配置
|
||||
* @author: <a href="http://xiaoyaoyou1212.360doc.com">DAWI</a>
|
||||
* @date: 2017/10/16 11:46
|
||||
*/
|
||||
public class BleConfig {
|
||||
private static BleConfig instance;
|
||||
|
||||
private int scanTimeout = DEFAULT_SCAN_TIME;//扫描超时时间(毫秒)
|
||||
private int connectTimeout = DEFAULT_CONN_TIME;//连接超时时间(毫秒)
|
||||
private int operateTimeout = DEFAULT_OPERATE_TIME;//数据操作超时时间(毫秒)
|
||||
private int connectRetryCount = DEFAULT_RETRY_COUNT;//连接重试次数
|
||||
private int connectRetryInterval = DEFAULT_RETRY_INTERVAL;//连接重试间隔(毫秒)
|
||||
private int operateRetryCount = DEFAULT_RETRY_COUNT;//数据操作重试次数
|
||||
private int operateRetryInterval = DEFAULT_RETRY_INTERVAL;//数据操作重试间隔时间(毫秒)
|
||||
private int maxConnectCount = DEFAULT_MAX_CONNECT_COUNT;//最大连接数量
|
||||
|
||||
//yankee
|
||||
private int scanRepeatInterval = DEFAULT_SCAN_REPEAT_INTERVAL;//每隔X时间重复扫描 (毫秒)
|
||||
|
||||
private BleConfig() {
|
||||
}
|
||||
|
||||
public static BleConfig getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (BleConfig.class) {
|
||||
if (instance == null) {
|
||||
instance = new BleConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发送数据超时时间
|
||||
*
|
||||
* @return 返回发送数据超时时间
|
||||
*/
|
||||
public int getOperateTimeout() {
|
||||
return operateTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置发送数据超时时间
|
||||
*
|
||||
* @param operateTimeout 发送数据超时时间
|
||||
* @return 返回ViseBle
|
||||
*/
|
||||
public BleConfig setOperateTimeout(int operateTimeout) {
|
||||
this.operateTimeout = operateTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接超时时间
|
||||
*
|
||||
* @return 返回连接超时时间
|
||||
*/
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置连接超时时间
|
||||
*
|
||||
* @param connectTimeout 连接超时时间
|
||||
* @return 返回ViseBle
|
||||
*/
|
||||
public BleConfig setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扫描超时时间
|
||||
*
|
||||
* @return 返回扫描超时时间
|
||||
*/
|
||||
public int getScanTimeout() {
|
||||
return scanTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置扫描超时时间
|
||||
*
|
||||
* @param scanTimeout 扫描超时时间
|
||||
* @return 返回ViseBle
|
||||
*/
|
||||
public BleConfig setScanTimeout(int scanTimeout) {
|
||||
this.scanTimeout = scanTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接重试次数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getConnectRetryCount() {
|
||||
return connectRetryCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置连接重试次数
|
||||
*
|
||||
* @param connectRetryCount
|
||||
* @return
|
||||
*/
|
||||
public BleConfig setConnectRetryCount(int connectRetryCount) {
|
||||
this.connectRetryCount = connectRetryCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接重试间隔时间
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getConnectRetryInterval() {
|
||||
return connectRetryInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置连接重试间隔时间
|
||||
*
|
||||
* @param connectRetryInterval
|
||||
* @return
|
||||
*/
|
||||
public BleConfig setConnectRetryInterval(int connectRetryInterval) {
|
||||
this.connectRetryInterval = connectRetryInterval;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最大连接数量
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getMaxConnectCount() {
|
||||
return maxConnectCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最大连接数量
|
||||
*
|
||||
* @param maxConnectCount
|
||||
* @return
|
||||
*/
|
||||
public BleConfig setMaxConnectCount(int maxConnectCount) {
|
||||
this.maxConnectCount = maxConnectCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取操作数据重试次数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getOperateRetryCount() {
|
||||
return operateRetryCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置操作数据重试次数
|
||||
*
|
||||
* @param operateRetryCount
|
||||
* @return
|
||||
*/
|
||||
public BleConfig setOperateRetryCount(int operateRetryCount) {
|
||||
this.operateRetryCount = operateRetryCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取操作数据重试间隔时间
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getOperateRetryInterval() {
|
||||
return operateRetryInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置操作数据重试间隔时间
|
||||
*
|
||||
* @param operateRetryInterval
|
||||
* @return
|
||||
*/
|
||||
public BleConfig setOperateRetryInterval(int operateRetryInterval) {
|
||||
this.operateRetryInterval = operateRetryInterval;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扫描间隔时间
|
||||
* @return
|
||||
*/
|
||||
public int getScanRepeatInterval() {
|
||||
return scanRepeatInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置每隔多少时间重复扫描一次
|
||||
* 设置扫描间隔时间 (毫秒)
|
||||
* @param scanRepeatInterval
|
||||
* @return
|
||||
*/
|
||||
public BleConfig setScanRepeatInterval(int scanRepeatInterval) {
|
||||
this.scanRepeatInterval = scanRepeatInterval;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
34
app/src/main/java/com/qidian/baseble/common/BleConstant.java
Normal file
34
app/src/main/java/com/qidian/baseble/common/BleConstant.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.qidian.baseble.common;
|
||||
|
||||
/**
|
||||
* @Description: BLE常量
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/20 20:31.
|
||||
*/
|
||||
public class BleConstant {
|
||||
public static final String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
|
||||
|
||||
public static final int TIME_FOREVER = -1;
|
||||
|
||||
// public static final int DEFAULT_SCAN_TIME = 20000;//之前的数值
|
||||
public static final int DEFAULT_SCAN_TIME = 25000;
|
||||
public static final int DEFAULT_CONN_TIME = 10000;
|
||||
public static final int DEFAULT_OPERATE_TIME = 5000;
|
||||
|
||||
public static final int DEFAULT_RETRY_INTERVAL = 1000;
|
||||
public static final int DEFAULT_RETRY_COUNT = 3;
|
||||
|
||||
public static final int DEFAULT_MAX_CONNECT_COUNT = 5;
|
||||
|
||||
public static final int MSG_CONNECT_TIMEOUT = 0x01;
|
||||
public static final int MSG_WRITE_DATA_TIMEOUT = 0x02;
|
||||
public static final int MSG_READ_DATA_TIMEOUT = 0x03;
|
||||
public static final int MSG_RECEIVE_DATA_TIMEOUT = 0x04;
|
||||
public static final int MSG_CONNECT_RETRY = 0x05;
|
||||
public static final int MSG_WRITE_DATA_RETRY = 0x06;
|
||||
public static final int MSG_READ_DATA_RETRY = 0x07;
|
||||
public static final int MSG_RECEIVE_DATA_RETRY = 0x08;
|
||||
|
||||
//yankee
|
||||
public static final int DEFAULT_SCAN_REPEAT_INTERVAL = -1;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.qidian.baseble.common;
|
||||
|
||||
/**
|
||||
* @Description: BLE异常Code
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:43.
|
||||
*/
|
||||
public enum BleExceptionCode {
|
||||
TIMEOUT, //超时
|
||||
CONNECT_ERR, //连接异常
|
||||
GATT_ERR, //GATT异常
|
||||
INITIATED_ERR, //初始化异常
|
||||
OTHER_ERR //其他异常
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.qidian.baseble.common;
|
||||
|
||||
import android.bluetooth.BluetoothClass;
|
||||
|
||||
/**
|
||||
* @Description: BLE服务类型
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/7 22:07.
|
||||
*/
|
||||
public enum BluetoothServiceType {
|
||||
AUDIO(BluetoothClass.Service.AUDIO), //音频服务
|
||||
CAPTURE(BluetoothClass.Service.CAPTURE), //捕捉服务
|
||||
INFORMATION(BluetoothClass.Service.INFORMATION), //信息服务
|
||||
LIMITED_DISCOVERABILITY(BluetoothClass.Service.LIMITED_DISCOVERABILITY), //有限发现服务
|
||||
NETWORKING(BluetoothClass.Service.NETWORKING), //网络服务
|
||||
OBJECT_TRANSFER(BluetoothClass.Service.OBJECT_TRANSFER), //对象传输服务
|
||||
POSITIONING(BluetoothClass.Service.POSITIONING), //定位服务
|
||||
RENDER(BluetoothClass.Service.RENDER), //给予服务
|
||||
TELEPHONY(BluetoothClass.Service.TELEPHONY); //电话服务
|
||||
|
||||
private int code;
|
||||
|
||||
BluetoothServiceType(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return this.code;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.qidian.baseble.common;
|
||||
|
||||
/**
|
||||
* @Description: 状态描述
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/20 17:06.
|
||||
*/
|
||||
public enum ConnectState {
|
||||
CONNECT_INIT(-1), //连接初始化
|
||||
CONNECT_PROCESS(0x00), //连接中
|
||||
CONNECT_SUCCESS(0x01), //连接成功
|
||||
CONNECT_FAILURE(0x02), //连接失败
|
||||
CONNECT_TIMEOUT(0x03), //连接超时
|
||||
CONNECT_DISCONNECT(0x04); //连接断开
|
||||
|
||||
private int code;
|
||||
|
||||
ConnectState(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.qidian.baseble.common;
|
||||
|
||||
/**
|
||||
* @Description: 属性类型
|
||||
* @author: <a href="http://xiaoyaoyou1212.360doc.com">DAWI</a>
|
||||
* @date: 2017/10/17 20:27
|
||||
*/
|
||||
public enum PropertyType {
|
||||
PROPERTY_READ(0x01),
|
||||
PROPERTY_WRITE(0x02),
|
||||
PROPERTY_NOTIFY(0x04),
|
||||
PROPERTY_INDICATE(0x08);
|
||||
|
||||
private int propertyValue;
|
||||
|
||||
PropertyType(int propertyValue) {
|
||||
this.propertyValue = propertyValue;
|
||||
}
|
||||
|
||||
public int getPropertyValue() {
|
||||
return propertyValue;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
package com.qidian.baseble.core;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
|
||||
import com.qidian.baseble.common.PropertyType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @Description: BluetoothGatt 相关信息
|
||||
* @author: <a href="http://xiaoyaoyou1212.360doc.com">DAWI</a>
|
||||
* @date: 2017/10/17 16:25
|
||||
*/
|
||||
public class BluetoothGattChannel {
|
||||
|
||||
private BluetoothGatt bluetoothGatt;
|
||||
private BluetoothGattService service;
|
||||
private BluetoothGattCharacteristic characteristic;
|
||||
private BluetoothGattDescriptor descriptor;
|
||||
private String gattInfoKey;
|
||||
private PropertyType propertyType;
|
||||
private UUID serviceUUID;
|
||||
private UUID characteristicUUID;
|
||||
private UUID descriptorUUID;
|
||||
|
||||
private BluetoothGattChannel(BluetoothGatt bluetoothGatt, PropertyType propertyType, UUID serviceUUID, UUID characteristicUUID, UUID descriptorUUID) {
|
||||
this.bluetoothGatt = bluetoothGatt;
|
||||
this.propertyType = propertyType;
|
||||
this.serviceUUID = serviceUUID;
|
||||
this.characteristicUUID = characteristicUUID;
|
||||
this.descriptorUUID = descriptorUUID;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (propertyType != null) {
|
||||
stringBuilder.append(propertyType.getPropertyValue());
|
||||
}
|
||||
if (serviceUUID != null && bluetoothGatt != null) {
|
||||
service = bluetoothGatt.getService(serviceUUID);
|
||||
stringBuilder.append(serviceUUID.toString());
|
||||
}
|
||||
if (service != null && characteristicUUID != null) {
|
||||
characteristic = service.getCharacteristic(characteristicUUID);
|
||||
stringBuilder.append(characteristicUUID.toString());
|
||||
}
|
||||
if (characteristic != null && descriptorUUID != null) {
|
||||
descriptor = characteristic.getDescriptor(descriptorUUID);
|
||||
stringBuilder.append(descriptorUUID.toString());
|
||||
}
|
||||
gattInfoKey = stringBuilder.toString();
|
||||
}
|
||||
|
||||
public BluetoothGatt getBluetoothGatt() {
|
||||
return bluetoothGatt;
|
||||
}
|
||||
|
||||
public BluetoothGattCharacteristic getCharacteristic() {
|
||||
return characteristic;
|
||||
}
|
||||
|
||||
public void setCharacteristic(BluetoothGattCharacteristic bGCharacteristic) {
|
||||
this.characteristic = bGCharacteristic;
|
||||
}
|
||||
|
||||
public BluetoothGattDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public BluetoothGattService getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public BluetoothGattChannel setDescriptor(BluetoothGattDescriptor descriptor) {
|
||||
this.descriptor = descriptor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getGattInfoKey() {
|
||||
return gattInfoKey;
|
||||
}
|
||||
|
||||
public UUID getCharacteristicUUID() {
|
||||
return characteristicUUID;
|
||||
}
|
||||
|
||||
public UUID getDescriptorUUID() {
|
||||
return descriptorUUID;
|
||||
}
|
||||
|
||||
public PropertyType getPropertyType() {
|
||||
return propertyType;
|
||||
}
|
||||
|
||||
public UUID getServiceUUID() {
|
||||
return serviceUUID;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private BluetoothGatt bluetoothGatt;
|
||||
private PropertyType propertyType;
|
||||
private UUID serviceUUID;
|
||||
private UUID characteristicUUID;
|
||||
private UUID descriptorUUID;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
public Builder setBluetoothGatt(BluetoothGatt bluetoothGatt) {
|
||||
this.bluetoothGatt = bluetoothGatt;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCharacteristicUUID(UUID characteristicUUID) {
|
||||
this.characteristicUUID = characteristicUUID;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDescriptorUUID(UUID descriptorUUID) {
|
||||
this.descriptorUUID = descriptorUUID;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPropertyType(PropertyType propertyType) {
|
||||
this.propertyType = propertyType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setServiceUUID(UUID serviceUUID) {
|
||||
this.serviceUUID = serviceUUID;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BluetoothGattChannel builder() {
|
||||
return new BluetoothGattChannel(bluetoothGatt, propertyType, serviceUUID, characteristicUUID, descriptorUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
1046
app/src/main/java/com/qidian/baseble/core/DeviceMirror.java
Normal file
1046
app/src/main/java/com/qidian/baseble/core/DeviceMirror.java
Normal file
File diff suppressed because it is too large
Load Diff
227
app/src/main/java/com/qidian/baseble/core/DeviceMirrorPool.java
Normal file
227
app/src/main/java/com/qidian/baseble/core/DeviceMirrorPool.java
Normal file
@ -0,0 +1,227 @@
|
||||
package com.qidian.baseble.core;
|
||||
|
||||
import com.qidian.baseble.common.BleConfig;
|
||||
import com.qidian.baseble.common.ConnectState;
|
||||
import com.qidian.baseble.model.BluetoothLeDevice;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 设备镜像池,用来管理多个设备连接后的操作
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 17/8/1 23:18.
|
||||
*/
|
||||
public class DeviceMirrorPool {
|
||||
private final LruHashMap<String, DeviceMirror> DEVICE_MIRROR_MAP;
|
||||
|
||||
public DeviceMirrorPool() {
|
||||
DEVICE_MIRROR_MAP = new LruHashMap<>(BleConfig.getInstance().getMaxConnectCount());
|
||||
}
|
||||
|
||||
public DeviceMirrorPool(int deviceMirrorSize) {
|
||||
DEVICE_MIRROR_MAP = new LruHashMap<>(deviceMirrorSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加设备镜像
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
*/
|
||||
public synchronized void addDeviceMirror(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (bluetoothLeDevice == null) {
|
||||
return;
|
||||
}
|
||||
String key = bluetoothLeDevice.getAddress() + bluetoothLeDevice.getName();
|
||||
if (!DEVICE_MIRROR_MAP.containsKey(key)) {
|
||||
DEVICE_MIRROR_MAP.put(key, new DeviceMirror(bluetoothLeDevice));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加设备镜像
|
||||
*
|
||||
* @param deviceMirror
|
||||
*/
|
||||
public synchronized void addDeviceMirror(DeviceMirror deviceMirror) {
|
||||
if (deviceMirror == null) {
|
||||
return;
|
||||
}
|
||||
if (!DEVICE_MIRROR_MAP.containsKey(deviceMirror.getUniqueSymbol())) {
|
||||
DEVICE_MIRROR_MAP.put(deviceMirror.getUniqueSymbol(), deviceMirror);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除设备镜像
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
*/
|
||||
public synchronized void removeDeviceMirror(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (bluetoothLeDevice == null) {
|
||||
return;
|
||||
}
|
||||
String key = bluetoothLeDevice.getAddress() + bluetoothLeDevice.getName();
|
||||
if (DEVICE_MIRROR_MAP.containsKey(key)) {
|
||||
DEVICE_MIRROR_MAP.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除设备镜像
|
||||
*
|
||||
* @param deviceMirror
|
||||
*/
|
||||
public synchronized void removeDeviceMirror(DeviceMirror deviceMirror) {
|
||||
if (deviceMirror == null) {
|
||||
return;
|
||||
}
|
||||
if (DEVICE_MIRROR_MAP.containsKey(deviceMirror.getUniqueSymbol())) {
|
||||
deviceMirror.clear();
|
||||
DEVICE_MIRROR_MAP.remove(deviceMirror.getUniqueSymbol());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否包含设备镜像
|
||||
*
|
||||
* @param deviceMirror
|
||||
* @return
|
||||
*/
|
||||
public synchronized boolean isContainDevice(DeviceMirror deviceMirror) {
|
||||
if (deviceMirror == null || !DEVICE_MIRROR_MAP.containsKey(deviceMirror.getUniqueSymbol())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否包含设备镜像
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
* @return
|
||||
*/
|
||||
public synchronized boolean isContainDevice(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (bluetoothLeDevice == null || !DEVICE_MIRROR_MAP.containsKey(bluetoothLeDevice.getAddress() +
|
||||
bluetoothLeDevice.getName())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* 判断是否连接设备
|
||||
* 自添加 2022
|
||||
* @return
|
||||
*/
|
||||
public synchronized boolean isConnectDevice( ) {
|
||||
if (DEVICE_MIRROR_MAP.size()==0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接池中该设备镜像的连接状态,如果没有连接则返回CONNECT_DISCONNECT。
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
* @return
|
||||
*/
|
||||
public synchronized ConnectState getConnectState(BluetoothLeDevice bluetoothLeDevice) {
|
||||
DeviceMirror deviceMirror = getDeviceMirror(bluetoothLeDevice);
|
||||
if (deviceMirror != null) {
|
||||
return deviceMirror.getConnectState();
|
||||
}
|
||||
return ConnectState.CONNECT_DISCONNECT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接池中的设备镜像,如果没有连接则返回空
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
* @return
|
||||
*/
|
||||
public synchronized DeviceMirror getDeviceMirror(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (bluetoothLeDevice != null) {
|
||||
String key = bluetoothLeDevice.getAddress() + bluetoothLeDevice.getName();
|
||||
if (DEVICE_MIRROR_MAP.containsKey(key)) {
|
||||
return DEVICE_MIRROR_MAP.get(key);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开连接池中某一个设备
|
||||
*
|
||||
* @param bluetoothLeDevice
|
||||
*/
|
||||
public synchronized void disconnect(BluetoothLeDevice bluetoothLeDevice) {
|
||||
if (isContainDevice(bluetoothLeDevice)) {
|
||||
getDeviceMirror(bluetoothLeDevice).disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开连接池中所有设备
|
||||
*/
|
||||
public synchronized void disconnect() {
|
||||
for (Map.Entry<String, DeviceMirror> stringDeviceMirrorEntry : DEVICE_MIRROR_MAP.entrySet()) {
|
||||
stringDeviceMirrorEntry.getValue().disconnect();
|
||||
}
|
||||
DEVICE_MIRROR_MAP.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除连接池
|
||||
*/
|
||||
public synchronized void clear() {
|
||||
for (Map.Entry<String, DeviceMirror> stringDeviceMirrorEntry : DEVICE_MIRROR_MAP.entrySet()) {
|
||||
stringDeviceMirrorEntry.getValue().clear();
|
||||
}
|
||||
DEVICE_MIRROR_MAP.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接池设备镜像Map集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, DeviceMirror> getDeviceMirrorMap() {
|
||||
return DEVICE_MIRROR_MAP;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接池设备镜像List集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public synchronized List<DeviceMirror> getDeviceMirrorList() {
|
||||
final List<DeviceMirror> deviceMirrors = new ArrayList<>(DEVICE_MIRROR_MAP.values());
|
||||
Collections.sort(deviceMirrors, new Comparator<DeviceMirror>() {
|
||||
@Override
|
||||
public int compare(final DeviceMirror lhs, final DeviceMirror rhs) {
|
||||
return lhs.getUniqueSymbol().compareToIgnoreCase(rhs.getUniqueSymbol());
|
||||
}
|
||||
});
|
||||
return deviceMirrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接池设备详细信息List集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public synchronized List<BluetoothLeDevice> getDeviceList() {
|
||||
final List<BluetoothLeDevice> deviceList = new ArrayList<>();
|
||||
for (DeviceMirror deviceMirror : getDeviceMirrorList()) {
|
||||
if (deviceMirror != null) {
|
||||
deviceList.add(deviceMirror.getBluetoothLeDevice());
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
}
|
||||
34
app/src/main/java/com/qidian/baseble/core/LruHashMap.java
Normal file
34
app/src/main/java/com/qidian/baseble/core/LruHashMap.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.qidian.baseble.core;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* @Description: Lru算法实现的HashMap
|
||||
* @author: <a href="http://xiaoyaoyou1212.360doc.com">DAWI</a>
|
||||
* @date: 2017/9/28 19:57
|
||||
*/
|
||||
public class LruHashMap<K, V> extends LinkedHashMap<K, V> {
|
||||
private final int MAX_SAVE_SIZE;
|
||||
|
||||
public LruHashMap(int saveSize) {
|
||||
super((int) Math.ceil(saveSize / 0.75) + 1, 0.75f, true);
|
||||
MAX_SAVE_SIZE = saveSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Entry eldest) {
|
||||
if (size() > MAX_SAVE_SIZE && eldest.getValue() instanceof DeviceMirror) {
|
||||
((DeviceMirror) eldest.getValue()).disconnect();
|
||||
}
|
||||
return size() > MAX_SAVE_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Entry<K, V> entry : entrySet()) {
|
||||
sb.append(String.format("%s:%s ", entry.getKey(), entry.getValue()));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package com.qidian.baseble.exception;
|
||||
|
||||
import com.qidian.baseble.common.BleExceptionCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Description: BLE异常基类
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:28.
|
||||
*/
|
||||
public class BleException implements Serializable {
|
||||
private BleExceptionCode code;
|
||||
private String description;
|
||||
|
||||
public BleException(BleExceptionCode code, String description) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public BleExceptionCode getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public BleException setCode(BleExceptionCode code) {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public BleException setDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BleException{" +
|
||||
"code=" + code +
|
||||
", description='" + description + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.qidian.baseble.exception;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
|
||||
import com.qidian.baseble.common.BleExceptionCode;
|
||||
|
||||
/**
|
||||
* @Description: 连接异常
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:29.
|
||||
*/
|
||||
public class ConnectException extends BleException {
|
||||
private BluetoothGatt bluetoothGatt;
|
||||
private int gattStatus;
|
||||
|
||||
public ConnectException(BluetoothGatt bluetoothGatt, int gattStatus) {
|
||||
super(BleExceptionCode.CONNECT_ERR, "Connect Exception Occurred! ");
|
||||
this.bluetoothGatt = bluetoothGatt;
|
||||
this.gattStatus = gattStatus;
|
||||
}
|
||||
|
||||
public int getGattStatus() {
|
||||
return gattStatus;
|
||||
}
|
||||
|
||||
public ConnectException setGattStatus(int gattStatus) {
|
||||
this.gattStatus = gattStatus;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BluetoothGatt getBluetoothGatt() {
|
||||
return bluetoothGatt;
|
||||
}
|
||||
|
||||
public ConnectException setBluetoothGatt(BluetoothGatt bluetoothGatt) {
|
||||
this.bluetoothGatt = bluetoothGatt;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConnectException{" +
|
||||
"gattStatus=" + gattStatus +
|
||||
", bluetoothGatt=" + bluetoothGatt +
|
||||
"} " + super.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.qidian.baseble.exception;
|
||||
|
||||
import com.qidian.baseble.common.BleExceptionCode;
|
||||
|
||||
/**
|
||||
* @Description: Gatt异常
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:30.
|
||||
*/
|
||||
public class GattException extends BleException {
|
||||
private int gattStatus;
|
||||
|
||||
public GattException(int gattStatus) {
|
||||
super(BleExceptionCode.GATT_ERR, "Gatt Exception Occurred! ");
|
||||
this.gattStatus = gattStatus;
|
||||
}
|
||||
|
||||
public int getGattStatus() {
|
||||
return gattStatus;
|
||||
}
|
||||
|
||||
public GattException setGattStatus(int gattStatus) {
|
||||
this.gattStatus = gattStatus;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GattException{" +
|
||||
"gattStatus=" + gattStatus +
|
||||
'}' + super.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.qidian.baseble.exception;
|
||||
|
||||
import com.qidian.baseble.common.BleExceptionCode;
|
||||
|
||||
/**
|
||||
* @Description: 初始化异常
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:30.
|
||||
*/
|
||||
public class InitiatedException extends BleException {
|
||||
public InitiatedException() {
|
||||
super(BleExceptionCode.INITIATED_ERR, "Initiated Exception Occurred! ");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.qidian.baseble.exception;
|
||||
|
||||
import com.qidian.baseble.common.BleExceptionCode;
|
||||
|
||||
/**
|
||||
* @Description: 其他异常
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:32.
|
||||
*/
|
||||
public class OtherException extends BleException {
|
||||
public OtherException(String description) {
|
||||
super(BleExceptionCode.OTHER_ERR, description);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.qidian.baseble.exception;
|
||||
|
||||
import com.qidian.baseble.common.BleExceptionCode;
|
||||
|
||||
/**
|
||||
* @Description: 超时异常
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:29.
|
||||
*/
|
||||
public class TimeoutException extends BleException {
|
||||
public TimeoutException() {
|
||||
super(BleExceptionCode.TIMEOUT, "Timeout Exception Occurred! ");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package com.qidian.baseble.exception.handler;
|
||||
|
||||
import com.qidian.baseble.exception.BleException;
|
||||
import com.qidian.baseble.exception.ConnectException;
|
||||
import com.qidian.baseble.exception.GattException;
|
||||
import com.qidian.baseble.exception.InitiatedException;
|
||||
import com.qidian.baseble.exception.OtherException;
|
||||
import com.qidian.baseble.exception.TimeoutException;
|
||||
|
||||
/**
|
||||
* @Description: 异常处理
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:35.
|
||||
*/
|
||||
public abstract class BleExceptionHandler {
|
||||
public BleExceptionHandler handleException(BleException exception) {
|
||||
if (exception != null) {
|
||||
if (exception instanceof ConnectException) {
|
||||
onConnectException((ConnectException) exception);
|
||||
} else if (exception instanceof GattException) {
|
||||
onGattException((GattException) exception);
|
||||
} else if (exception instanceof TimeoutException) {
|
||||
onTimeoutException((TimeoutException) exception);
|
||||
} else if (exception instanceof InitiatedException) {
|
||||
onInitiatedException((InitiatedException) exception);
|
||||
} else {
|
||||
onOtherException((OtherException) exception);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* connect failed
|
||||
*/
|
||||
protected abstract void onConnectException(ConnectException e);
|
||||
|
||||
/**
|
||||
* gatt error status
|
||||
*/
|
||||
protected abstract void onGattException(GattException e);
|
||||
|
||||
/**
|
||||
* operation timeout
|
||||
*/
|
||||
protected abstract void onTimeoutException(TimeoutException e);
|
||||
|
||||
/**
|
||||
* operation inititiated error
|
||||
*/
|
||||
protected abstract void onInitiatedException(InitiatedException e);
|
||||
|
||||
/**
|
||||
* other exceptions
|
||||
*/
|
||||
protected abstract void onOtherException(OtherException e);
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.qidian.baseble.exception.handler;
|
||||
|
||||
import com.qidian.baseble.exception.ConnectException;
|
||||
import com.qidian.baseble.exception.GattException;
|
||||
import com.qidian.baseble.exception.InitiatedException;
|
||||
import com.qidian.baseble.exception.OtherException;
|
||||
import com.qidian.baseble.exception.TimeoutException;
|
||||
import com.vise.log.ViseLog;
|
||||
|
||||
/**
|
||||
* @Description: 异常默认处理
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/14 10:35.
|
||||
*/
|
||||
public class DefaultBleExceptionHandler extends BleExceptionHandler {
|
||||
@Override
|
||||
protected void onConnectException(ConnectException e) {
|
||||
ViseLog.e(e.getDescription());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onGattException(GattException e) {
|
||||
ViseLog.e(e.getDescription());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTimeoutException(TimeoutException e) {
|
||||
ViseLog.e(e.getDescription());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitiatedException(InitiatedException e) {
|
||||
ViseLog.e(e.getDescription());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onOtherException(OtherException e) {
|
||||
ViseLog.e(e.getDescription());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,426 @@
|
||||
package com.qidian.baseble.model;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.qidian.baseble.common.BluetoothServiceType;
|
||||
import com.qidian.baseble.model.adrecord.AdRecordStore;
|
||||
import com.qidian.baseble.model.resolver.BluetoothClassResolver;
|
||||
import com.qidian.baseble.utils.AdRecordUtil;
|
||||
import com.vise.utils.convert.HexUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Description: 设备信息
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/5 20:44.
|
||||
*/
|
||||
public class BluetoothLeDevice implements Parcelable {
|
||||
|
||||
/**
|
||||
* The Constant CREATOR.
|
||||
*/
|
||||
public static final Creator<BluetoothLeDevice> CREATOR = new Creator<BluetoothLeDevice>() {
|
||||
public BluetoothLeDevice createFromParcel(final Parcel in) {
|
||||
return new BluetoothLeDevice(in);
|
||||
}
|
||||
|
||||
public BluetoothLeDevice[] newArray(final int size) {
|
||||
return new BluetoothLeDevice[size];
|
||||
}
|
||||
};
|
||||
protected static final int MAX_RSSI_LOG_SIZE = 10;
|
||||
private static final String PARCEL_EXTRA_BLUETOOTH_DEVICE = "bluetooth_device";
|
||||
private static final String PARCEL_EXTRA_CURRENT_RSSI = "current_rssi";
|
||||
private static final String PARCEL_EXTRA_CURRENT_TIMESTAMP = "current_timestamp";
|
||||
private static final String PARCEL_EXTRA_DEVICE_RSSI_LOG = "device_rssi_log";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD = "device_scanrecord";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD_STORE = "device_scanrecord_store";
|
||||
private static final String PARCEL_EXTRA_FIRST_RSSI = "device_first_rssi";
|
||||
private static final String PARCEL_EXTRA_FIRST_TIMESTAMP = "first_timestamp";
|
||||
private static final long LOG_INVALIDATION_THRESHOLD = 10 * 1000;
|
||||
private final AdRecordStore mRecordStore;
|
||||
private final BluetoothDevice mDevice;
|
||||
private final Map<Long, Integer> mRssiLog;
|
||||
private final byte[] mScanRecord;
|
||||
private final int mFirstRssi;
|
||||
private final long mFirstTimestamp;
|
||||
private int mCurrentRssi;
|
||||
private long mCurrentTimestamp;
|
||||
private transient Set<BluetoothServiceType> mServiceSet;
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device a standard android Bluetooth device
|
||||
* @param rssi the RSSI value of the Bluetooth device
|
||||
* @param scanRecord the scan record of the device
|
||||
* @param timestamp the timestamp of the RSSI reading
|
||||
*/
|
||||
public BluetoothLeDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
|
||||
mDevice = device;
|
||||
mFirstRssi = rssi;
|
||||
mFirstTimestamp = timestamp;
|
||||
mRecordStore = new AdRecordStore(AdRecordUtil.parseScanRecordAsSparseArray(scanRecord));
|
||||
mScanRecord = scanRecord;
|
||||
mRssiLog = new LinkedHashMap<>(MAX_RSSI_LOG_SIZE);
|
||||
updateRssiReading(timestamp, rssi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device the device
|
||||
*/
|
||||
public BluetoothLeDevice(final BluetoothLeDevice device) {
|
||||
mCurrentRssi = device.getRssi();
|
||||
mCurrentTimestamp = device.getTimestamp();
|
||||
mDevice = device.getDevice();
|
||||
mFirstRssi = device.getFirstRssi();
|
||||
mFirstTimestamp = device.getFirstTimestamp();
|
||||
mRecordStore = new AdRecordStore(AdRecordUtil.parseScanRecordAsSparseArray(device.getScanRecord()));
|
||||
mRssiLog = device.getRssiLog();
|
||||
mScanRecord = device.getScanRecord();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new bluetooth le device.
|
||||
*
|
||||
* @param in the in
|
||||
*/
|
||||
protected BluetoothLeDevice(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
|
||||
mCurrentRssi = b.getInt(PARCEL_EXTRA_CURRENT_RSSI, 0);
|
||||
mCurrentTimestamp = b.getLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, 0);
|
||||
mDevice = b.getParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE);
|
||||
mFirstRssi = b.getInt(PARCEL_EXTRA_FIRST_RSSI, 0);
|
||||
mFirstTimestamp = b.getLong(PARCEL_EXTRA_FIRST_TIMESTAMP, 0);
|
||||
mRecordStore = b.getParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE);
|
||||
mRssiLog = (Map<Long, Integer>) b.getSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG);
|
||||
mScanRecord = b.getByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the to rssi log.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
private void addToRssiLog(final long timestamp, final int rssiReading) {
|
||||
synchronized (mRssiLog) {
|
||||
if (timestamp - mCurrentTimestamp > LOG_INVALIDATION_THRESHOLD) {
|
||||
mRssiLog.clear();
|
||||
}
|
||||
|
||||
mCurrentRssi = rssiReading;
|
||||
mCurrentTimestamp = timestamp;
|
||||
mRssiLog.put(timestamp, rssiReading);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
final BluetoothLeDevice other = (BluetoothLeDevice) obj;
|
||||
if (mCurrentRssi != other.mCurrentRssi) return false;
|
||||
if (mCurrentTimestamp != other.mCurrentTimestamp) return false;
|
||||
if (mDevice == null) {
|
||||
if (other.mDevice != null) return false;
|
||||
} else if (!mDevice.equals(other.mDevice)) return false;
|
||||
if (mFirstRssi != other.mFirstRssi) return false;
|
||||
if (mFirstTimestamp != other.mFirstTimestamp) return false;
|
||||
if (mRecordStore == null) {
|
||||
if (other.mRecordStore != null) return false;
|
||||
} else if (!mRecordStore.equals(other.mRecordStore)) return false;
|
||||
if (mRssiLog == null) {
|
||||
if (other.mRssiLog != null) return false;
|
||||
} else if (!mRssiLog.equals(other.mRssiLog)) return false;
|
||||
if (Arrays.equals(mScanRecord, other.mScanRecord)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ad record store.
|
||||
*
|
||||
* @return the ad record store
|
||||
*/
|
||||
public AdRecordStore getAdRecordStore() {
|
||||
return mRecordStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address.
|
||||
*
|
||||
* @return the address
|
||||
*/
|
||||
public String getAddress() {
|
||||
return mDevice.getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device bond state.
|
||||
*
|
||||
* @return the bluetooth device bond state
|
||||
*/
|
||||
public String getBluetoothDeviceBondState() {
|
||||
return resolveBondingState(mDevice.getBondState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device class name.
|
||||
*
|
||||
* @return the bluetooth device class name
|
||||
*/
|
||||
public String getBluetoothDeviceClassName() {
|
||||
return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
|
||||
}
|
||||
|
||||
public Set<BluetoothServiceType> getBluetoothDeviceKnownSupportedServices() {
|
||||
if (mServiceSet == null) {
|
||||
synchronized (this) {
|
||||
if (mServiceSet == null) {
|
||||
final Set<BluetoothServiceType> serviceSet = new HashSet<>();
|
||||
for (final BluetoothServiceType service : BluetoothServiceType.values()) {
|
||||
|
||||
if (mDevice.getBluetoothClass().hasService(service.getCode())) {
|
||||
serviceSet.add(service);
|
||||
}
|
||||
}
|
||||
mServiceSet = Collections.unmodifiableSet(serviceSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mServiceSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device major class name.
|
||||
*
|
||||
* @return the bluetooth device major class name
|
||||
*/
|
||||
public String getBluetoothDeviceMajorClassName() {
|
||||
return BluetoothClassResolver.resolveMajorDeviceClass(mDevice.getBluetoothClass().getMajorDeviceClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device.
|
||||
*
|
||||
* @return the device
|
||||
*/
|
||||
public BluetoothDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first rssi.
|
||||
*
|
||||
* @return the first rssi
|
||||
*/
|
||||
public int getFirstRssi() {
|
||||
return mFirstRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first timestamp.
|
||||
*
|
||||
* @return the first timestamp
|
||||
*/
|
||||
public long getFirstTimestamp() {
|
||||
return mFirstTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return mDevice.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rssi.
|
||||
*
|
||||
* @return the rssi
|
||||
*/
|
||||
public int getRssi() {
|
||||
return mCurrentRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rssi log.
|
||||
*
|
||||
* @return the rssi log
|
||||
*/
|
||||
protected Map<Long, Integer> getRssiLog() {
|
||||
synchronized (mRssiLog) {
|
||||
return mRssiLog;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the running average rssi.
|
||||
*
|
||||
* @return the running average rssi
|
||||
*/
|
||||
public double getRunningAverageRssi() {
|
||||
int sum = 0;
|
||||
int count = 0;
|
||||
|
||||
synchronized (mRssiLog) {
|
||||
|
||||
for (final Long aLong : mRssiLog.keySet()) {
|
||||
count++;
|
||||
sum += mRssiLog.get(aLong);
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
return sum / count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取major
|
||||
* @return major
|
||||
*/
|
||||
// public long getMajor(){
|
||||
// return HexUtil.byteToLong(HexUtilu.subBytes(mScanRecord,25,2),0,2,true);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取minor
|
||||
* @return minor
|
||||
*/
|
||||
// public long minor(){
|
||||
// return HexUtil.byteToLong(HexUtil.subBytes(mScanRecord,27,2),0,2,true);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Gets the scan record.
|
||||
*
|
||||
* @return the scan record
|
||||
*/
|
||||
public byte[] getScanRecord() {
|
||||
return mScanRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the timestamp.
|
||||
*
|
||||
* @return the timestamp
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return mCurrentTimestamp;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + mCurrentRssi;
|
||||
result = prime * result + (int) (mCurrentTimestamp ^ (mCurrentTimestamp >>> 32));
|
||||
result = prime * result + ((mDevice == null) ? 0 : mDevice.hashCode());
|
||||
result = prime * result + mFirstRssi;
|
||||
result = prime * result + (int) (mFirstTimestamp ^ (mFirstTimestamp >>> 32));
|
||||
result = prime * result + ((mRecordStore == null) ? 0 : mRecordStore.hashCode());
|
||||
result = prime * result + ((mRssiLog == null) ? 0 : mRssiLog.hashCode());
|
||||
result = prime * result + Arrays.hashCode(mScanRecord);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BluetoothLeDevice [mDevice=" + mDevice + ", " +
|
||||
"mRssi=" + mFirstRssi + ", mScanRecord=" + HexUtil.encodeHexStr(mScanRecord) +
|
||||
", mRecordStore=" + mRecordStore + ", getBluetoothDeviceBondState()=" +
|
||||
getBluetoothDeviceBondState() + ", getBluetoothDeviceClassName()=" +
|
||||
getBluetoothDeviceClassName() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rssi reading.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
public void updateRssiReading(final long timestamp, final int rssiReading) {
|
||||
addToRssiLog(timestamp, rssiReading);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
b.putByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD, mScanRecord);
|
||||
|
||||
b.putInt(PARCEL_EXTRA_FIRST_RSSI, mFirstRssi);
|
||||
b.putInt(PARCEL_EXTRA_CURRENT_RSSI, mCurrentRssi);
|
||||
|
||||
b.putLong(PARCEL_EXTRA_FIRST_TIMESTAMP, mFirstTimestamp);
|
||||
b.putLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, mCurrentTimestamp);
|
||||
|
||||
b.putParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE, mDevice);
|
||||
b.putParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE, mRecordStore);
|
||||
b.putSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG, (Serializable) mRssiLog);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve bonding state.
|
||||
*
|
||||
* @param bondState the bond state
|
||||
* @return the string
|
||||
*/
|
||||
private static String resolveBondingState(final int bondState) {
|
||||
switch (bondState) {
|
||||
case BluetoothDevice.BOND_BONDED://已配对
|
||||
return "Paired";
|
||||
case BluetoothDevice.BOND_BONDING://配对中
|
||||
return "Pairing";
|
||||
case BluetoothDevice.BOND_NONE://未配对
|
||||
return "UnBonded";
|
||||
default:
|
||||
return "Unknown";//未知状态
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package com.qidian.baseble.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 设备信息集合
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/21 16:48.
|
||||
*/
|
||||
public class BluetoothLeDeviceStore {
|
||||
|
||||
private final Map<String, BluetoothLeDevice> mDeviceMap;
|
||||
|
||||
public BluetoothLeDeviceStore() {
|
||||
mDeviceMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public void addDevice(BluetoothLeDevice device) {
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
if (mDeviceMap.containsKey(device.getAddress())) {
|
||||
mDeviceMap.get(device.getAddress()).updateRssiReading(device.getTimestamp(), device.getRssi());
|
||||
} else {
|
||||
mDeviceMap.put(device.getAddress(), device);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeDevice(BluetoothLeDevice device) {
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
if (mDeviceMap.containsKey(device.getAddress())) {
|
||||
mDeviceMap.remove(device.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mDeviceMap.clear();
|
||||
}
|
||||
|
||||
public Map<String, BluetoothLeDevice> getDeviceMap() {
|
||||
return mDeviceMap;
|
||||
}
|
||||
|
||||
public List<BluetoothLeDevice> getDeviceList() {
|
||||
final List<BluetoothLeDevice> methodResult = new ArrayList<>(mDeviceMap.values());
|
||||
|
||||
Collections.sort(methodResult, new Comparator<BluetoothLeDevice>() {
|
||||
|
||||
@Override
|
||||
public int compare(final BluetoothLeDevice arg0, final BluetoothLeDevice arg1) {
|
||||
return arg0.getAddress().compareToIgnoreCase(arg1.getAddress());
|
||||
}
|
||||
});
|
||||
|
||||
return methodResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BluetoothLeDeviceStore{" +
|
||||
"DeviceList=" + getDeviceList() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,185 @@
|
||||
package com.qidian.baseble.model.adrecord;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Description: 广播包解析model
|
||||
* 参考:https://www.bluetooth.com/zh-cn/specifications/assigned-numbers/generic-access-profile
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/7 21:53.
|
||||
*/
|
||||
public class AdRecord implements Parcelable {
|
||||
|
||||
public static final int BLE_GAP_AD_TYPE_FLAGS = 0x01;//< Flags for discoverAbility.
|
||||
public static final int BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE = 0x02;//< Partial list of 16 bit service UUIDs.
|
||||
public static final int BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE = 0x03;//< Complete list of 16 bit service UUIDs.
|
||||
public static final int BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE = 0x04;//< Partial list of 32 bit service UUIDs.
|
||||
public static final int BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE = 0x05;//< Complete list of 32 bit service UUIDs.
|
||||
public static final int BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE = 0x06;//< Partial list of 128 bit service UUIDs.
|
||||
public static final int BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE = 0x07;//< Complete list of 128 bit service UUIDs.
|
||||
public static final int BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME = 0x08;//< Short local device name.
|
||||
public static final int BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME = 0x09;//< Complete local device name.
|
||||
public static final int BLE_GAP_AD_TYPE_TX_POWER_LEVEL = 0x0A;//< Transmit power level.
|
||||
public static final int BLE_GAP_AD_TYPE_CLASS_OF_DEVICE = 0x0D;//< Class of device.
|
||||
public static final int BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C = 0x0E;//< Simple Pairing Hash C.
|
||||
public static final int BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F;//< Simple Pairing Randomizer R.
|
||||
public static final int BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE = 0x10;//< Security Manager TK Value.
|
||||
public static final int BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11;//< Security Manager Out Of Band Flags.
|
||||
public static final int BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE = 0x12;//< Slave Connection Interval Range.
|
||||
public static final int BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT = 0x14;//< List of 16-bit Service Solicitation UUIDs.
|
||||
public static final int BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT = 0x15;//< List of 128-bit Service Solicitation UUIDs.
|
||||
public static final int BLE_GAP_AD_TYPE_SERVICE_DATA = 0x16;//< Service Data - 16-bit UUID.
|
||||
public static final int BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS = 0x17;//< Public Target Address.
|
||||
public static final int BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS = 0x18;//< Random Target Address.
|
||||
public static final int BLE_GAP_AD_TYPE_APPEARANCE = 0x19;//< Appearance.
|
||||
public static final int BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL = 0x1A;//< Advertising Interval.
|
||||
public static final int BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS = 0x1B;//< LE Bluetooth Device Address.
|
||||
public static final int BLE_GAP_AD_TYPE_LE_ROLE = 0x1C;//< LE Role.
|
||||
public static final int BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 = 0x1D;//< Simple Pairing Hash C-256.
|
||||
public static final int BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 = 0x1E;//< Simple Pairing Randomizer R-256.
|
||||
public static final int BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID = 0x20;//< Service Data - 32-bit UUID.
|
||||
public static final int BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID = 0x21;//< Service Data - 128-bit UUID.
|
||||
public static final int BLE_GAP_AD_TYPE_3D_INFORMATION_DATA = 0x3D;//< 3D Information Data.
|
||||
public static final int BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;//< Manufacturer Specific Data.
|
||||
|
||||
public static final Creator<AdRecord> CREATOR = new Creator<AdRecord>() {
|
||||
public AdRecord createFromParcel(final Parcel in) {
|
||||
return new AdRecord(in);
|
||||
}
|
||||
|
||||
public AdRecord[] newArray(final int size) {
|
||||
return new AdRecord[size];
|
||||
}
|
||||
};
|
||||
private static final String PARCEL_RECORD_DATA = "record_data";
|
||||
private static final String PARCEL_RECORD_TYPE = "record_type";
|
||||
private static final String PARCEL_RECORD_LENGTH = "record_length";
|
||||
/* Model Object Definition */
|
||||
private final int mLength;
|
||||
private final int mType;
|
||||
private final byte[] mData;
|
||||
|
||||
public AdRecord(final int length, final int type, final byte[] data) {
|
||||
mLength = length;
|
||||
mType = type;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
public AdRecord(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mLength = b.getInt(PARCEL_RECORD_LENGTH);
|
||||
mType = b.getInt(PARCEL_RECORD_TYPE);
|
||||
mData = b.getByteArray(PARCEL_RECORD_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
public String getHumanReadableType() {
|
||||
return getHumanReadableAdType(mType);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecord [mLength=" + mLength + ", mType=" + mType + ", mData=" + Arrays.toString(mData) + ", getHumanReadableType()=" +
|
||||
getHumanReadableType() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
b.putInt(PARCEL_RECORD_LENGTH, mLength);
|
||||
b.putInt(PARCEL_RECORD_TYPE, mType);
|
||||
b.putByteArray(PARCEL_RECORD_DATA, mData);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
private static String getHumanReadableAdType(final int type) {
|
||||
switch (type) {
|
||||
case BLE_GAP_AD_TYPE_FLAGS:
|
||||
return "Flags for discoverAbility.";
|
||||
case BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE:
|
||||
return "Partial list of 16 bit service UUIDs.";
|
||||
case BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE:
|
||||
return "Complete list of 16 bit service UUIDs.";
|
||||
case BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE:
|
||||
return "Partial list of 32 bit service UUIDs.";
|
||||
case BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE:
|
||||
return "Complete list of 32 bit service UUIDs.";
|
||||
case BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE:
|
||||
return "Partial list of 128 bit service UUIDs.";
|
||||
case BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE:
|
||||
return "Complete list of 128 bit service UUIDs.";
|
||||
case BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME:
|
||||
return "Short local device name.";
|
||||
case BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME:
|
||||
return "Complete local device name.";
|
||||
case BLE_GAP_AD_TYPE_TX_POWER_LEVEL:
|
||||
return "Transmit power level.";
|
||||
case BLE_GAP_AD_TYPE_CLASS_OF_DEVICE:
|
||||
return "Class of device.";
|
||||
case BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C:
|
||||
return "Simple Pairing Hash C.";
|
||||
case BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R:
|
||||
return "Simple Pairing Randomizer R.";
|
||||
case BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE:
|
||||
return "Security Manager TK Value.";
|
||||
case BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS:
|
||||
return "Security Manager Out Of Band Flags.";
|
||||
case BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE:
|
||||
return "Slave Connection Interval Range.";
|
||||
case BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT:
|
||||
return "List of 16-bit Service Solicitation UUIDs.";
|
||||
case BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT:
|
||||
return "List of 128-bit Service Solicitation UUIDs.";
|
||||
case BLE_GAP_AD_TYPE_SERVICE_DATA:
|
||||
return "Service Data - 16-bit UUID.";
|
||||
case BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS:
|
||||
return "Public Target Address.";
|
||||
case BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS:
|
||||
return "Random Target Address.";
|
||||
case BLE_GAP_AD_TYPE_APPEARANCE:
|
||||
return "Appearance.";
|
||||
case BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL:
|
||||
return "Advertising Interval.";
|
||||
case BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS:
|
||||
return "LE Bluetooth Device Address.";
|
||||
case BLE_GAP_AD_TYPE_LE_ROLE:
|
||||
return "LE Role.";
|
||||
case BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256:
|
||||
return "Simple Pairing Hash C-256.";
|
||||
case BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256:
|
||||
return "Simple Pairing Randomizer R-256.";
|
||||
case BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID:
|
||||
return "Service Data - 32-bit UUID.";
|
||||
case BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID:
|
||||
return "Service Data - 128-bit UUID.";
|
||||
case BLE_GAP_AD_TYPE_3D_INFORMATION_DATA:
|
||||
return "3D Information Data.";
|
||||
case BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA:
|
||||
return "Manufacturer Specific Data.";
|
||||
default:
|
||||
return "Unknown AdRecord Structure: " + type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,156 @@
|
||||
package com.qidian.baseble.model.adrecord;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.qidian.baseble.utils.AdRecordUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @Description: 广播包解析仓库
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/7 21:54.
|
||||
*/
|
||||
public class AdRecordStore implements Parcelable {
|
||||
|
||||
public static final Creator<AdRecordStore> CREATOR = new Creator<AdRecordStore>() {
|
||||
public AdRecordStore createFromParcel(final Parcel in) {
|
||||
return new AdRecordStore(in);
|
||||
}
|
||||
|
||||
public AdRecordStore[] newArray(final int size) {
|
||||
return new AdRecordStore[size];
|
||||
}
|
||||
};
|
||||
private static final String RECORDS_ARRAY = "records_array";
|
||||
private static final String LOCAL_NAME_COMPLETE = "local_name_complete";
|
||||
private static final String LOCAL_NAME_SHORT = "local_name_short";
|
||||
private final SparseArray<AdRecord> mAdRecords;
|
||||
private final String mLocalNameComplete;
|
||||
private final String mLocalNameShort;
|
||||
|
||||
public AdRecordStore(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mAdRecords = b.getSparseParcelableArray(RECORDS_ARRAY);
|
||||
mLocalNameComplete = b.getString(LOCAL_NAME_COMPLETE);
|
||||
mLocalNameShort = b.getString(LOCAL_NAME_SHORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device Ad Record Store.
|
||||
*
|
||||
* @param adRecords the ad records
|
||||
*/
|
||||
public AdRecordStore(final SparseArray<AdRecord> adRecords) {
|
||||
mAdRecords = adRecords;
|
||||
mLocalNameComplete = AdRecordUtil.getRecordDataAsString(mAdRecords.get(AdRecord.BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME));
|
||||
mLocalNameShort = AdRecordUtil.getRecordDataAsString(mAdRecords.get(AdRecord.BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME));
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the short local device name.
|
||||
*
|
||||
* @return the local name complete
|
||||
*/
|
||||
public String getLocalNameComplete() {
|
||||
return mLocalNameComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the complete local device name.
|
||||
*
|
||||
* @return the local name short
|
||||
*/
|
||||
public String getLocalNameShort() {
|
||||
return mLocalNameShort;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves an individual record.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record
|
||||
*/
|
||||
public AdRecord getRecord(final int record) {
|
||||
return mAdRecords.get(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the record data as string.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record data as string
|
||||
*/
|
||||
public String getRecordDataAsString(final int record) {
|
||||
return AdRecordUtil.getRecordDataAsString(mAdRecords.get(record));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the record as collection.
|
||||
*
|
||||
* @return the records as collection
|
||||
*/
|
||||
public Collection<AdRecord> getRecordsAsCollection() {
|
||||
return Collections.unmodifiableCollection(asList(mAdRecords));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is record present.
|
||||
*
|
||||
* @param record the record
|
||||
* @return true, if is record present
|
||||
*/
|
||||
public boolean isRecordPresent(final int record) {
|
||||
return mAdRecords.indexOfKey(record) >= 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecordStore [mLocalNameComplete=" + mLocalNameComplete + ", mLocalNameShort=" + mLocalNameShort + "]";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle();
|
||||
b.putString(LOCAL_NAME_COMPLETE, mLocalNameComplete);
|
||||
b.putString(LOCAL_NAME_SHORT, mLocalNameShort);
|
||||
b.putSparseParcelableArray(RECORDS_ARRAY, mAdRecords);
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* As list.
|
||||
*
|
||||
* @param <C> the generic type
|
||||
* @param sparseArray the sparse array
|
||||
* @return the collection
|
||||
*/
|
||||
public static <C> Collection<C> asList(final SparseArray<C> sparseArray) {
|
||||
if (sparseArray == null) return null;
|
||||
final Collection<C> arrayList = new ArrayList<>(sparseArray.size());
|
||||
for (int i = 0; i < sparseArray.size(); i++) {
|
||||
arrayList.add(sparseArray.valueAt(i));
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,146 @@
|
||||
package com.qidian.baseble.model.resolver;
|
||||
|
||||
import android.bluetooth.BluetoothClass;
|
||||
|
||||
/**
|
||||
* @Description: 蓝牙设备类别
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/7 21:48.
|
||||
*/
|
||||
public class BluetoothClassResolver {
|
||||
public static String resolveDeviceClass(final int btClass) {
|
||||
switch (btClass) {
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAMCORDER:
|
||||
return "A/V, Camcorder";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
||||
return "A/V, Car Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
||||
return "A/V, Handsfree";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
|
||||
return "A/V, Headphones";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
|
||||
return "A/V, HiFi Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
|
||||
return "A/V, Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_MICROPHONE:
|
||||
return "A/V, Microphone";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
|
||||
return "A/V, Portable Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_SET_TOP_BOX:
|
||||
return "A/V, Set Top Box";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_UNCATEGORIZED:
|
||||
return "A/V, Uncategorized";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VCR:
|
||||
return "A/V, VCR";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CAMERA:
|
||||
return "A/V, Video Camera";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CONFERENCING:
|
||||
return "A/V, Video Conferencing";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER:
|
||||
return "A/V, Video Display and Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_GAMING_TOY:
|
||||
return "A/V, Video Gaming Toy";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_MONITOR:
|
||||
return "A/V, Video Monitor";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
||||
return "A/V, Video Wearable Headset";
|
||||
case BluetoothClass.Device.COMPUTER_DESKTOP:
|
||||
return "Computer, Desktop";
|
||||
case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA:
|
||||
return "Computer, Handheld PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_LAPTOP:
|
||||
return "Computer, Laptop";
|
||||
case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA:
|
||||
return "Computer, Palm Size PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_SERVER:
|
||||
return "Computer, Server";
|
||||
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
|
||||
return "Computer, Uncategorized";
|
||||
case BluetoothClass.Device.COMPUTER_WEARABLE:
|
||||
return "Computer, Wearable";
|
||||
case BluetoothClass.Device.HEALTH_BLOOD_PRESSURE:
|
||||
return "Health, Blood Pressure";
|
||||
case BluetoothClass.Device.HEALTH_DATA_DISPLAY:
|
||||
return "Health, Data Display";
|
||||
case BluetoothClass.Device.HEALTH_GLUCOSE:
|
||||
return "Health, Glucose";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_OXIMETER:
|
||||
return "Health, Pulse Oximeter";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_RATE:
|
||||
return "Health, Pulse Rate";
|
||||
case BluetoothClass.Device.HEALTH_THERMOMETER:
|
||||
return "Health, Thermometer";
|
||||
case BluetoothClass.Device.HEALTH_UNCATEGORIZED:
|
||||
return "Health, Uncategorized";
|
||||
case BluetoothClass.Device.HEALTH_WEIGHING:
|
||||
return "Health, Weighting";
|
||||
case BluetoothClass.Device.PHONE_CELLULAR:
|
||||
return "Phone, Cellular";
|
||||
case BluetoothClass.Device.PHONE_CORDLESS:
|
||||
return "Phone, Cordless";
|
||||
case BluetoothClass.Device.PHONE_ISDN:
|
||||
return "Phone, ISDN";
|
||||
case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY:
|
||||
return "Phone, Modem or Gateway";
|
||||
case BluetoothClass.Device.PHONE_SMART:
|
||||
return "Phone, Smart";
|
||||
case BluetoothClass.Device.PHONE_UNCATEGORIZED:
|
||||
return "Phone, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_CONTROLLER:
|
||||
return "Toy, Controller";
|
||||
case BluetoothClass.Device.TOY_DOLL_ACTION_FIGURE:
|
||||
return "Toy, Doll/Action Figure";
|
||||
case BluetoothClass.Device.TOY_GAME:
|
||||
return "Toy, Game";
|
||||
case BluetoothClass.Device.TOY_ROBOT:
|
||||
return "Toy, Robot";
|
||||
case BluetoothClass.Device.TOY_UNCATEGORIZED:
|
||||
return "Toy, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_VEHICLE:
|
||||
return "Toy, Vehicle";
|
||||
case BluetoothClass.Device.WEARABLE_GLASSES:
|
||||
return "Wearable, Glasses";
|
||||
case BluetoothClass.Device.WEARABLE_HELMET:
|
||||
return "Wearable, Helmet";
|
||||
case BluetoothClass.Device.WEARABLE_JACKET:
|
||||
return "Wearable, Jacket";
|
||||
case BluetoothClass.Device.WEARABLE_PAGER:
|
||||
return "Wearable, Pager";
|
||||
case BluetoothClass.Device.WEARABLE_UNCATEGORIZED:
|
||||
return "Wearable, Uncategorized";
|
||||
case BluetoothClass.Device.WEARABLE_WRIST_WATCH:
|
||||
return "Wearable, Wrist Watch";
|
||||
default:
|
||||
return "Unknown, Unknown (class=" + btClass + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public static String resolveMajorDeviceClass(final int majorBtClass) {
|
||||
switch (majorBtClass) {
|
||||
case BluetoothClass.Device.Major.AUDIO_VIDEO:
|
||||
return "Audio/ Video";
|
||||
case BluetoothClass.Device.Major.COMPUTER:
|
||||
return "Computer";
|
||||
case BluetoothClass.Device.Major.HEALTH:
|
||||
return "Health";
|
||||
case BluetoothClass.Device.Major.IMAGING:
|
||||
return "Imaging";
|
||||
case BluetoothClass.Device.Major.MISC:
|
||||
return "Misc";
|
||||
case BluetoothClass.Device.Major.NETWORKING:
|
||||
return "Networking";
|
||||
case BluetoothClass.Device.Major.PERIPHERAL:
|
||||
return "Peripheral";
|
||||
case BluetoothClass.Device.Major.PHONE:
|
||||
return "Phone";
|
||||
case BluetoothClass.Device.Major.TOY:
|
||||
return "Toy";
|
||||
case BluetoothClass.Device.Major.UNCATEGORIZED:
|
||||
return "Uncategorized";
|
||||
case BluetoothClass.Device.Major.WEARABLE:
|
||||
return "Wearable";
|
||||
default:
|
||||
return "Unknown (" + majorBtClass + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,650 @@
|
||||
package com.qidian.baseble.model.resolver;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
/**
|
||||
* @Description: 公司标识符
|
||||
* 参考:https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/7 21:49.
|
||||
*/
|
||||
public class CompanyIdentifierResolver {
|
||||
public static final int ERICSSON_TECHNOLOGY_LICENSING = 0x0000;
|
||||
public static final int NOKIA_MOBILE_PHONES = 0x0001;
|
||||
public static final int INTEL_CORP = 0x0002;
|
||||
public static final int IBM_CORP = 0x0003;
|
||||
public static final int TOSHIBA_CORP = 0x0004;
|
||||
public static final int THREE_COM = 0x0005;
|
||||
public static final int MICROSOFT = 0x0006;
|
||||
public static final int LUCENT = 0x0007;
|
||||
public static final int MOTOROLA = 0x0008;
|
||||
public static final int INFINEON_TECHNOLOGIES_AG = 0x0009;
|
||||
public static final int CAMBRIDGE_SILICON_RADIO = 0x000A;
|
||||
public static final int SILICON_WAVE = 0x000B;
|
||||
public static final int DIGIANSWER_A_S = 0x000C;
|
||||
public static final int TEXAS_INSTRUMENTS_INC = 0x000D;
|
||||
public static final int CEVA_INC_FORMERLY_PARTHUS_TECHNOLOGIES_INC = 0x000E;
|
||||
public static final int BROADCOM_CORPORATION = 0x000F;
|
||||
public static final int MITEL_SEMICONDUCTOR = 0x0010;
|
||||
public static final int WIDCOMM_INC = 0x0011;
|
||||
public static final int ZEEVO_INC = 0x0012;
|
||||
public static final int ATMEL_CORPORATION = 0x0013;
|
||||
public static final int MITSUBISHI_ELECTRIC_CORPORATION = 0x0014;
|
||||
public static final int RTX_TELECOM_A_S = 0x0015;
|
||||
public static final int KC_TECHNOLOGY_INC = 0x0016;
|
||||
public static final int NEWLOGIC = 0x0017;
|
||||
public static final int TRANSILICA_INC = 0x0018;
|
||||
public static final int ROHDE_SCHWARZ_GMBH_CO_KG = 0x0019;
|
||||
public static final int TTPCOM_LIMITED = 0x001A;
|
||||
public static final int SIGNIA_TECHNOLOGIES_INC = 0x001B;
|
||||
public static final int CONEXANT_SYSTEMS_INC = 0x001C;
|
||||
public static final int QUALCOMM = 0x001D;
|
||||
public static final int INVENTEL = 0x001E;
|
||||
public static final int AVM_BERLIN = 0x001F;
|
||||
public static final int BANDSPEED_INC = 0x0020;
|
||||
public static final int MANSELLA_LTD = 0x0021;
|
||||
public static final int NEC_CORPORATION = 0x0022;
|
||||
public static final int WAVEPLUS_TECHNOLOGY_CO_LTD = 0x0023;
|
||||
public static final int ALCATEL = 0x0024;
|
||||
public static final int PHILIPS_SEMICONDUCTORS = 0x0025;
|
||||
public static final int C_TECHNOLOGIES = 0x0026;
|
||||
public static final int OPEN_INTERFACE = 0x0027;
|
||||
public static final int R_F_MICRO_DEVICES = 0x0028;
|
||||
public static final int HITACHI_LTD = 0x0029;
|
||||
public static final int SYMBOL_TECHNOLOGIES_INC = 0x002A;
|
||||
public static final int TENOVIS = 0x002B;
|
||||
public static final int MACRONIX_INTERNATIONAL_CO_LTD = 0x002C;
|
||||
public static final int GCT_SEMICONDUCTOR = 0x002D;
|
||||
public static final int NORWOOD_SYSTEMS = 0x002E;
|
||||
public static final int MEWTEL_TECHNOLOGY_INC = 0x002F;
|
||||
public static final int ST_MICROELECTRONICS = 0x0030;
|
||||
public static final int SYNOPSIS = 0x0031;
|
||||
public static final int REDM_COMMUNICATIONS_LTD = 0x0032;
|
||||
public static final int COMMIL_LTD = 0x0033;
|
||||
public static final int COMPUTER_ACCESS_TECHNOLOGY_CORPORATION_CATC = 0x0034;
|
||||
public static final int ECLIPSE_HQ_ESPANA_SL = 0x0035;
|
||||
public static final int RENESAS_TECHNOLOGY_CORP = 0x0036;
|
||||
public static final int MOBILIAN_CORPORATION = 0x0037;
|
||||
public static final int TERAX = 0x0038;
|
||||
public static final int INTEGRATED_SYSTEM_SOLUTION_CORP = 0x0039;
|
||||
public static final int MATSUSHITA_ELECTRIC_INDUSTRIAL_CO_LTD = 0x003A;
|
||||
public static final int GENNUM_CORPORATION = 0x003B;
|
||||
public static final int RESEARCH_IN_MOTION = 0x003C;
|
||||
public static final int IPEXTREME_INC = 0x003D;
|
||||
public static final int SYSTEMS_AND_CHIPS_INC = 0x003E;
|
||||
public static final int BLUETOOTH_SIG_INC = 0x003F;
|
||||
public static final int SEIKO_EPSON_CORPORATION = 0x0040;
|
||||
public static final int INTEGRATED_SILICON_SOLUTION_TAIWAN_INC = 0x0041;
|
||||
public static final int CONWISE_TECHNOLOGY_CORPORATION_LTD = 0x0042;
|
||||
public static final int PARROT_SA = 0x0043;
|
||||
public static final int SOCKET_MOBILE = 0x0044;
|
||||
public static final int ATHEROS_COMMUNICATIONS_INC = 0x0045;
|
||||
public static final int MEDIATEK_INC = 0x0046;
|
||||
public static final int BLUEGIGA = 0x0047;
|
||||
public static final int MARVELL_TECHNOLOGY_GROUP_LTD = 0x0048;
|
||||
public static final int THREE_DSP_CORPORATION = 0x0049;
|
||||
public static final int ACCEL_SEMICONDUCTOR_LTD = 0x004A;
|
||||
public static final int CONTINENTAL_AUTOMOTIVE_SYSTEMS = 0x004B;
|
||||
public static final int APPLE_INC = 0x004C;
|
||||
public static final int STACCATO_COMMUNICATIONS_INC = 0x004D;
|
||||
public static final int AVAGO_TECHNOLOGIES = 0x004E;
|
||||
public static final int APT_LICENSING_LTD = 0x004F;
|
||||
public static final int SIRF_TECHNOLOGY = 0x0050;
|
||||
public static final int TZERO_TECHNOLOGIES_INC = 0x0051;
|
||||
public static final int JM_CORPORATION = 0x0052;
|
||||
public static final int FREE2MOVE_AB = 0x0053;
|
||||
public static final int THREE_DIJOY_CORPORATION = 0x0054;
|
||||
public static final int PLANTRONICS_INC = 0x0055;
|
||||
public static final int SONY_ERICSSON_MOBILE_COMMUNICATIONS = 0x0056;
|
||||
public static final int HARMAN_INTERNATIONAL_INDUSTRIES_INC = 0x0057;
|
||||
public static final int VIZIO_INC = 0x0058;
|
||||
public static final int NORDIC_SEMICONDUCTOR_ASA = 0x0059;
|
||||
public static final int EM_MICROELECTRONICMARIN_SA = 0x005A;
|
||||
public static final int RALINK_TECHNOLOGY_CORPORATION = 0x005B;
|
||||
public static final int BELKIN_INTERNATIONAL_INC = 0x005C;
|
||||
public static final int REALTEK_SEMICONDUCTOR_CORPORATION = 0x005D;
|
||||
public static final int STONESTREET_ONE_LLC = 0x005E;
|
||||
public static final int WICENTRIC_INC = 0x005F;
|
||||
public static final int RIVIERAWAVES_SAS = 0x0060;
|
||||
public static final int RDA_MICROELECTRONICS = 0x0061;
|
||||
public static final int GIBSON_GUITARS = 0x0062;
|
||||
public static final int MICOMMAND_INC = 0x0063;
|
||||
public static final int BAND_XI_INTERNATIONAL_LLC = 0x0064;
|
||||
public static final int HEWLETTPACKARD_COMPANY = 0x0065;
|
||||
public static final int NINE_SOLUTIONS_OY = 0x0066;
|
||||
public static final int GN_NETCOM_A_S = 0x0067;
|
||||
public static final int GENERAL_MOTORS = 0x0068;
|
||||
public static final int AD_ENGINEERING_INC = 0x0069;
|
||||
public static final int MINDTREE_LTD = 0x006A;
|
||||
public static final int POLAR_ELECTRO_OY = 0x006B;
|
||||
public static final int BEAUTIFUL_ENTERPRISE_CO_LTD = 0x006C;
|
||||
public static final int BRIARTEK_INC = 0x006D;
|
||||
public static final int SUMMIT_DATA_COMMUNICATIONS_INC = 0x006E;
|
||||
public static final int SOUND_ID = 0x006F;
|
||||
public static final int MONSTER_LLC = 0x0070;
|
||||
public static final int CONNECTBLUE_AB = 0x0071;
|
||||
public static final int SHANGHAI_SUPER_SMART_ELECTRONICS_CO_LTD = 0x0072;
|
||||
public static final int GROUP_SENSE_LTD = 0x0073;
|
||||
public static final int ZOMM_LLC = 0x0074;
|
||||
public static final int SAMSUNG_ELECTRONICS_CO_LTD = 0x0075;
|
||||
public static final int CREATIVE_TECHNOLOGY_LTD = 0x0076;
|
||||
public static final int LAIRD_TECHNOLOGIES = 0x0077;
|
||||
public static final int NIKE_INC = 0x0078;
|
||||
public static final int LESSWIRE_AG = 0x0079;
|
||||
public static final int MSTAR_SEMICONDUCTOR_INC = 0x007A;
|
||||
public static final int HANLYNN_TECHNOLOGIES = 0x007B;
|
||||
public static final int A_R_CAMBRIDGE = 0x007C;
|
||||
public static final int SEERS_TECHNOLOGY_CO_LTD = 0x007D;
|
||||
public static final int SPORTS_TRACKING_TECHNOLOGIES_LTD = 0x007E;
|
||||
public static final int AUTONET_MOBILE = 0x007F;
|
||||
public static final int DELORME_PUBLISHING_COMPANY_INC = 0x0080;
|
||||
public static final int WUXI_VIMICRO = 0x0081;
|
||||
public static final int SENNHEISER_COMMUNICATIONS_A_S = 0x0082;
|
||||
public static final int TIMEKEEPING_SYSTEMS_INC = 0x0083;
|
||||
public static final int LUDUS_HELSINKI_LTD = 0x0084;
|
||||
public static final int BLUERADIOS_INC = 0x0085;
|
||||
public static final int EQUINOX_AG = 0x0086;
|
||||
public static final int GARMIN_INTERNATIONAL_INC = 0x0087;
|
||||
public static final int ECOTEST = 0x0088;
|
||||
public static final int GN_RESOUND_A_S = 0x0089;
|
||||
public static final int JAWBONE = 0x008A;
|
||||
public static final int TOPCORN_POSITIONING_SYSTEMS_LLC = 0x008B;
|
||||
public static final int QUALCOMM_RETAIL_SOLUTIONS_INC_FORMERLY_QUALCOMM_LABS_INC = 0x008C;
|
||||
public static final int ZSCAN_SOFTWARE = 0x008D;
|
||||
public static final int QUINTIC_CORP = 0x008E;
|
||||
public static final int STOLLMAN_EV_GMBH = 0x008F;
|
||||
public static final int FUNAI_ELECTRIC_CO_LTD = 0x0090;
|
||||
public static final int ADVANCED_PANMOBIL_SYSTEMS_GMBH_CO_KG = 0x0091;
|
||||
public static final int THINKOPTICS_INC = 0x0092;
|
||||
public static final int UNIVERSAL_ELECTRONICS_INC = 0x0093;
|
||||
public static final int AIROHA_TECHNOLOGY_CORP = 0x0094;
|
||||
public static final int NEC_LIGHTING_LTD = 0x0095;
|
||||
public static final int ODM_TECHNOLOGY_INC = 0x0096;
|
||||
public static final int CONNECTEDEVICE_LTD = 0x0097;
|
||||
public static final int ZER01TV_GMBH = 0x0098;
|
||||
public static final int ITECH_DYNAMIC_GLOBAL_DISTRIBUTION_LTD = 0x0099;
|
||||
public static final int ALPWISE = 0x009A;
|
||||
public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS_CO_LTD = 0x009B;
|
||||
public static final int COLORFY_INC = 0x009C;
|
||||
public static final int GEOFORCE_INC = 0x009D;
|
||||
public static final int BOSE_CORPORATION = 0x009E;
|
||||
public static final int SUUNTO_OY = 0x009F;
|
||||
public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 0x00A0;
|
||||
public static final int SRMEDIZINELEKTRONIK = 0x00A1;
|
||||
public static final int VERTU_CORPORATION_LIMITED = 0x00A2;
|
||||
public static final int META_WATCH_LTD = 0x00A3;
|
||||
public static final int LINAK_A_S = 0x00A4;
|
||||
public static final int OTL_DYNAMICS_LLC = 0x00A5;
|
||||
public static final int PANDA_OCEAN_INC = 0x00A6;
|
||||
public static final int VISTEON_CORPORATION = 0x00A7;
|
||||
public static final int ARP_DEVICES_LIMITED = 0x00A8;
|
||||
public static final int MAGNETI_MARELLI_SPA = 0x00A9;
|
||||
public static final int CAEN_RFID_SRL = 0x00AA;
|
||||
public static final int INGENIEURSYSTEMGRUPPE_ZAHN_GMBH = 0x00AB;
|
||||
public static final int GREEN_THROTTLE_GAMES = 0x00AC;
|
||||
public static final int PETER_SYSTEMTECHNIK_GMBH = 0x00AD;
|
||||
public static final int OMEGAWAVE_OY = 0x00AE;
|
||||
public static final int CINETIX = 0x00AF;
|
||||
public static final int PASSIF_SEMICONDUCTOR_CORP = 0x00B0;
|
||||
public static final int SARIS_CYCLING_GROUP_INC = 0x00B1;
|
||||
public static final int BEKEY_A_S = 0x00B2;
|
||||
public static final int CLARINOX_TECHNOLOGIES_PTY_LTD = 0x00B3;
|
||||
public static final int BDE_TECHNOLOGY_CO_LTD = 0x00B4;
|
||||
public static final int SWIRL_NETWORKS = 0x00B5;
|
||||
public static final int MESO_INTERNATIONAL = 0x00B6;
|
||||
public static final int TRELAB_LTD = 0x00B7;
|
||||
public static final int QUALCOMM_INNOVATION_CENTER_INC_QUIC = 0x00B8;
|
||||
public static final int JOHNSON_CONTROLS_INC = 0x00B9;
|
||||
public static final int STARKEY_LABORATORIES_INC = 0x00BA;
|
||||
public static final int SPOWER_ELECTRONICS_LIMITED = 0x00BB;
|
||||
public static final int ACE_SENSOR_INC = 0x00BC;
|
||||
public static final int APLIX_CORPORATION = 0x00BD;
|
||||
public static final int AAMP_OF_AMERICA = 0x00BE;
|
||||
public static final int STALMART_TECHNOLOGY_LIMITED = 0x00BF;
|
||||
public static final int AMICCOM_ELECTRONICS_CORPORATION = 0x00C0;
|
||||
public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY_COLTD = 0x00C1;
|
||||
public static final int GENEQ_INC = 0x00C2;
|
||||
public static final int ADIDAS_AG = 0x00C3;
|
||||
public static final int LG_ELECTRONICS = 0x00C4;
|
||||
public static final int ONSET_COMPUTER_CORPORATION = 0x00C5;
|
||||
public static final int SELFLY_BV = 0x00C6;
|
||||
public static final int QUUPPA_OY = 0x00C7;
|
||||
public static final int GELO_INC = 0x00C8;
|
||||
public static final int EVLUMA = 0x00C9;
|
||||
public static final int MC10 = 0x00CA;
|
||||
public static final int BINAURIC_SE = 0x00CB;
|
||||
public static final int BEATS_ELECTRONICS = 0x00CC;
|
||||
public static final int MICROCHIP_TECHNOLOGY_INC = 0x00CD;
|
||||
public static final int ELGATO_SYSTEMS_GMBH = 0x00CE;
|
||||
public static final int ARCHOS_SA = 0x00CF;
|
||||
public static final int DEXCOM_INC = 0x00D0;
|
||||
public static final int POLAR_ELECTRO_EUROPE_BV = 0x00D1;
|
||||
public static final int DIALOG_SEMICONDUCTOR_BV = 0x00D2;
|
||||
public static final int TAIXINGBANG_TECHNOLOGY_HK_CO_LTD = 0x00D3;
|
||||
public static final int KAWANTECH = 0x00D4;
|
||||
public static final int AUSTCO_COMMUNICATION_SYSTEMS = 0x00D5;
|
||||
public static final int TIMEX_GROUP_USA_INC = 0x00D6;
|
||||
public static final int QUALCOMM_TECHNOLOGIES_INC = 0x00D7;
|
||||
public static final int QUALCOMM_CONNECTED_EXPERIENCES_INC = 0x00D8;
|
||||
public static final int VOYETRA_TURTLE_BEACH = 0x00D9;
|
||||
public static final int TXTR_GMBH = 0x00DA;
|
||||
public static final int BIOSENTRONICS = 0x00DB;
|
||||
public static final int PROCTER_GAMBLE = 0x00DC;
|
||||
public static final int HOSIDEN_CORPORATION = 0x00DD;
|
||||
public static final int MUZIK_LLC = 0x00DE;
|
||||
public static final int MISFIT_WEARABLES_CORP = 0x00DF;
|
||||
public static final int GOOGLE = 0x00E0;
|
||||
public static final int DANLERS_LTD = 0x00E1;
|
||||
public static final int SEMILINK_INC = 0x00E2;
|
||||
public static final int INMUSIC_BRANDS_INC = 0x00E3;
|
||||
public static final int LS_RESEARCH_INC = 0x00E4;
|
||||
public static final int EDEN_SOFTWARE_CONSULTANTS_LTD = 0x00E5;
|
||||
public static final int FRESHTEMP = 0x00E6;
|
||||
public static final int KS_TECHNOLOGIES = 0x00E7;
|
||||
public static final int ACTS_TECHNOLOGIES = 0x00E8;
|
||||
public static final int VTRACK_SYSTEMS = 0x00E9;
|
||||
public static final int NIELSENKELLERMAN_COMPANY = 0x00EA;
|
||||
public static final int SERVER_TECHNOLOGY_INC = 0x00EB;
|
||||
public static final int BIORESEARCH_ASSOCIATES = 0x00EC;
|
||||
public static final int JOLLY_LOGIC_LLC = 0x00ED;
|
||||
public static final int ABOVE_AVERAGE_OUTCOMES_INC = 0x00EE;
|
||||
public static final int BITSPLITTERS_GMBH = 0x00EF;
|
||||
public static final int PAYPAL_INC = 0x00F0;
|
||||
public static final int WITRON_TECHNOLOGY_LIMITED = 0x00F1;
|
||||
public static final int MORSE_PROJECT_INC = 0x00F2;
|
||||
public static final int KENT_DISPLAYS_INC = 0x00F3;
|
||||
public static final int NAUTILUS_INC = 0x00F4;
|
||||
public static final int SMARTIFIER_OY = 0x00F5;
|
||||
public static final int ELCOMETER_LIMITED = 0x00F6;
|
||||
public static final int VSN_TECHNOLOGIES_INC = 0x00F7;
|
||||
public static final int ACEUNI_CORP_LTD = 0x00F8;
|
||||
public static final int STICKNFIND = 0x00F9;
|
||||
public static final int CRYSTAL_CODE_AB = 0x00FA;
|
||||
public static final int KOUKAAM_AS = 0x00FB;
|
||||
public static final int DELPHI_CORPORATION = 0x00FC;
|
||||
public static final int VALENCETECH_LIMITED = 0x00FD;
|
||||
public static final int RESERVED = 0x00FE;
|
||||
public static final int TYPO_PRODUCTS_LLC = 0x00FF;
|
||||
public static final int TOMTOM_INTERNATIONAL_BV = 0x0100;
|
||||
public static final int FUGOO_INC = 0x0101;
|
||||
public static final int KEISER_CORPORATION = 0x0102;
|
||||
public static final int BANG_OLUFSEN_A_S = 0x0103;
|
||||
public static final int PLUS_LOCATIONS_SYSTEMS_PTY_LTD = 0x0104;
|
||||
public static final int UBIQUITOUS_COMPUTING_TECHNOLOGY_CORPORATION = 0x0105;
|
||||
public static final int INNOVATIVE_YACHTTER_SOLUTIONS = 0x0106;
|
||||
public static final int WILLIAM_DEMANT_HOLDING_A_S = 0x0107;
|
||||
public static final int CHICONY_ELECTRONICS_CO_LTD = 0x0108;
|
||||
public static final int ATUS_BV = 0x0109;
|
||||
public static final int CODEGATE_LTD = 0x010A;
|
||||
public static final int ERI_INC = 0x010B;
|
||||
public static final int TRANSDUCERS_DIRECT_LLC = 0x010C;
|
||||
public static final int FUJITSU_TEN_LIMITED = 0x010D;
|
||||
public static final int AUDI_AG = 0x010E;
|
||||
public static final int HISILICON_TECHNOLOGIES_CO_LTD = 0x010F;
|
||||
public static final int NIPPON_SEIKI_CO_LTD = 0x0110;
|
||||
public static final int STEELSERIES_APS = 0x0111;
|
||||
public static final int VYZYBL_INC = 0x0112;
|
||||
public static final int OPENBRAIN_TECHNOLOGIES_CO_LTD = 0x0113;
|
||||
public static final int XENSR = 0x0114;
|
||||
public static final int ESOLUTIONS = 0x0115;
|
||||
public static final int ONE_OAK_TECHNOLOGIES = 0x0116;
|
||||
public static final int WIMOTO_TECHNOLOGIES_INC = 0x0117;
|
||||
public static final int RADIUS_NETWORKS_INC = 0x0118;
|
||||
public static final int WIZE_TECHNOLOGY_CO_LTD = 0x0119;
|
||||
public static final int QUALCOMM_LABS_INC = 0x011A;
|
||||
public static final int ARUBA_NETWORKS = 0x011B;
|
||||
public static final int BAIDU = 0x011C;
|
||||
public static final int ARENDI_AG = 0x011D;
|
||||
public static final int SKODA_AUTO_AS = 0x011E;
|
||||
public static final int VOLKSWAGON_AG = 0x011F;
|
||||
public static final int PORSCHE_AG = 0x0120;
|
||||
public static final int SINO_WEALTH_ELECTRONIC_LTD = 0x0121;
|
||||
public static final int AIRTURN_INC = 0x0122;
|
||||
public static final int KINSA_INC = 0x0123;
|
||||
public static final int HID_GLOBAL = 0x0124;
|
||||
public static final int SEAT_ES = 0x0125;
|
||||
public static final int PROMETHEAN_LTD = 0x0126;
|
||||
public static final int SALUTICA_ALLIED_SOLUTIONS = 0x0127;
|
||||
public static final int GPSI_GROUP_PTY_LTD = 0x0128;
|
||||
public static final int NIMBLE_DEVICES_OY = 0x0129;
|
||||
public static final int CHANGZHOU_YONGSE_INFOTECH_CO_LTD = 0x012A;
|
||||
public static final int SPORTIQ = 0x012B;
|
||||
public static final int TEMEC_INSTRUMENTS_BV = 0x012C;
|
||||
public static final int SONY_CORPORATION = 0x012D;
|
||||
public static final int ASSA_ABLOY = 0x012E;
|
||||
public static final int CLARION_CO_LTD = 0x012F;
|
||||
public static final int WAREHOUSE_INNOVATIONS = 0x0130;
|
||||
public static final int CYPRESS_SEMICONDUCTOR_CORPORATION = 0x0131;
|
||||
public static final int MADS_INC = 0x0132;
|
||||
public static final int BLUE_MAESTRO_LIMITED = 0x0133;
|
||||
public static final int RESOLUTION_PRODUCTS_INC = 0x0134;
|
||||
public static final int AIREWEAR_LLC = 0x0135;
|
||||
public static final int ETC_SP_ZOO = 0x0136;
|
||||
public static final int PRESTIGIO_PLAZA_LTD = 0x0137;
|
||||
|
||||
private static final SparseArray<String> COMPANY_NAME_MAP = populateCompanyNameMap();
|
||||
|
||||
public static String getCompanyName(final int companyId, final String fallback) {
|
||||
final String name = COMPANY_NAME_MAP.get(companyId);
|
||||
return name == null ? fallback : name;
|
||||
}
|
||||
|
||||
private static SparseArray<String> populateCompanyNameMap() {
|
||||
final SparseArray<String> map = new SparseArray<>();
|
||||
|
||||
map.put(ERICSSON_TECHNOLOGY_LICENSING, "Ericsson Technology Licensing");
|
||||
map.put(NOKIA_MOBILE_PHONES, "Nokia Mobile Phones");
|
||||
map.put(INTEL_CORP, "Intel Corp.");
|
||||
map.put(IBM_CORP, "IBM Corp.");
|
||||
map.put(TOSHIBA_CORP, "Toshiba Corp.");
|
||||
map.put(THREE_COM, "3Com");
|
||||
map.put(MICROSOFT, "Microsoft");
|
||||
map.put(LUCENT, "Lucent");
|
||||
map.put(MOTOROLA, "Motorola");
|
||||
map.put(INFINEON_TECHNOLOGIES_AG, "Infineon Technologies AG");
|
||||
map.put(CAMBRIDGE_SILICON_RADIO, "Cambridge Silicon Radio");
|
||||
map.put(SILICON_WAVE, "Silicon Wave");
|
||||
map.put(DIGIANSWER_A_S, "Digianswer A/S");
|
||||
map.put(TEXAS_INSTRUMENTS_INC, "Texas Instruments Inc.");
|
||||
map.put(CEVA_INC_FORMERLY_PARTHUS_TECHNOLOGIES_INC, "Ceva, Inc. (formerly Parthus Technologies, Inc.)");
|
||||
map.put(BROADCOM_CORPORATION, "Broadcom Corporation");
|
||||
map.put(MITEL_SEMICONDUCTOR, "Mitel Semiconductor");
|
||||
map.put(WIDCOMM_INC, "Widcomm, Inc");
|
||||
map.put(ZEEVO_INC, "Zeevo, Inc.");
|
||||
map.put(ATMEL_CORPORATION, "Atmel Corporation");
|
||||
map.put(MITSUBISHI_ELECTRIC_CORPORATION, "Mitsubishi Electric Corporation");
|
||||
map.put(RTX_TELECOM_A_S, "RTX Telecom A/S");
|
||||
map.put(KC_TECHNOLOGY_INC, "KC Technology Inc.");
|
||||
map.put(NEWLOGIC, "NewLogic");
|
||||
map.put(TRANSILICA_INC, "Transilica, Inc.");
|
||||
map.put(ROHDE_SCHWARZ_GMBH_CO_KG, "Rohde & Schwarz GmbH & Co. KG");
|
||||
map.put(TTPCOM_LIMITED, "TTPCom Limited");
|
||||
map.put(SIGNIA_TECHNOLOGIES_INC, "Signia Technologies, Inc.");
|
||||
map.put(CONEXANT_SYSTEMS_INC, "Conexant Systems Inc.");
|
||||
map.put(QUALCOMM, "Qualcomm");
|
||||
map.put(INVENTEL, "Inventel");
|
||||
map.put(AVM_BERLIN, "AVM Berlin");
|
||||
map.put(BANDSPEED_INC, "BandSpeed, Inc.");
|
||||
map.put(MANSELLA_LTD, "Mansella Ltd");
|
||||
map.put(NEC_CORPORATION, "NEC Corporation");
|
||||
map.put(WAVEPLUS_TECHNOLOGY_CO_LTD, "WavePlus Technology Co., Ltd.");
|
||||
map.put(ALCATEL, "Alcatel");
|
||||
map.put(PHILIPS_SEMICONDUCTORS, "Philips Semiconductors");
|
||||
map.put(C_TECHNOLOGIES, "C Technologies");
|
||||
map.put(OPEN_INTERFACE, "Open Interface");
|
||||
map.put(R_F_MICRO_DEVICES, "R F Micro Devices");
|
||||
map.put(HITACHI_LTD, "Hitachi Ltd");
|
||||
map.put(SYMBOL_TECHNOLOGIES_INC, "Symbol Technologies, Inc.");
|
||||
map.put(TENOVIS, "Tenovis");
|
||||
map.put(MACRONIX_INTERNATIONAL_CO_LTD, "Macronix International Co. Ltd.");
|
||||
map.put(GCT_SEMICONDUCTOR, "GCT Semiconductor");
|
||||
map.put(NORWOOD_SYSTEMS, "Norwood Systems");
|
||||
map.put(MEWTEL_TECHNOLOGY_INC, "MewTel Technology Inc.");
|
||||
map.put(ST_MICROELECTRONICS, "ST Microelectronics");
|
||||
map.put(SYNOPSIS, "Synopsis");
|
||||
map.put(REDM_COMMUNICATIONS_LTD, "Red-M (Communications) Ltd");
|
||||
map.put(COMMIL_LTD, "Commil Ltd");
|
||||
map.put(COMPUTER_ACCESS_TECHNOLOGY_CORPORATION_CATC, "Computer Access Technology Corporation (CATC)");
|
||||
map.put(ECLIPSE_HQ_ESPANA_SL, "Eclipse (HQ Espana) S.L.");
|
||||
map.put(RENESAS_TECHNOLOGY_CORP, "Renesas Technology Corp.");
|
||||
map.put(MOBILIAN_CORPORATION, "Mobilian Corporation");
|
||||
map.put(TERAX, "Terax");
|
||||
map.put(INTEGRATED_SYSTEM_SOLUTION_CORP, "Integrated System Solution Corp.");
|
||||
map.put(MATSUSHITA_ELECTRIC_INDUSTRIAL_CO_LTD, "Matsushita Electric Industrial Co., Ltd.");
|
||||
map.put(GENNUM_CORPORATION, "Gennum Corporation");
|
||||
map.put(RESEARCH_IN_MOTION, "Research In Motion");
|
||||
map.put(IPEXTREME_INC, "IPextreme, Inc.");
|
||||
map.put(SYSTEMS_AND_CHIPS_INC, "Systems and Chips, Inc.");
|
||||
map.put(BLUETOOTH_SIG_INC, "Bluetooth SIG, Inc.");
|
||||
map.put(SEIKO_EPSON_CORPORATION, "Seiko Epson Corporation");
|
||||
map.put(INTEGRATED_SILICON_SOLUTION_TAIWAN_INC, "Integrated Silicon Solution Taiwan, Inc.");
|
||||
map.put(CONWISE_TECHNOLOGY_CORPORATION_LTD, "CONWISE Technology Corporation Ltd");
|
||||
map.put(PARROT_SA, "PARROT SA");
|
||||
map.put(SOCKET_MOBILE, "Socket Mobile");
|
||||
map.put(ATHEROS_COMMUNICATIONS_INC, "Atheros Communications, Inc.");
|
||||
map.put(MEDIATEK_INC, "MediaTek, Inc.");
|
||||
map.put(BLUEGIGA, "Bluegiga");
|
||||
map.put(MARVELL_TECHNOLOGY_GROUP_LTD, "Marvell Technology Group Ltd.");
|
||||
map.put(THREE_DSP_CORPORATION, "3DSP Corporation");
|
||||
map.put(ACCEL_SEMICONDUCTOR_LTD, "Accel Semiconductor Ltd.");
|
||||
map.put(CONTINENTAL_AUTOMOTIVE_SYSTEMS, "Continental Automotive Systems");
|
||||
map.put(APPLE_INC, "Apple, Inc.");
|
||||
map.put(STACCATO_COMMUNICATIONS_INC, "Staccato Communications, Inc.");
|
||||
map.put(AVAGO_TECHNOLOGIES, "Avago Technologies");
|
||||
map.put(APT_LICENSING_LTD, "APT Licensing Ltd.");
|
||||
map.put(SIRF_TECHNOLOGY, "SiRF Technology");
|
||||
map.put(TZERO_TECHNOLOGIES_INC, "Tzero Technologies, Inc.");
|
||||
map.put(JM_CORPORATION, "J&M Corporation");
|
||||
map.put(FREE2MOVE_AB, "Free2move AB");
|
||||
map.put(THREE_DIJOY_CORPORATION, "3DiJoy Corporation");
|
||||
map.put(PLANTRONICS_INC, "Plantronics, Inc.");
|
||||
map.put(SONY_ERICSSON_MOBILE_COMMUNICATIONS, "Sony Ericsson Mobile Communications");
|
||||
map.put(HARMAN_INTERNATIONAL_INDUSTRIES_INC, "Harman International Industries, Inc.");
|
||||
map.put(VIZIO_INC, "Vizio, Inc.");
|
||||
map.put(NORDIC_SEMICONDUCTOR_ASA, "Nordic Semiconductor ASA");
|
||||
map.put(EM_MICROELECTRONICMARIN_SA, "EM Microelectronic-Marin SA");
|
||||
map.put(RALINK_TECHNOLOGY_CORPORATION, "Ralink Technology Corporation");
|
||||
map.put(BELKIN_INTERNATIONAL_INC, "Belkin International, Inc.");
|
||||
map.put(REALTEK_SEMICONDUCTOR_CORPORATION, "Realtek Semiconductor Corporation");
|
||||
map.put(STONESTREET_ONE_LLC, "Stonestreet One, LLC");
|
||||
map.put(WICENTRIC_INC, "Wicentric, Inc.");
|
||||
map.put(RIVIERAWAVES_SAS, "RivieraWaves S.A.S");
|
||||
map.put(RDA_MICROELECTRONICS, "RDA Microelectronics");
|
||||
map.put(GIBSON_GUITARS, "Gibson Guitars");
|
||||
map.put(MICOMMAND_INC, "MiCommand Inc.");
|
||||
map.put(BAND_XI_INTERNATIONAL_LLC, "Band XI International, LLC");
|
||||
map.put(HEWLETTPACKARD_COMPANY, "Hewlett-Packard Company");
|
||||
map.put(NINE_SOLUTIONS_OY, "9Solutions Oy");
|
||||
map.put(GN_NETCOM_A_S, "GN Netcom A/S");
|
||||
map.put(GENERAL_MOTORS, "General Motors");
|
||||
map.put(AD_ENGINEERING_INC, "A&D Engineering, Inc.");
|
||||
map.put(MINDTREE_LTD, "MindTree Ltd.");
|
||||
map.put(POLAR_ELECTRO_OY, "Polar Electro OY");
|
||||
map.put(BEAUTIFUL_ENTERPRISE_CO_LTD, "Beautiful Enterprise Co., Ltd.");
|
||||
map.put(BRIARTEK_INC, "BriarTek, Inc.");
|
||||
map.put(SUMMIT_DATA_COMMUNICATIONS_INC, "Summit Data Communications, Inc.");
|
||||
map.put(SOUND_ID, "Sound ID");
|
||||
map.put(MONSTER_LLC, "Monster, LLC");
|
||||
map.put(CONNECTBLUE_AB, "connectBlue AB");
|
||||
map.put(SHANGHAI_SUPER_SMART_ELECTRONICS_CO_LTD, "ShangHai Super Smart Electronics Co. Ltd.");
|
||||
map.put(GROUP_SENSE_LTD, "Group Sense Ltd.");
|
||||
map.put(ZOMM_LLC, "Zomm, LLC");
|
||||
map.put(SAMSUNG_ELECTRONICS_CO_LTD, "Samsung Electronics Co. Ltd.");
|
||||
map.put(CREATIVE_TECHNOLOGY_LTD, "Creative Technology Ltd.");
|
||||
map.put(LAIRD_TECHNOLOGIES, "Laird Technologies");
|
||||
map.put(NIKE_INC, "Nike, Inc.");
|
||||
map.put(LESSWIRE_AG, "lesswire AG");
|
||||
map.put(MSTAR_SEMICONDUCTOR_INC, "MStar Semiconductor, Inc.");
|
||||
map.put(HANLYNN_TECHNOLOGIES, "Hanlynn Technologies");
|
||||
map.put(A_R_CAMBRIDGE, "A & R Cambridge");
|
||||
map.put(SEERS_TECHNOLOGY_CO_LTD, "Seers Technology Co. Ltd");
|
||||
map.put(SPORTS_TRACKING_TECHNOLOGIES_LTD, "Sports Tracking Technologies Ltd.");
|
||||
map.put(AUTONET_MOBILE, "Autonet Mobile");
|
||||
map.put(DELORME_PUBLISHING_COMPANY_INC, "DeLorme Publishing Company, Inc.");
|
||||
map.put(WUXI_VIMICRO, "WuXi Vimicro");
|
||||
map.put(SENNHEISER_COMMUNICATIONS_A_S, "Sennheiser Communications A/S");
|
||||
map.put(TIMEKEEPING_SYSTEMS_INC, "TimeKeeping Systems, Inc.");
|
||||
map.put(LUDUS_HELSINKI_LTD, "Ludus Helsinki Ltd.");
|
||||
map.put(BLUERADIOS_INC, "BlueRadios, Inc.");
|
||||
map.put(EQUINOX_AG, "equinox AG");
|
||||
map.put(GARMIN_INTERNATIONAL_INC, "Garmin International, Inc.");
|
||||
map.put(ECOTEST, "Ecotest");
|
||||
map.put(GN_RESOUND_A_S, "GN ReSound A/S");
|
||||
map.put(JAWBONE, "Jawbone");
|
||||
map.put(TOPCORN_POSITIONING_SYSTEMS_LLC, "Topcorn Positioning Systems, LLC");
|
||||
map.put(QUALCOMM_RETAIL_SOLUTIONS_INC_FORMERLY_QUALCOMM_LABS_INC, "Qualcomm Retail Solutions, Inc. (formerly Qualcomm Labs, Inc.)");
|
||||
map.put(ZSCAN_SOFTWARE, "Zscan Software");
|
||||
map.put(QUINTIC_CORP, "Quintic Corp.");
|
||||
map.put(STOLLMAN_EV_GMBH, "Stollman E+V GmbH");
|
||||
map.put(FUNAI_ELECTRIC_CO_LTD, "Funai Electric Co., Ltd.");
|
||||
map.put(ADVANCED_PANMOBIL_SYSTEMS_GMBH_CO_KG, "Advanced PANMOBIL Systems GmbH & Co. KG");
|
||||
map.put(THINKOPTICS_INC, "ThinkOptics, Inc.");
|
||||
map.put(UNIVERSAL_ELECTRONICS_INC, "Universal Electronics, Inc.");
|
||||
map.put(AIROHA_TECHNOLOGY_CORP, "Airoha Technology Corp.");
|
||||
map.put(NEC_LIGHTING_LTD, "NEC Lighting, Ltd.");
|
||||
map.put(ODM_TECHNOLOGY_INC, "ODM Technology, Inc.");
|
||||
map.put(CONNECTEDEVICE_LTD, "ConnecteDevice Ltd.");
|
||||
map.put(ZER01TV_GMBH, "zer01.tv GmbH");
|
||||
map.put(ITECH_DYNAMIC_GLOBAL_DISTRIBUTION_LTD, "i.Tech Dynamic Global Distribution Ltd.");
|
||||
map.put(ALPWISE, "Alpwise");
|
||||
map.put(JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS_CO_LTD, "Jiangsu Toppower Automotive Electronics Co., Ltd.");
|
||||
map.put(COLORFY_INC, "Colorfy, Inc.");
|
||||
map.put(GEOFORCE_INC, "Geoforce Inc.");
|
||||
map.put(BOSE_CORPORATION, "Bose Corporation");
|
||||
map.put(SUUNTO_OY, "Suunto Oy");
|
||||
map.put(KENSINGTON_COMPUTER_PRODUCTS_GROUP, "Kensington Computer Products Group");
|
||||
map.put(SRMEDIZINELEKTRONIK, "SR-Medizinelektronik");
|
||||
map.put(VERTU_CORPORATION_LIMITED, "Vertu Corporation Limited");
|
||||
map.put(META_WATCH_LTD, "Meta Watch Ltd.");
|
||||
map.put(LINAK_A_S, "LINAK A/S");
|
||||
map.put(OTL_DYNAMICS_LLC, "OTL Dynamics LLC");
|
||||
map.put(PANDA_OCEAN_INC, "Panda Ocean Inc.");
|
||||
map.put(VISTEON_CORPORATION, "Visteon Corporation");
|
||||
map.put(ARP_DEVICES_LIMITED, "ARP Devices Limited");
|
||||
map.put(MAGNETI_MARELLI_SPA, "Magneti Marelli S.p.A");
|
||||
map.put(CAEN_RFID_SRL, "CAEN RFID srl");
|
||||
map.put(INGENIEURSYSTEMGRUPPE_ZAHN_GMBH, "Ingenieur-Systemgruppe Zahn GmbH");
|
||||
map.put(GREEN_THROTTLE_GAMES, "Green Throttle Games");
|
||||
map.put(PETER_SYSTEMTECHNIK_GMBH, "Peter Systemtechnik GmbH");
|
||||
map.put(OMEGAWAVE_OY, "Omegawave Oy");
|
||||
map.put(CINETIX, "Cinetix");
|
||||
map.put(PASSIF_SEMICONDUCTOR_CORP, "Passif Semiconductor Corp");
|
||||
map.put(SARIS_CYCLING_GROUP_INC, "Saris Cycling Group, Inc");
|
||||
map.put(BEKEY_A_S, "Bekey A/S");
|
||||
map.put(CLARINOX_TECHNOLOGIES_PTY_LTD, "Clarinox Technologies Pty. Ltd.");
|
||||
map.put(BDE_TECHNOLOGY_CO_LTD, "BDE Technology Co., Ltd.");
|
||||
map.put(SWIRL_NETWORKS, "Swirl Networks");
|
||||
map.put(MESO_INTERNATIONAL, "Meso international");
|
||||
map.put(TRELAB_LTD, "TreLab Ltd");
|
||||
map.put(QUALCOMM_INNOVATION_CENTER_INC_QUIC, "Qualcomm Innovation Center, Inc. (QuIC)");
|
||||
map.put(JOHNSON_CONTROLS_INC, "Johnson Controls, Inc.");
|
||||
map.put(STARKEY_LABORATORIES_INC, "Starkey Laboratories Inc.");
|
||||
map.put(SPOWER_ELECTRONICS_LIMITED, "S-Power Electronics Limited");
|
||||
map.put(ACE_SENSOR_INC, "Ace Sensor Inc");
|
||||
map.put(APLIX_CORPORATION, "Aplix Corporation");
|
||||
map.put(AAMP_OF_AMERICA, "AAMP of America");
|
||||
map.put(STALMART_TECHNOLOGY_LIMITED, "Stalmart Technology Limited");
|
||||
map.put(AMICCOM_ELECTRONICS_CORPORATION, "AMICCOM Electronics Corporation");
|
||||
map.put(SHENZHEN_EXCELSECU_DATA_TECHNOLOGY_COLTD, "Shenzhen Excelsecu Data Technology Co.,Ltd");
|
||||
map.put(GENEQ_INC, "Geneq Inc.");
|
||||
map.put(ADIDAS_AG, "adidas AG");
|
||||
map.put(LG_ELECTRONICS, "LG Electronics");
|
||||
map.put(ONSET_COMPUTER_CORPORATION, "Onset Computer Corporation");
|
||||
map.put(SELFLY_BV, "Selfly BV");
|
||||
map.put(QUUPPA_OY, "Quuppa Oy.");
|
||||
map.put(GELO_INC, "GeLo Inc");
|
||||
map.put(EVLUMA, "Evluma");
|
||||
map.put(MC10, "MC10");
|
||||
map.put(BINAURIC_SE, "Binauric SE");
|
||||
map.put(BEATS_ELECTRONICS, "Beats Electronics");
|
||||
map.put(MICROCHIP_TECHNOLOGY_INC, "Microchip Technology Inc.");
|
||||
map.put(ELGATO_SYSTEMS_GMBH, "Elgato Systems GmbH");
|
||||
map.put(ARCHOS_SA, "ARCHOS SA");
|
||||
map.put(DEXCOM_INC, "Dexcom, Inc.");
|
||||
map.put(POLAR_ELECTRO_EUROPE_BV, "Polar Electro Europe B.V.");
|
||||
map.put(DIALOG_SEMICONDUCTOR_BV, "Dialog Semiconductor B.V.");
|
||||
map.put(TAIXINGBANG_TECHNOLOGY_HK_CO_LTD, "Taixingbang Technology (HK) Co,. LTD.");
|
||||
map.put(KAWANTECH, "Kawantech");
|
||||
map.put(AUSTCO_COMMUNICATION_SYSTEMS, "Austco Communication Systems");
|
||||
map.put(TIMEX_GROUP_USA_INC, "Timex Group USA, Inc.");
|
||||
map.put(QUALCOMM_TECHNOLOGIES_INC, "Qualcomm Technologies, Inc.");
|
||||
map.put(QUALCOMM_CONNECTED_EXPERIENCES_INC, "Qualcomm Connected Experiences, Inc.");
|
||||
map.put(VOYETRA_TURTLE_BEACH, "Voyetra Turtle Beach");
|
||||
map.put(TXTR_GMBH, "txtr GmbH");
|
||||
map.put(BIOSENTRONICS, "Biosentronics");
|
||||
map.put(PROCTER_GAMBLE, "Procter & Gamble");
|
||||
map.put(HOSIDEN_CORPORATION, "Hosiden Corporation");
|
||||
map.put(MUZIK_LLC, "Muzik LLC");
|
||||
map.put(MISFIT_WEARABLES_CORP, "Misfit Wearables Corp");
|
||||
map.put(GOOGLE, "Google");
|
||||
map.put(DANLERS_LTD, "Danlers Ltd");
|
||||
map.put(SEMILINK_INC, "Semilink Inc");
|
||||
map.put(INMUSIC_BRANDS_INC, "inMusic Brands, Inc");
|
||||
map.put(LS_RESEARCH_INC, "L.S. Research Inc.");
|
||||
map.put(EDEN_SOFTWARE_CONSULTANTS_LTD, "Eden Software Consultants Ltd.");
|
||||
map.put(FRESHTEMP, "Freshtemp");
|
||||
map.put(KS_TECHNOLOGIES, "KS Technologies");
|
||||
map.put(ACTS_TECHNOLOGIES, "ACTS Technologies");
|
||||
map.put(VTRACK_SYSTEMS, "Vtrack Systems");
|
||||
map.put(NIELSENKELLERMAN_COMPANY, "Nielsen-Kellerman Company");
|
||||
map.put(SERVER_TECHNOLOGY_INC, "Server Technology, Inc.");
|
||||
map.put(BIORESEARCH_ASSOCIATES, "BioResearch Associates");
|
||||
map.put(JOLLY_LOGIC_LLC, "Jolly Logic, LLC");
|
||||
map.put(ABOVE_AVERAGE_OUTCOMES_INC, "Above Average Outcomes, Inc.");
|
||||
map.put(BITSPLITTERS_GMBH, "Bitsplitters GmbH");
|
||||
map.put(PAYPAL_INC, "PayPal, Inc.");
|
||||
map.put(WITRON_TECHNOLOGY_LIMITED, "Witron Technology Limited");
|
||||
map.put(MORSE_PROJECT_INC, "Morse Project Inc.");
|
||||
map.put(KENT_DISPLAYS_INC, "Kent Displays Inc.");
|
||||
map.put(NAUTILUS_INC, "Nautilus Inc.");
|
||||
map.put(SMARTIFIER_OY, "Smartifier Oy");
|
||||
map.put(ELCOMETER_LIMITED, "Elcometer Limited");
|
||||
map.put(VSN_TECHNOLOGIES_INC, "VSN Technologies Inc.");
|
||||
map.put(ACEUNI_CORP_LTD, "AceUni Corp., Ltd.");
|
||||
map.put(STICKNFIND, "StickNFind");
|
||||
map.put(CRYSTAL_CODE_AB, "Crystal Code AB");
|
||||
map.put(KOUKAAM_AS, "KOUKAAM a.s.");
|
||||
map.put(DELPHI_CORPORATION, "Delphi Corporation");
|
||||
map.put(VALENCETECH_LIMITED, "ValenceTech Limited");
|
||||
map.put(RESERVED, "Reserved");
|
||||
map.put(TYPO_PRODUCTS_LLC, "Typo Products, LLC");
|
||||
map.put(TOMTOM_INTERNATIONAL_BV, "TomTom International BV");
|
||||
map.put(FUGOO_INC, "Fugoo, Inc");
|
||||
map.put(KEISER_CORPORATION, "Keiser Corporation");
|
||||
map.put(BANG_OLUFSEN_A_S, "Bang & Olufsen A/S");
|
||||
map.put(PLUS_LOCATIONS_SYSTEMS_PTY_LTD, "PLUS Locations Systems Pty Ltd");
|
||||
map.put(UBIQUITOUS_COMPUTING_TECHNOLOGY_CORPORATION, "Ubiquitous Computing Technology Corporation");
|
||||
map.put(INNOVATIVE_YACHTTER_SOLUTIONS, "Innovative Yachtter Solutions");
|
||||
map.put(WILLIAM_DEMANT_HOLDING_A_S, "William Demant Holding A/S");
|
||||
map.put(CHICONY_ELECTRONICS_CO_LTD, "Chicony Electronics Co., Ltd.");
|
||||
map.put(ATUS_BV, "Atus BV");
|
||||
map.put(CODEGATE_LTD, "Codegate Ltd.");
|
||||
map.put(ERI_INC, "ERi, Inc.");
|
||||
map.put(TRANSDUCERS_DIRECT_LLC, "Transducers Direct, LLC");
|
||||
map.put(FUJITSU_TEN_LIMITED, "Fujitsu Ten Limited");
|
||||
map.put(AUDI_AG, "Audi AG");
|
||||
map.put(HISILICON_TECHNOLOGIES_CO_LTD, "HiSilicon Technologies Co., Ltd.");
|
||||
map.put(NIPPON_SEIKI_CO_LTD, "Nippon Seiki Co., Ltd.");
|
||||
map.put(STEELSERIES_APS, "Steelseries ApS");
|
||||
map.put(VYZYBL_INC, "vyzybl Inc.");
|
||||
map.put(OPENBRAIN_TECHNOLOGIES_CO_LTD, "Openbrain Technologies, Co., Ltd.");
|
||||
map.put(XENSR, "Xensr");
|
||||
map.put(ESOLUTIONS, "e.solutions");
|
||||
map.put(ONE_OAK_TECHNOLOGIES, "1OAK Technologies");
|
||||
map.put(WIMOTO_TECHNOLOGIES_INC, "Wimoto Technologies Inc");
|
||||
map.put(RADIUS_NETWORKS_INC, "Radius Networks, Inc.");
|
||||
map.put(WIZE_TECHNOLOGY_CO_LTD, "Wize Technology Co., Ltd.");
|
||||
map.put(QUALCOMM_LABS_INC, "Qualcomm Labs, Inc.");
|
||||
map.put(ARUBA_NETWORKS, "Aruba Networks");
|
||||
map.put(BAIDU, "Baidu");
|
||||
map.put(ARENDI_AG, "Arendi AG");
|
||||
map.put(SKODA_AUTO_AS, "Skoda Auto a.s.");
|
||||
map.put(VOLKSWAGON_AG, "Volkswagon AG");
|
||||
map.put(PORSCHE_AG, "Porsche AG");
|
||||
map.put(SINO_WEALTH_ELECTRONIC_LTD, "Sino Wealth Electronic Ltd.");
|
||||
map.put(AIRTURN_INC, "AirTurn, Inc.");
|
||||
map.put(KINSA_INC, "Kinsa, Inc.");
|
||||
map.put(HID_GLOBAL, "HID Global");
|
||||
map.put(SEAT_ES, "SEAT es");
|
||||
map.put(PROMETHEAN_LTD, "Promethean Ltd.");
|
||||
map.put(SALUTICA_ALLIED_SOLUTIONS, "Salutica Allied Solutions");
|
||||
map.put(GPSI_GROUP_PTY_LTD, "GPSI Group Pty Ltd");
|
||||
map.put(NIMBLE_DEVICES_OY, "Nimble Devices Oy");
|
||||
map.put(CHANGZHOU_YONGSE_INFOTECH_CO_LTD, "Changzhou Yongse Infotech Co., Ltd");
|
||||
map.put(SPORTIQ, "SportIQ");
|
||||
map.put(TEMEC_INSTRUMENTS_BV, "TEMEC Instruments B.V.");
|
||||
map.put(SONY_CORPORATION, "Sony Corporation");
|
||||
map.put(ASSA_ABLOY, "ASSA ABLOY");
|
||||
map.put(CLARION_CO_LTD, "Clarion Co., Ltd.");
|
||||
map.put(WAREHOUSE_INNOVATIONS, "Warehouse Innovations");
|
||||
map.put(CYPRESS_SEMICONDUCTOR_CORPORATION, "Cypress Semiconductor Corporation");
|
||||
map.put(MADS_INC, "MADS Inc");
|
||||
map.put(BLUE_MAESTRO_LIMITED, "Blue Maestro Limited");
|
||||
map.put(RESOLUTION_PRODUCTS_INC, "Resolution Products, Inc.");
|
||||
map.put(AIREWEAR_LLC, "Airewear LLC");
|
||||
map.put(ETC_SP_ZOO, "ETC sp. z.o.o.");
|
||||
map.put(PRESTIGIO_PLAZA_LTD, "Prestigio Plaza Ltd.");
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,378 @@
|
||||
package com.qidian.baseble.model.resolver;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: Bluetooth服务发现协议(SDP)规格
|
||||
* 参考:https://www.bluetooth.com/zh-cn/specifications/assigned-numbers/service-discovery
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/7 21:49.
|
||||
*/
|
||||
public class GattAttributeResolver {
|
||||
public static final String BASE_GUID = "00000000-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_PROTOCOL_SDP = "00000001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String USER_DATAGRAM_PROTOCOL_UDP = "00000002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM = "00000003-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCP = "00000004-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSBIN = "00000005-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSAT = "00000006-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBJECT_EXCHANGE_PROTOCOL_OBEX = "00000008-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IP = "00000009-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FTP = "0000000a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HTTP = "0000000c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WSP = "0000000e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BNEP_SVC = "0000000f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_PROTOCOL = "00000010-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HIDP = "00000011-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CONTROL_CHANNEL_PROTOCOL = "00000012-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_DATA_CHANNEL_PROTOCOL = "00000014-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_NOTIFICATION_PROTOCOL = "00000016-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VCTP_PROTOCOL = "00000017-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VDTP_PROTOCOL = "00000019-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CMPT_PROTOCOL = "0000001b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDI_C_PLANE_PROTOCOL = "0000001d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_CONTROL_CHANNEL = "0000001e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_DATA_CHANNEL = "0000001f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String L2CAP = "00000100-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_SERVER = "00001000-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BROWSE_GROUP_DESCRIPTOR = "00001001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PUBLIC_BROWSE_GROUP = "00001002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SPP = "00001101-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LAN_ACCESS_USING_PPP = "00001102-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DUN_GW = "00001103-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_SYNC = "00001104-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_OBJECT_PUSH = "00001105-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_FILE_TRANSFER = "00001106-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IRMC_SYNC_COMMAND = "00001107-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HSP_HS = "00001108-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CORDLESS_TELEPHONY = "00001109-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SOURCE = "0000110a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SINK = "0000110b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AV_REMOTE_CONTROL_TARGET = "0000110c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ADVANCED_AUDIO = "0000110d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AVRCP_REMOTE = "0000110e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING = "0000110f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERCOM = "00001110-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FAX = "00001111-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEADSET_PROFILE_HSP_AUDIO_GATEWAY = "00001112-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP = "00001113-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP_CLIENT = "00001114-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PANU = "00001115-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NAP = "00001116-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GN = "00001117-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING = "00001118-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_PRINTING = "00001119-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING = "0000111a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_RESPONDER = "0000111b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_AUTOMATIC_ARCHIVE = "0000111c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_REFERENCE_OBJECTS = "0000111d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP = "0000111e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY = "0000111f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING_REFERENCE_OBJECTS = "00001120-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFLECTED_UI = "00001121-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BASIC_PRINTING = "00001122-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PRINTING_STATUS = "00001123-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HID = "00001124-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CABLE_REPLACEMENT = "00001125-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_PRINT = "00001126-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_SCAN = "00001127-0000-1000-8000-00805f9b34fb";
|
||||
public static final String COMMON_ISDN_ACCESS = "00001128-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING_GATEWAY = "00001129-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDIMT = "0000112a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDITA = "0000112b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_VIDEO = "0000112c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SIM_ACCESS = "0000112d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PCE = "0000112e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PSE = "0000112f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PBAP = "00001130-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAS = "00001132-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MNS = "00001133-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAP = "00001134-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNP = "00001200-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_NETWORKING = "00001201-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_FILE_TRANSFER = "00001202-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_AUDIO = "00001203-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_TELEPHONY = "00001204-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP = "00001205-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_IP = "00001206-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_PAN = "00001300-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_LAP = "00001301-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_L2CAP = "00001302-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE = "00001303-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SINK = "00001304-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP = "00001305-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP = "00001400-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SOURCE = "00001401-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SINK = "00001402-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GAP = "00001800-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GATT = "00001801-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMMEDIATE_ALERT = "00001802-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LINK_LOSS = "00001803-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER = "00001804-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_THERMOMETER = "00001809-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_INFORMATION = "0000180a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE = "0000180d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CYCLING_SC = "00001816-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_NAME = "00002a00-0000-1000-8000-00805f9b34fb";
|
||||
public static final String APPEARANCE = "00002a01-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PRIVACY_FLAG = "00002a02-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RECONNECTION_ADDRESS = "00002a03-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS = "00002a04-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_CHANGED = "00002a05-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_LEVEL = "00002a06-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER_LEVEL = "00002a07-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DATE_TIME = "00002a08-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_OF_WEEK = "00002a09-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_DATE_TIME = "00002a0a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String EXACT_TIME_256 = "00002a0c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DST_OFFSET = "00002a0d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ZONE = "00002a0e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LOCAL_TIME_INFORMATION = "00002a0f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_WITH_DST = "00002a11-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ACCURACY = "00002a12-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_SOURCE = "00002a13-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_TIME_INFORMATION = "00002a14-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_CONTROL_POINT = "00002a16-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_STATE = "00002a17-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_MEASUREMENT = "00002a1c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_TYPE = "00002a1d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_TEMPERATURE = "00002a1e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MEASUREMENT_INTERVAL = "00002a21-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SYSTEM_ID = "00002a23-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MODEL_NUMBER_STRING = "00002a24-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERIAL_NUMBER_STRING = "00002a25-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FIRMWARE_REVISION_STRING = "00002a26-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDWARE_REVISION_STRING = "00002a27-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SOFTWARE_REVISION_STRING = "00002a28-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MANUFACTURER_NAME_STRING = "00002a29-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IEEE_1107320601_REGULATORY = "00002a2a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CURRENT_TIME = "00002a2b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_MEASUREMENT = "00002a35-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_CUFF_PRESSURE = "00002a36-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_MEASUREMENT = "00002a37-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BODY_SENSOR_LOCATION = "00002a38-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_CONTROL_POINT = "00002a39-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_STATUS = "00002a3f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_CONTROL_POINT = "00002a40-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_SETTING = "00002a41-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID_BIT_MASK = "00002a42-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID = "00002a43-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_NOTIFICATION_CONTROL_POINT = "00002a44-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UNREAD_ALERT_STATUS = "00002a45-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NEW_ALERT = "00002a46-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_NEW_ALERT_CATEGORY = "00002a47-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_UNREAD_ALERT_CATEGORY = "00002a48-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_FEATURE = "00002a49-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNPID = "00002a50-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SC_CONTROL_POINT = "00002a55-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_MEASUREMENT = "00002a5b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_FEATURE = "00002a5c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SENSOR_LOCATION = "00002a5d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ACTIVESYNC = "831c4071-7bc8-4a9c-a01c-15df25a4adbc";
|
||||
public static final String ESTIMOTE_SERVICE = "b9403000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_UUID = "b9403003-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MAJOR = "b9403001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MINOR = "b9403002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_BATTERY = "b9403041-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_TEMPERATURE = "b9403021-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_POWER = "b9403011-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_INTERVAL = "b9403012-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_VERSION_SERVICE = "b9404000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_SOFTWARE_VERSION = "b9404001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_HARDWARE_VERSION = "b9404002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_AUTHENTICATION_SERVICE = "b9402000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_SEED = "b9402001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_VECTOR = "b9402002-f5f8-466e-aff9-25556b57fe6d";
|
||||
|
||||
private final static Map<String, String> sGattAttributesMap = populateGattAttributesMap();
|
||||
|
||||
public static String getAttributeName(final String uuid, final String fallback) {
|
||||
final String name = sGattAttributesMap.get(uuid.toLowerCase(Locale.US));
|
||||
return name == null ? fallback : name;
|
||||
}
|
||||
|
||||
private static Map<String, String> populateGattAttributesMap() {
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
|
||||
map.put(BASE_GUID, "Base GUID");
|
||||
map.put(SERVICE_DISCOVERY_PROTOCOL_SDP, "Service Discovery Protocol (SDP)");
|
||||
map.put(USER_DATAGRAM_PROTOCOL_UDP, "User Datagram Protocol (UDP)");
|
||||
map.put(RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM, "Radio Frequency Communication Protocol (RFCOMM)");
|
||||
map.put(TCP, "TCP");
|
||||
map.put(TCSBIN, "TCSBIN");
|
||||
map.put(TCSAT, "TCSAT");
|
||||
map.put(OBJECT_EXCHANGE_PROTOCOL_OBEX, "Object Exchange Protocol (OBEX)");
|
||||
map.put(IP, "IP");
|
||||
map.put(FTP, "FTP");
|
||||
map.put(HTTP, "HTTP");
|
||||
map.put(WSP, "WSP");
|
||||
map.put(BNEP_SVC, "BNEP_SVC");
|
||||
map.put(UPNP_PROTOCOL, "UPNP Protocol");
|
||||
map.put(HIDP, "HIDP");
|
||||
map.put(HARDCOPY_CONTROL_CHANNEL_PROTOCOL, "Hardcopy Control Channel Protocol");
|
||||
map.put(HARDCOPY_DATA_CHANNEL_PROTOCOL, "Hardcopy Data Channel Protocol");
|
||||
map.put(HARDCOPY_NOTIFICATION_PROTOCOL, "Hardcopy Notification Protocol");
|
||||
map.put(VCTP_PROTOCOL, "VCTP Protocol");
|
||||
map.put(VDTP_PROTOCOL, "VDTP Protocol");
|
||||
map.put(CMPT_PROTOCOL, "CMPT Protocol");
|
||||
map.put(UDI_C_PLANE_PROTOCOL, "UDI C Plane Protocol");
|
||||
map.put(MCAP_CONTROL_CHANNEL, "MCAP Control Channel");
|
||||
map.put(MCAP_DATA_CHANNEL, "MCAP Data Channel");
|
||||
map.put(L2CAP, "L2CAP");
|
||||
map.put(SERVICE_DISCOVERY_SERVER, "Service Discovery Server");
|
||||
map.put(BROWSE_GROUP_DESCRIPTOR, "Browse Group Descriptor");
|
||||
map.put(PUBLIC_BROWSE_GROUP, "Public Browse Group");
|
||||
map.put(SPP, "SPP");
|
||||
map.put(LAN_ACCESS_USING_PPP, "LAN Access Using PPP");
|
||||
map.put(DUN_GW, "DUN_GW");
|
||||
map.put(OBEX_SYNC, "OBEX_SYNC");
|
||||
map.put(OBEX_OBJECT_PUSH, "OBEX Object Push");
|
||||
map.put(OBEX_FILE_TRANSFER, "OBEX File Transfer");
|
||||
map.put(IRMC_SYNC_COMMAND, "IrMC Sync Command");
|
||||
map.put(HSP_HS, "HSP_HS");
|
||||
map.put(CORDLESS_TELEPHONY, "Cordless Telephony");
|
||||
map.put(AUDIO_SOURCE, "Audio Source");
|
||||
map.put(AUDIO_SINK, "Audio Sink");
|
||||
map.put(AV_REMOTE_CONTROL_TARGET, "AV Remote Control Target");
|
||||
map.put(ADVANCED_AUDIO, "ADVANCED_AUDIO");
|
||||
map.put(AVRCP_REMOTE, "AVRCP_REMOTE");
|
||||
map.put(VIDEO_CONFERENCING, "Video Conferencing");
|
||||
map.put(INTERCOM, "Intercom");
|
||||
map.put(FAX, "FAX");
|
||||
map.put(HEADSET_PROFILE_HSP_AUDIO_GATEWAY, "Headset Profile (HSP) - Audio Gateway");
|
||||
map.put(WAP, "WAP");
|
||||
map.put(WAP_CLIENT, "WAP Client");
|
||||
map.put(PANU, "PANU");
|
||||
map.put(NAP, "NAP");
|
||||
map.put(GN, "GN");
|
||||
map.put(DIRECT_PRINTING, "Direct Printing");
|
||||
map.put(REFERENCE_PRINTING, "Reference Printing");
|
||||
map.put(IMAGING, "Imaging");
|
||||
map.put(IMAGING_RESPONDER, "Imaging Responder");
|
||||
map.put(IMAGING_AUTOMATIC_ARCHIVE, "Imaging Automatic Archive");
|
||||
map.put(IMAGING_REFERENCE_OBJECTS, "Imaging Reference Objects");
|
||||
map.put(HANDS_FREE_PROFILE_HFP, "Hands Free Profile (HFP)");
|
||||
map.put(HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY, "Hands Free Profile (HFP) – Audio Gateway");
|
||||
map.put(DIRECT_PRINTING_REFERENCE_OBJECTS, "Direct Printing Reference Objects");
|
||||
map.put(REFLECTED_UI, "Reflected UI");
|
||||
map.put(BASIC_PRINTING, "Basic Printing");
|
||||
map.put(PRINTING_STATUS, "Printing Status");
|
||||
map.put(HID, "HID");
|
||||
map.put(HARDCOPY_CABLE_REPLACEMENT, "Hardcopy Cable Replacement");
|
||||
map.put(HCR_PRINT, "HCR Print");
|
||||
map.put(HCR_SCAN, "HCR Scan");
|
||||
map.put(COMMON_ISDN_ACCESS, "Common ISDN Access");
|
||||
map.put(VIDEO_CONFERENCING_GATEWAY, "Video Conferencing Gateway");
|
||||
map.put(UDIMT, "UDIMT");
|
||||
map.put(UDITA, "UDITA");
|
||||
map.put(AUDIO_VIDEO, "Audio Video");
|
||||
map.put(SIM_ACCESS, "SIM Access");
|
||||
map.put(OBEX_PCE, "OBEX PCE");
|
||||
map.put(OBEX_PSE, "OBEX PSE");
|
||||
map.put(OBEX_PBAP, "OBEX PBAP");
|
||||
map.put(OBEX_MAS, "OBEX MAS");
|
||||
map.put(OBEX_MNS, "OBEX MNS");
|
||||
map.put(OBEX_MAP, "OBEX MAP");
|
||||
map.put(PNP, "PNP");
|
||||
map.put(GENERIC_NETWORKING, "Generic Networking");
|
||||
map.put(GENERIC_FILE_TRANSFER, "Generic File Transfer");
|
||||
map.put(GENERIC_AUDIO, "Generic Audio");
|
||||
map.put(GENERIC_TELEPHONY, "Generic Telephony");
|
||||
map.put(UPNP, "UPNP");
|
||||
map.put(UPNP_IP, "UPNP IP");
|
||||
map.put(ESDP_UPNP_IP_PAN, "ESDP UPnP IP PAN");
|
||||
map.put(ESDP_UPNP_IP_LAP, "ESDP UPnP IP LAP");
|
||||
map.put(ESDP_UPNP_L2CAP, "ESDP Upnp L2CAP");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE, "Video Distribution Profile (VDP) - Source");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SINK, "Video Distribution Profile (VDP) - Sink");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP, "Video Distribution Profile (VDP)");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP, "Health Device Profile (HDP)");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SOURCE, "Health Device Profile (HDP) - Source");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SINK, "Health Device Profile (HDP) - Sink");
|
||||
map.put(GAP, "GAP");
|
||||
map.put(GATT, "GATT");
|
||||
map.put(IMMEDIATE_ALERT, "IMMEDIATE_ALERT");
|
||||
map.put(LINK_LOSS, "LINK_LOSS");
|
||||
map.put(TX_POWER, "TX_POWER");
|
||||
map.put(HEALTH_THERMOMETER, "Health Thermometer");
|
||||
map.put(DEVICE_INFORMATION, "Device Information");
|
||||
map.put(HEART_RATE, "HEART_RATE");
|
||||
map.put(CYCLING_SC, "CYCLING_SC");
|
||||
map.put(CLIENT_CHARACTERISTIC_CONFIG, "CLIENT_CHARACTERISTIC_CONFIG");
|
||||
map.put(DEVICE_NAME, "Device Name");
|
||||
map.put(APPEARANCE, "Appearance");
|
||||
map.put(PERIPHERAL_PRIVACY_FLAG, "Peripheral Privacy Flag");
|
||||
map.put(RECONNECTION_ADDRESS, "Reconnection Address");
|
||||
map.put(PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS, "Peripheral Preferred Connection Parameters");
|
||||
map.put(SERVICE_CHANGED, "Service Changed");
|
||||
map.put(ALERT_LEVEL, "Alert Level");
|
||||
map.put(TX_POWER_LEVEL, "Tx Power Level");
|
||||
map.put(DATE_TIME, "Date Time");
|
||||
map.put(DAY_OF_WEEK, "Day of Week");
|
||||
map.put(DAY_DATE_TIME, "Day Date Time");
|
||||
map.put(EXACT_TIME_256, "Exact Time 256");
|
||||
map.put(DST_OFFSET, "DST Offset");
|
||||
map.put(TIME_ZONE, "Time Zone");
|
||||
map.put(LOCAL_TIME_INFORMATION, "Local Time Information");
|
||||
map.put(TIME_WITH_DST, "Time with DST");
|
||||
map.put(TIME_ACCURACY, "Time Accuracy");
|
||||
map.put(TIME_SOURCE, "Time Source");
|
||||
map.put(REFERENCE_TIME_INFORMATION, "Reference Time Information");
|
||||
map.put(TIME_UPDATE_CONTROL_POINT, "Time Update Control Point");
|
||||
map.put(TIME_UPDATE_STATE, "Time Update State");
|
||||
map.put(TEMPERATURE_MEASUREMENT, "Temperature Measurement");
|
||||
map.put(TEMPERATURE_TYPE, "Temperature Type");
|
||||
map.put(INTERMEDIATE_TEMPERATURE, "Intermediate Temperature");
|
||||
map.put(MEASUREMENT_INTERVAL, "Measurement Interval");
|
||||
map.put(SYSTEM_ID, "System ID");
|
||||
map.put(MODEL_NUMBER_STRING, "Model Number String");
|
||||
map.put(SERIAL_NUMBER_STRING, "Serial Number String");
|
||||
map.put(FIRMWARE_REVISION_STRING, "Firmware Revision String");
|
||||
map.put(HARDWARE_REVISION_STRING, "Hardware Revision String");
|
||||
map.put(SOFTWARE_REVISION_STRING, "Software Revision String");
|
||||
map.put(MANUFACTURER_NAME_STRING, "Manufacturer Name String");
|
||||
map.put(IEEE_1107320601_REGULATORY, "IEEE 11073-20601 Regulatory");
|
||||
map.put(CURRENT_TIME, "Current Time");
|
||||
map.put(BLOOD_PRESSURE_MEASUREMENT, "Blood Pressure Measurement");
|
||||
map.put(INTERMEDIATE_CUFF_PRESSURE, "Intermediate Cuff Pressure");
|
||||
map.put(HEART_RATE_MEASUREMENT, "Heart Rate Measurement");
|
||||
map.put(BODY_SENSOR_LOCATION, "Body Sensor Location");
|
||||
map.put(HEART_RATE_CONTROL_POINT, "Heart Rate Control Point");
|
||||
map.put(ALERT_STATUS, "Alert Status");
|
||||
map.put(RINGER_CONTROL_POINT, "Ringer Control Point");
|
||||
map.put(RINGER_SETTING, "Ringer Setting");
|
||||
map.put(ALERT_CATEGORY_ID_BIT_MASK, "Alert Category ID Bit Mask");
|
||||
map.put(ALERT_CATEGORY_ID, "Alert Category ID");
|
||||
map.put(ALERT_NOTIFICATION_CONTROL_POINT, "Alert Notification Control Point");
|
||||
map.put(UNREAD_ALERT_STATUS, "Unread Alert Status");
|
||||
map.put(NEW_ALERT, "New Alert");
|
||||
map.put(SUPPORTED_NEW_ALERT_CATEGORY, "Supported New Alert Category");
|
||||
map.put(SUPPORTED_UNREAD_ALERT_CATEGORY, "Supported Unread Alert Category");
|
||||
map.put(BLOOD_PRESSURE_FEATURE, "Blood Pressure Feature");
|
||||
map.put(PNPID, "PNPID");
|
||||
map.put(SC_CONTROL_POINT, "SC_CONTROL_POINT");
|
||||
map.put(CSC_MEASUREMENT, "CSC_MEASUREMENT");
|
||||
map.put(CSC_FEATURE, "CSC_FEATURE");
|
||||
map.put(SENSOR_LOCATION, "SENSOR_LOCATION");
|
||||
map.put(ACTIVESYNC, "ActiveSync");
|
||||
map.put(ESTIMOTE_SERVICE, "Estimote Service");
|
||||
map.put(ESTIMOTE_UUID, "Estimote UUID");
|
||||
map.put(ESTIMOTE_MAJOR, "Estimote Major");
|
||||
map.put(ESTIMOTE_MINOR, "Estimote Minor");
|
||||
map.put(ESTIMOTE_BATTERY, "Estimote Battery");
|
||||
map.put(ESTIMOTE_TEMPERATURE, "Estimote Temperature");
|
||||
map.put(ESTIMOTE_POWER, "Estimote Power");
|
||||
map.put(ESTIMOTE_ADVERTISING_INTERVAL, "Estimote Advertising Interval");
|
||||
map.put(ESTIMOTE_VERSION_SERVICE, "Estimote Version Service");
|
||||
map.put(ESTIMOTE_SOFTWARE_VERSION, "Estimote Software Version");
|
||||
map.put(ESTIMOTE_HARDWARE_VERSION, "Estimote Hardware Version");
|
||||
map.put(ESTIMOTE_AUTHENTICATION_SERVICE, "Estimote Authentication Service");
|
||||
map.put(ESTIMOTE_ADVERTISING_SEED, "Estimote Advertising Seed");
|
||||
map.put(ESTIMOTE_ADVERTISING_VECTOR, "Estimote Advertising Vector");
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
134
app/src/main/java/com/qidian/baseble/utils/AdRecordUtil.java
Normal file
134
app/src/main/java/com/qidian/baseble/utils/AdRecordUtil.java
Normal file
@ -0,0 +1,134 @@
|
||||
package com.qidian.baseble.utils;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
|
||||
import com.qidian.baseble.model.adrecord.AdRecord;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 广播包解析工具类
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/7 21:56.
|
||||
*/
|
||||
public class AdRecordUtil {
|
||||
private AdRecordUtil() {
|
||||
// TO AVOID INSTANTIATION
|
||||
}
|
||||
|
||||
public static String getRecordDataAsString(final AdRecord nameRecord) {
|
||||
if (nameRecord == null) {
|
||||
return "";
|
||||
}
|
||||
return new String(nameRecord.getData());
|
||||
}
|
||||
|
||||
public static byte[] getServiceData(final AdRecord serviceData) {
|
||||
if (serviceData == null) {
|
||||
return null;
|
||||
}
|
||||
if (serviceData.getType() != AdRecord.BLE_GAP_AD_TYPE_SERVICE_DATA) return null;
|
||||
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Chop out the uuid
|
||||
return Arrays.copyOfRange(raw, 2, raw.length);
|
||||
}
|
||||
|
||||
public static int getServiceDataUuid(final AdRecord serviceData) {
|
||||
if (serviceData == null) {
|
||||
return -1;
|
||||
}
|
||||
if (serviceData.getType() != AdRecord.BLE_GAP_AD_TYPE_SERVICE_DATA) return -1;
|
||||
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Find UUID data in byte array
|
||||
int uuid = (raw[1] & 0xFF) << 8;
|
||||
uuid += (raw[0] & 0xFF);
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read out all the AD structures from the raw scan record
|
||||
*/
|
||||
public static List<AdRecord> parseScanRecordAsList(final byte[] scanRecord) {
|
||||
final List<AdRecord> records = new ArrayList<>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = scanRecord[index] & 0xFF;
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.add(new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(records);
|
||||
}
|
||||
|
||||
public static Map<Integer, AdRecord> parseScanRecordAsMap(final byte[] scanRecord) {
|
||||
final Map<Integer, AdRecord> records = new HashMap<>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = scanRecord[index] & 0xFF;
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap(records);
|
||||
}
|
||||
|
||||
public static SparseArray<AdRecord> parseScanRecordAsSparseArray(final byte[] scanRecord) {
|
||||
final SparseArray<AdRecord> records = new SparseArray<>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = scanRecord[index] & 0xFF;
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
}
|
||||
37
app/src/main/java/com/qidian/baseble/utils/BleUtil.java
Normal file
37
app/src/main/java/com/qidian/baseble/utils/BleUtil.java
Normal file
@ -0,0 +1,37 @@
|
||||
package com.qidian.baseble.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
/**
|
||||
* @Description: 蓝牙基础操作工具类
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/5 20:43.
|
||||
*/
|
||||
public class BleUtil {
|
||||
public static void enableBluetooth(Activity activity, int requestCode) {
|
||||
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||
activity.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
public static boolean isSupportBle(Context context) {
|
||||
if (context == null || !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||
return false;
|
||||
}
|
||||
BluetoothManager manager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
return manager.getAdapter() != null;
|
||||
}
|
||||
|
||||
public static boolean isBleEnable(Context context) {
|
||||
if (!isSupportBle(context)) {
|
||||
return false;
|
||||
}
|
||||
BluetoothManager manager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
return manager.getAdapter().isEnabled();
|
||||
}
|
||||
|
||||
}
|
||||
402
app/src/main/java/com/qidian/baseble/utils/HexUtil.java
Normal file
402
app/src/main/java/com/qidian/baseble/utils/HexUtil.java
Normal file
@ -0,0 +1,402 @@
|
||||
package com.qidian.baseble.utils;
|
||||
|
||||
import com.vise.log.ViseLog;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* @Description: 十六进制转换类
|
||||
* @author: <a href="http://www.xiaoyaoyou1212.com">DAWI</a>
|
||||
* @date: 16/8/7 21:57.
|
||||
*/
|
||||
public class HexUtil {
|
||||
/**
|
||||
* 用于建立十六进制字符的输出的小写字符数组
|
||||
*/
|
||||
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
/**
|
||||
* 用于建立十六进制字符的输出的大写字符数组
|
||||
*/
|
||||
private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符数组
|
||||
*
|
||||
* @param data byte[]
|
||||
* @return 十六进制char[]
|
||||
*/
|
||||
public static char[] encodeHex(byte[] data) {
|
||||
return encodeHex(data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符数组
|
||||
*
|
||||
* @param data byte[]
|
||||
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
|
||||
* @return 十六进制char[]
|
||||
*/
|
||||
public static char[] encodeHex(byte[] data, boolean toLowerCase) {
|
||||
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符数组
|
||||
*
|
||||
* @param data byte[]
|
||||
* @param toDigits 用于控制输出的char[]
|
||||
* @return 十六进制char[]
|
||||
*/
|
||||
protected static char[] encodeHex(byte[] data, char[] toDigits) {
|
||||
int l = data.length;
|
||||
char[] out = new char[l << 1];
|
||||
// two characters form the hex value.
|
||||
for (int i = 0, j = 0; i < l; i++) {
|
||||
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
|
||||
out[j++] = toDigits[0x0F & data[i]];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字节数组转16进制
|
||||
*
|
||||
* @param bytes 需要转换的byte数组
|
||||
* @return 转换后的Hex字符串
|
||||
*/
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
String hex = Integer.toHexString(bytes[i] & 0xFF);
|
||||
if (hex.length() < 2) {
|
||||
sb.append(0);
|
||||
}
|
||||
sb.append(hex);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* @Titl:
|
||||
* @Param
|
||||
* @Return:
|
||||
* @Description:设备数据处理流程
|
||||
* @author xundanqing
|
||||
* @CreateDate: 2019/4/4 11:34
|
||||
*/
|
||||
public static String byte_String(byte b) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(String.format("%02x", b));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static int byteToInt(byte b) {
|
||||
int x = b & 0xff;
|
||||
return x;
|
||||
}
|
||||
|
||||
public static byte[] int2ByteArray(int i) {
|
||||
byte[] result = new byte[4];
|
||||
result[0] = (byte) ((i >> 24) & 0xFF);
|
||||
result[1] = (byte) ((i >> 16) & 0xFF);
|
||||
result[2] = (byte) ((i >> 8) & 0xFF);
|
||||
result[3] = (byte) (i & 0xFF);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* @Titl:
|
||||
* @Param
|
||||
* @Return:
|
||||
* @Description:获得当前时间
|
||||
* @author xundanqing
|
||||
* @CreateDate: 2019/4/4 11:34
|
||||
*/
|
||||
public static byte[] GetTempTime(String timeString) {
|
||||
|
||||
byte timebyte[];
|
||||
timebyte = StrToBCDBytes(timeString);
|
||||
return timebyte;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @Titl:
|
||||
* @Param
|
||||
* @Return:
|
||||
* @Description:字符串转bcd
|
||||
* @author xundanqing
|
||||
* @CreateDate: 2019/4/4 11:34
|
||||
*/
|
||||
public static byte[] StrToBCDBytes(String s) {
|
||||
if (s.length() % 2 != 0) {
|
||||
s = "0" + s;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
char[] cs = s.toCharArray();
|
||||
for (int i = 0; i < cs.length; i += 2) {
|
||||
int high = cs[i] - 48;
|
||||
int low = cs[i + 1] - 48;
|
||||
baos.write(high << 4 | low);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public static byte[] addBytes(byte[] data1, byte[] data2) {
|
||||
byte[] data3 = new byte[data1.length + data2.length];
|
||||
System.arraycopy(data1, 0, data3, 0, data1.length);
|
||||
System.arraycopy(data2, 0, data3, data1.length, data2.length);
|
||||
return data3;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @Title: getInt
|
||||
* @Description: 将字节数组前4字节转换为整型数值
|
||||
* @author fun
|
||||
* @date 2019年3月27日
|
||||
*/
|
||||
public static int byteArrayToInt(byte[] bytes) {
|
||||
int value = 0;
|
||||
// 由高位到低位
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
int shift = (bytes.length - 1 - i) * 8;
|
||||
value += (bytes[i] & 0x000000FF) << shift;// 往高位游
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
*
|
||||
* @param data byte[]
|
||||
* @return 十六进制String
|
||||
*/
|
||||
public static String encodeHexStr(byte[] data) {
|
||||
return encodeHexStr(data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
*
|
||||
* @param data byte[]
|
||||
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
|
||||
* @return 十六进制String
|
||||
*/
|
||||
public static String encodeHexStr(byte[] data, boolean toLowerCase) {
|
||||
return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
*
|
||||
* @param data byte[]
|
||||
* @param toDigits 用于控制输出的char[]
|
||||
* @return 十六进制String
|
||||
*/
|
||||
protected static String encodeHexStr(byte[] data, char[] toDigits) {
|
||||
if (data == null) {
|
||||
ViseLog.e("this data is null.");
|
||||
return "";
|
||||
}
|
||||
return new String(encodeHex(data, toDigits));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十六进制字符串转换为字节数组
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static byte[] decodeHex(String data) {
|
||||
if (data == null) {
|
||||
ViseLog.e("this data is null.");
|
||||
return new byte[0];
|
||||
}
|
||||
return decodeHex(data.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十六进制字符数组转换为字节数组
|
||||
*
|
||||
* @param data 十六进制char[]
|
||||
* @return byte[]
|
||||
* @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
|
||||
*/
|
||||
public static byte[] decodeHex(char[] data) {
|
||||
|
||||
int len = data.length;
|
||||
|
||||
if ((len & 0x01) != 0) {
|
||||
throw new RuntimeException("Odd number of characters.");
|
||||
}
|
||||
|
||||
byte[] out = new byte[len >> 1];
|
||||
|
||||
// two characters form the hex value.
|
||||
for (int i = 0, j = 0; j < len; i++) {
|
||||
int f = toDigit(data[j], j) << 4;
|
||||
j++;
|
||||
f = f | toDigit(data[j], j);
|
||||
j++;
|
||||
out[i] = (byte) (f & 0xFF);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十六进制字符转换成一个整数
|
||||
*
|
||||
* @param ch 十六进制char
|
||||
* @param index 十六进制字符在字符数组中的位置
|
||||
* @return 一个整数
|
||||
* @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
|
||||
*/
|
||||
protected static int toDigit(char ch, int index) {
|
||||
int digit = Character.digit(ch, 16);
|
||||
if (digit == -1) {
|
||||
throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index);
|
||||
}
|
||||
return digit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取字节数组
|
||||
*
|
||||
* @param src byte [] 数组源 这里填16进制的 数组
|
||||
* @param begin 起始位置 源数组的起始位置。0位置有效
|
||||
* @param count 截取长度
|
||||
* @return
|
||||
*/
|
||||
public static byte[] subBytes(byte[] src, int begin, int count) {
|
||||
byte[] bs = new byte[count];
|
||||
System.arraycopy(src, begin, bs, 0, count); // bs 目的数组 0 截取后存放的数值起始位置。0位置有效
|
||||
return bs;
|
||||
}
|
||||
|
||||
/**
|
||||
* int转byte数组
|
||||
*
|
||||
* @param bb
|
||||
* @param x
|
||||
* @param index 第几位开始
|
||||
* @param flag 标识高低位顺序,高位在前为true,低位在前为false
|
||||
*/
|
||||
public static void intToByte(byte[] bb, int x, int index, boolean flag) {
|
||||
if (flag) {
|
||||
bb[index + 0] = (byte) (x >> 24);
|
||||
bb[index + 1] = (byte) (x >> 16);
|
||||
bb[index + 2] = (byte) (x >> 8);
|
||||
bb[index + 3] = (byte) (x >> 0);
|
||||
} else {
|
||||
bb[index + 3] = (byte) (x >> 24);
|
||||
bb[index + 2] = (byte) (x >> 16);
|
||||
bb[index + 1] = (byte) (x >> 8);
|
||||
bb[index + 0] = (byte) (x >> 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* byte数组转int
|
||||
*
|
||||
* @param bb
|
||||
* @param index 第几位开始
|
||||
* @param flag 标识高低位顺序,高位在前为true,低位在前为false
|
||||
* @return
|
||||
*/
|
||||
public static int byteToInt(byte[] bb, int index, boolean flag) {
|
||||
if (flag) {
|
||||
return (int) ((((bb[index + 0] & 0xff) << 24)
|
||||
| ((bb[index + 1] & 0xff) << 16)
|
||||
| ((bb[index + 2] & 0xff) << 8)
|
||||
| ((bb[index + 3] & 0xff) << 0)));
|
||||
} else {
|
||||
return (int) ((((bb[index + 3] & 0xff) << 24)
|
||||
| ((bb[index + 2] & 0xff) << 16)
|
||||
| ((bb[index + 1] & 0xff) << 8)
|
||||
| ((bb[index + 0] & 0xff) << 0)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字节数组逆序
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static byte[] reverse(byte[] data) {
|
||||
byte[] reverseData = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
reverseData[i] = data[data.length - 1 - i];
|
||||
}
|
||||
return reverseData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 蓝牙传输 16进制 高低位 读数的 转换
|
||||
*
|
||||
* @param data 截取数据源,字节数组
|
||||
* @param index 截取数据开始位置
|
||||
* @param count 截取数据长度,只能为2、4、8个字节
|
||||
* @param flag 标识高低位顺序,高位在前为true,低位在前为false
|
||||
* @return
|
||||
*/
|
||||
public static long byteToLong(byte[] data, int index, int count, boolean flag) {
|
||||
long lg = 0;
|
||||
if (flag) {
|
||||
switch (count) {
|
||||
case 2:
|
||||
lg = ((((long) data[index + 0] & 0xff) << 8)
|
||||
| (((long) data[index + 1] & 0xff) << 0));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
lg = ((((long) data[index + 0] & 0xff) << 24)
|
||||
| (((long) data[index + 1] & 0xff) << 16)
|
||||
| (((long) data[index + 2] & 0xff) << 8)
|
||||
| (((long) data[index + 3] & 0xff) << 0));
|
||||
break;
|
||||
|
||||
case 8:
|
||||
lg = ((((long) data[index + 0] & 0xff) << 56)
|
||||
| (((long) data[index + 1] & 0xff) << 48)
|
||||
| (((long) data[index + 2] & 0xff) << 40)
|
||||
| (((long) data[index + 3] & 0xff) << 32)
|
||||
| (((long) data[index + 4] & 0xff) << 24)
|
||||
| (((long) data[index + 5] & 0xff) << 16)
|
||||
| (((long) data[index + 6] & 0xff) << 8)
|
||||
| (((long) data[index + 7] & 0xff) << 0));
|
||||
break;
|
||||
}
|
||||
return lg;
|
||||
} else {
|
||||
switch (count) {
|
||||
case 2:
|
||||
lg = ((((long) data[index + 1] & 0xff) << 8)
|
||||
| (((long) data[index + 0] & 0xff) << 0));
|
||||
break;
|
||||
case 4:
|
||||
lg = ((((long) data[index + 3] & 0xff) << 24)
|
||||
| (((long) data[index + 2] & 0xff) << 16)
|
||||
| (((long) data[index + 1] & 0xff) << 8)
|
||||
| (((long) data[index + 0] & 0xff) << 0));
|
||||
break;
|
||||
case 8:
|
||||
lg = ((((long) data[index + 7] & 0xff) << 56)
|
||||
| (((long) data[index + 6] & 0xff) << 48)
|
||||
| (((long) data[index + 5] & 0xff) << 40)
|
||||
| (((long) data[index + 4] & 0xff) << 32)
|
||||
| (((long) data[index + 3] & 0xff) << 24)
|
||||
| (((long) data[index + 2] & 0xff) << 16)
|
||||
| (((long) data[index + 1] & 0xff) << 8)
|
||||
| (((long) data[index + 0] & 0xff) << 0));
|
||||
break;
|
||||
}
|
||||
return lg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
549
app/src/main/java/com/qidian/zhongkesmart/MainActivity.kt
Normal file
549
app/src/main/java/com/qidian/zhongkesmart/MainActivity.kt
Normal file
@ -0,0 +1,549 @@
|
||||
|
||||
package com.qidian.zhongkesmart
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.CountDownTimer
|
||||
import android.os.Handler
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.blankj.utilcode.util.ToastUtils
|
||||
import com.netease.lava.nertc.sdk.NERtcOption
|
||||
import com.netease.nimlib.sdk.NIMClient
|
||||
import com.netease.nimlib.sdk.Observer
|
||||
import com.netease.nimlib.sdk.StatusCode
|
||||
import com.netease.nimlib.sdk.auth.AuthServiceObserver
|
||||
import com.netease.yunxin.nertc.ui.CallKitUI.init
|
||||
import com.netease.yunxin.nertc.ui.CallKitUIOptions
|
||||
import com.qidian.baseble.ViseBle
|
||||
import com.qidian.zhongkesmart.activity.*
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.config.EventCode
|
||||
import com.qidian.zhongkesmart.dialog.*
|
||||
import com.qidian.zhongkesmart.model.*
|
||||
import com.qidian.zhongkesmart.net.*
|
||||
import com.qidian.zhongkesmart.receiver.WifiReceiver
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import com.qidian.zhongkesmart.utils.TimeUtil.getNowTime
|
||||
import com.qidian.zjlw.presenter.Contract
|
||||
import com.qidian.zjlw.presenter.MainPresenter
|
||||
import com.qidian.zxing.lib_zxing.activity.CodeUtils
|
||||
import kotlinx.android.synthetic.main.activity_base.*
|
||||
import kotlinx.android.synthetic.main.activity_launch.*
|
||||
import kotlinx.android.synthetic.main.activity_wi_fi.*
|
||||
import kotlinx.android.synthetic.main.layout_setmess.*
|
||||
import kotlinx.android.synthetic.main.layout_standby.*
|
||||
import kotlinx.android.synthetic.main.layout_sys_bluetooth2.*
|
||||
import kotlinx.android.synthetic.main.layout_sys_netmess1.*
|
||||
import kotlinx.android.synthetic.main.layout_tiepain_details.*
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
|
||||
/**
|
||||
* 1、全局监听wifi
|
||||
* 2、监听蓝牙
|
||||
* 3、新增、修改、解除绑定贴片
|
||||
* 4、做扫码操作之前获取tokenbridge/device
|
||||
* 5、根据蓝牙接收数据记录开关
|
||||
* 位移型处理方式:
|
||||
*主要判断的是 三轴传感器的数值变化,在三轴传感器首次有值时认为该场景为开启状态(贴件首次安装均为关闭状态),再次有值时认为是关闭状态;贴件每次向网关发送数据时,网关需要查询该贴件的上次状态进行相反处理即可。
|
||||
*开启的持续时间为两次之间的差;
|
||||
*震动型型处理方式:
|
||||
*主要判断的是震动传感器的有值与否,当震动传感器有值的时候认为该场景为开启状态,当震动传感器X秒不在传值时认为该场景为关闭状态;
|
||||
*开启的持续时间为两次之间的差;
|
||||
* 5、离线任务
|
||||
* 每天00:00 时要求贴件 定时发送一次数据,当网关未收到贴件上传的数据时认为该贴件为离线状态
|
||||
*
|
||||
* 6、重要::::::::设置发包后45天后app无法打开
|
||||
*
|
||||
* 7、网关心跳接口 每15分钟调用一次
|
||||
*/
|
||||
|
||||
class MainActivity : BaseActivity(), EasyPermissions.PermissionCallbacks, Contract.GovernmentView {
|
||||
var TAG_L = "MainActivity"
|
||||
private val REQUEST_CODE = 100
|
||||
var wifiReceiver: WifiReceiver? = null
|
||||
|
||||
//添加新设备时候扫描出来的贴件MAC地址
|
||||
var mTJMac = ""
|
||||
|
||||
var mCode = ""
|
||||
var mToken = ""
|
||||
var warnType = ""
|
||||
|
||||
|
||||
//网关心跳计时
|
||||
var heartbeatTime = 0
|
||||
|
||||
var countDownTimer: CountDownTimer? = null
|
||||
var isResume = false
|
||||
//是否要重连
|
||||
var isNeedRetry = true
|
||||
|
||||
private val mPresenter by lazy { MainPresenter() }
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_main
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
mPresenter.attachView(this)
|
||||
checkLogin()
|
||||
initG2()
|
||||
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
override fun isImmersion(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
//添加设备-扫描二维码
|
||||
R.id.imv_index_add -> {
|
||||
if (DataServer.mHttpToken.isNullOrEmpty()) {
|
||||
// mPresenter.getHttpCode(this)
|
||||
ToastUtil.showToast("您还未绑定网关")
|
||||
} else {
|
||||
askPermissionOfCamera()
|
||||
/* mTJMac = "cf6a12483f38"
|
||||
FindNewEquipmentDialog.instance!!.getShareDialog(this,
|
||||
mTJMac,
|
||||
object : FindNewEquipmentDialog.PopupYearWindowCallBack {
|
||||
//新增
|
||||
override fun doWork(roomName: String?, type: String?) {
|
||||
if (!ToolUtil.isContainsTJData(
|
||||
roomName!!,
|
||||
type!!,
|
||||
mTJMac,
|
||||
this@MainActivity
|
||||
)
|
||||
) {
|
||||
mPresenter.getbindDevice(
|
||||
this@MainActivity,
|
||||
mTJMac,
|
||||
roomName!!,
|
||||
type!!
|
||||
)
|
||||
|
||||
}else{
|
||||
ToastUtil.showToast("请勿重复添加")
|
||||
}
|
||||
}
|
||||
|
||||
//修改
|
||||
override fun doChangeWork(roomName: String?, type: String?) {
|
||||
if (!ToolUtil.isContainsTJData(
|
||||
roomName!!,
|
||||
type!!,
|
||||
mTJMac,
|
||||
this@MainActivity
|
||||
)
|
||||
) {
|
||||
mPresenter.getChangeDevice(
|
||||
this@MainActivity,
|
||||
mTJMac,
|
||||
roomName,
|
||||
type
|
||||
)
|
||||
}else{
|
||||
ToastUtil.showToast("请勿重复添加")
|
||||
}
|
||||
}
|
||||
|
||||
//解绑
|
||||
override fun doUnBindWork() {
|
||||
mPresenter.removebindDevice(this@MainActivity, mTJMac)
|
||||
}
|
||||
|
||||
})*/
|
||||
}
|
||||
|
||||
}
|
||||
//二维码弹窗
|
||||
R.id.imv_index_qrcode -> {
|
||||
EquipmentStatusDialog.instance!!.getShareDialog(this,
|
||||
object : EquipmentStatusDialog.PopupYearWindowCallBack {
|
||||
override fun doWork(place: String?, use: String?) {
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
//我的设备
|
||||
R.id.li_index_01 -> {
|
||||
startActivity(Intent(this, MyEquipmentActivity::class.java))
|
||||
}
|
||||
//智能分析 2022/08/22要求不可点击
|
||||
R.id.li_index_02 -> {
|
||||
startActivity(Intent(this, SmartAnalysisActivity::class.java))
|
||||
}
|
||||
//语音通话
|
||||
R.id.li_index_03 -> {
|
||||
startActivity(Intent(this,SelectCallUserActivity::class.java))
|
||||
}
|
||||
//系统设置
|
||||
R.id.li_index_04 -> {
|
||||
// startActivity(Intent(this, SetLockActivity::class.java))
|
||||
startActivity(Intent(this, SettingActivity::class.java))
|
||||
}
|
||||
|
||||
R.id.iv_back -> {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun askPermissionOfCamera() {
|
||||
EasyPermissions.requestPermissions(
|
||||
this,
|
||||
"二维码扫码,请允许获取您的摄像头权限",
|
||||
DataServer.ACCESS_CAMERA_CODE,
|
||||
Manifest.permission.CAMERA
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
EasyPermissions.onRequestPermissionsResult(
|
||||
requestCode,
|
||||
permissions,
|
||||
grantResults,
|
||||
this
|
||||
)//1001
|
||||
}
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_CAMERA_CODE) {
|
||||
val intent =
|
||||
Intent(this, com.qidian.zxing.lib_zxing.activity.CaptureActivity::class.java)
|
||||
startActivityForResult(intent, REQUEST_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_CAMERA_CODE) {
|
||||
ToastUtil.showToast("摄像头权限获取失败,扫码功能不可用!")
|
||||
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
intent.data = Uri.fromParts("package", packageName, null)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode == REQUEST_CODE) {
|
||||
//处理扫描结果(在界面上显示)
|
||||
if (null != data) {
|
||||
val bundle = data.extras
|
||||
if (bundle != null) {
|
||||
if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
|
||||
val result = bundle.getString(CodeUtils.RESULT_STRING)
|
||||
Log.i("Zxing_Result", result!!)
|
||||
// mTJMac = ToolUtil.formatMac(result!!)
|
||||
mTJMac = result!!
|
||||
FindNewEquipmentDialog.instance!!.getShareDialog(this,
|
||||
mTJMac,
|
||||
object : FindNewEquipmentDialog.PopupYearWindowCallBack {
|
||||
//新增
|
||||
override fun doWork(roomName: String?, type: String?) {
|
||||
if (!ToolUtil.isContainsTJData(
|
||||
roomName!!,
|
||||
type!!,
|
||||
mTJMac,
|
||||
this@MainActivity
|
||||
)
|
||||
) {
|
||||
mPresenter.getbindDevice(
|
||||
this@MainActivity,
|
||||
mTJMac,
|
||||
roomName!!,
|
||||
type!!
|
||||
)
|
||||
|
||||
} else {
|
||||
ToastUtil.showToast("请勿重复添加")
|
||||
}
|
||||
}
|
||||
|
||||
//修改
|
||||
override fun doChangeWork(roomName: String?, type: String?) {
|
||||
if (!ToolUtil.isContainsTJData(
|
||||
roomName!!,
|
||||
type!!,
|
||||
mTJMac,
|
||||
this@MainActivity
|
||||
)
|
||||
) {
|
||||
mPresenter.getChangeDevice(
|
||||
this@MainActivity,
|
||||
mTJMac,
|
||||
roomName,
|
||||
type
|
||||
)
|
||||
} else {
|
||||
ToastUtil.showToast("请勿重复添加")
|
||||
}
|
||||
}
|
||||
|
||||
//解绑
|
||||
override fun doUnBindWork() {
|
||||
mPresenter.removebindDevice(this@MainActivity, mTJMac)
|
||||
}
|
||||
|
||||
override fun doConnectTj() {
|
||||
connectTjToSettingMode()
|
||||
}
|
||||
|
||||
override fun doDismiss() {
|
||||
isNeedRetry = false
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
} else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
|
||||
ToastUtil.showToast("解析二维码失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//修改信息
|
||||
override fun showChangeResult(messModel: Any?, mac: String, roomName: String?, type: String?) {
|
||||
ToastUtil.showToast("修改成功")
|
||||
FindNewEquipmentDialog.instance!!.bindSuccess()
|
||||
//修改本地该条记录
|
||||
ToolUtil.ChangeHistory(
|
||||
this,
|
||||
DataServer.mBindHistory,
|
||||
mac, BindBlueToothData(
|
||||
mac,
|
||||
BlueToothUtils.instance!!.getBlueToothPower(mac),
|
||||
roomName!!,
|
||||
type!!, TimeUtil.getNowTime()!!
|
||||
)
|
||||
)
|
||||
//修改该贴件接收蓝牙数据里面的type类型 (震动型、移动型)
|
||||
ToolUtil.changeMacBlueToothHistory(mac, this)
|
||||
|
||||
var list = ObjectBoxUtils.getDeviceByMac(mac)
|
||||
var deviceInfo:DeviceInfo?;
|
||||
if (list != null && list.isNotEmpty()) {
|
||||
deviceInfo = list[0]
|
||||
deviceInfo!!.isBind = true
|
||||
deviceInfo!!.name = roomName!!
|
||||
deviceInfo!!.type = type!!
|
||||
} else {
|
||||
deviceInfo = DeviceInfo()
|
||||
deviceInfo.mac = mac
|
||||
deviceInfo.isBind = true
|
||||
deviceInfo.name = roomName!!
|
||||
deviceInfo.type = type!!
|
||||
}
|
||||
ObjectBoxUtils.updateData(deviceInfo, DeviceInfo::class.java)
|
||||
}
|
||||
|
||||
//新增绑定
|
||||
override fun showAddResult(messModel: Any?, mac: String, type: String?, roomName: String?) {
|
||||
ToastUtil.showToast("绑定成功")
|
||||
FindNewEquipmentDialog.instance!!.bindSuccess()
|
||||
//存本地
|
||||
ToolUtil.addHistory(
|
||||
this@MainActivity,
|
||||
DataServer.mBindHistory,
|
||||
BindBlueToothData(
|
||||
mac,
|
||||
BlueToothUtils.instance!!.getBlueToothPower(mac),
|
||||
roomName!!,
|
||||
type!!, TimeUtil.getNowTime()!!
|
||||
)
|
||||
)
|
||||
|
||||
var list = ObjectBoxUtils.getDeviceByMac(mac)
|
||||
var deviceInfo:DeviceInfo?;
|
||||
if (list != null && list.isNotEmpty()) {
|
||||
deviceInfo = list[0]
|
||||
deviceInfo!!.isBind = true
|
||||
deviceInfo!!.time = getNowTime()!!
|
||||
deviceInfo!!.name = roomName!!
|
||||
deviceInfo!!.type = type!!
|
||||
} else {
|
||||
deviceInfo = DeviceInfo()
|
||||
deviceInfo.mac = mac
|
||||
deviceInfo.isBind = true
|
||||
deviceInfo.name = roomName!!
|
||||
deviceInfo.type = type!!
|
||||
deviceInfo.time = getNowTime()!!
|
||||
}
|
||||
ObjectBoxUtils.updateData(deviceInfo, DeviceInfo::class.java)
|
||||
}
|
||||
|
||||
|
||||
//解除绑定
|
||||
override fun showRemoveResult(messModel: Any?, mac: String) {
|
||||
ToastUtil.showToast("解除绑定成功")
|
||||
ObjectBoxUtils.deleteALLDataD(ObjectBoxUtils.getDeviceByMac(mac))
|
||||
ObjectBoxUtils.deleteALLDataA(ObjectBoxUtils.getActionByMac(mac))
|
||||
FindNewEquipmentDialog.instance!!.setDismiss()
|
||||
//清除本地贴件连接的该条记录
|
||||
ToolUtil.deleteHistory(
|
||||
this@MainActivity,
|
||||
DataServer.mBindHistory,
|
||||
mac
|
||||
)
|
||||
//将本地存储的蓝牙接收数据中的该贴件的信息删除
|
||||
ToolUtil.clearMacBlueToothHistory(mac)
|
||||
|
||||
|
||||
}
|
||||
|
||||
//获取token
|
||||
override fun showTokenResult(messModel: Any?) {
|
||||
var model = messModel as GetTokenM
|
||||
mToken = model.token
|
||||
DataServer.mHttpToken = mToken
|
||||
askPermissionOfCamera()
|
||||
}
|
||||
|
||||
override fun showAfter() {
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
isResume = true
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
isResume = false
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroy() {
|
||||
FindNewEquipmentDialog.instance!!.setDismiss()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun initG2() {
|
||||
NIMClient.getService(AuthServiceObserver::class.java).observeOnlineStatus({ statusCode ->
|
||||
if (statusCode == StatusCode.LOGINED) {
|
||||
val options: CallKitUIOptions = CallKitUIOptions.Builder() // 音视频通话 sdk appKey,用于通话中使用
|
||||
.rtcAppKey(BuildConfig.APP_KEY) // 当前用户 accId
|
||||
.currentUserAccId(ProfileManager.getInstance().userModel.imAccid) // 通话接听成功的超时时间单位 毫秒,默认30s
|
||||
.timeOutMillisecond(30 * 1000L) // 当系统版本为 Android Q及以上时,若应用在后台系统限制不直接展示页面
|
||||
// 而是展示 notification,通过点击 notification 跳转呼叫页面
|
||||
// 此处为 notification 相关配置,如图标,提示语等。
|
||||
.notificationConfigFetcher(SelfNotificationConfigFetcher()) // 收到被叫时若 app 在后台,在恢复到前台时是否自动唤起被叫页面,默认为 true
|
||||
.resumeBGInvitation(true) // 请求 rtc token 服务,若非安全模式不需设置,安全模式按照官网实现 token 服务通过如下接口设置回组件
|
||||
// .rtcTokenService(new TokenService() {
|
||||
// @Override
|
||||
// public void getToken(long uid, RequestCallback<String> callback) {
|
||||
// Result result = network.requestToken(uid);
|
||||
// if (result.success) {
|
||||
// callback.onSuccess(result.token);
|
||||
// } else if (result.exception != null) {
|
||||
// callback.onException(result.exception);
|
||||
// } else {
|
||||
// callback.onFailed(result.code);
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// 设置初始化 rtc sdk 相关配置,按照所需进行配置
|
||||
.rtcSdkOption(NERtcOption()) // 设置用户信息
|
||||
.userInfoHelper(SelfUserInfoHelper())
|
||||
.build()
|
||||
// 若重复初始化会销毁之前的初始化实例,重新初始化
|
||||
init(applicationContext, options)
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
|
||||
private fun checkLogin() {
|
||||
if (ProfileManager.getInstance().isLogin) {
|
||||
return
|
||||
}
|
||||
//此处注册之后会立刻回调一次
|
||||
NIMClient.getService(AuthServiceObserver::class.java).observeOnlineStatus(
|
||||
Observer { statusCode: StatusCode ->
|
||||
if (statusCode == StatusCode.LOGINED) {
|
||||
ProfileManager.getInstance().isLogin = true
|
||||
// CallOrderManager.getInstance().init()
|
||||
}
|
||||
} as Observer<StatusCode>, true)
|
||||
}
|
||||
|
||||
override fun receiveEvent(event: EventBusUtil.MessageEvent) {
|
||||
super.receiveEvent(event)
|
||||
when (event.code) {
|
||||
/**
|
||||
* 贴件唤醒成功
|
||||
*/
|
||||
EventCode.DEVICE_WAKE_UP_SUCCEED -> {
|
||||
if(isResume) {
|
||||
if (WakeUpDeviceDialog.instance!!.isShowing()) {
|
||||
WakeUpDeviceDialog.instance!!.setDismiss()
|
||||
FindNewEquipmentDialog.instance!!.setDismiss()
|
||||
countDownTimer!!.cancel()
|
||||
countDownTimer = null
|
||||
startActivity(
|
||||
Intent(
|
||||
this@MainActivity,
|
||||
SettingModeActivity::class.java
|
||||
).putExtra("mac", mTJMac)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun connectTjToSettingMode(){
|
||||
if(DataServer.connectMode==2) {
|
||||
if (!ViseBle.getInstance().deviceMirrorPool.isConnectDevice) {
|
||||
FindNewEquipmentDialog.instance!!.connectFail()
|
||||
return
|
||||
}
|
||||
}
|
||||
// startActivity(Intent(this@MainActivity, SettingModeActivity::class.java))
|
||||
WakeUpDeviceDialog.instance!!.getShareDialog(this@MainActivity,
|
||||
object : WakeUpDeviceDialog.PopupYearWindowCallBack {
|
||||
override fun doCancel() {
|
||||
countDownTimer!!.cancel()
|
||||
countDownTimer = null
|
||||
DataServer.nBlueToothVerifyMac = ""
|
||||
DataServer.nBlueToothMac = ""
|
||||
}
|
||||
})
|
||||
//广播模式下,需要连接贴件
|
||||
if(DataServer.connectMode==1){
|
||||
DataServer.nBlueToothMac = mTJMac
|
||||
}
|
||||
DataServer.nBlueToothVerifyMac = mTJMac
|
||||
countDownTimer = object : CountDownTimer(60 * 1000, 1000) {
|
||||
//1000ms运行一次
|
||||
override fun onFinish() {
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("进入配置模式失败,请确认贴件状态,并重新进入")
|
||||
WakeUpDeviceDialog.instance!!.setDismiss()
|
||||
DataServer.nBlueToothVerifyMac = ""
|
||||
countDownTimer = null
|
||||
Handler().postDelayed({
|
||||
if(isNeedRetry&&!WakeUpDeviceDialog.instance!!.isShowing())
|
||||
connectTjToSettingMode()
|
||||
},120*1000)
|
||||
}
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,270 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.Manifest
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.net.wifi.ScanResult
|
||||
import android.os.Build
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.provider.Settings
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.CheckBox
|
||||
import com.qidian.baseble.ViseBle
|
||||
import com.qidian.baseble.ble.BluetoothDeviceManager
|
||||
import com.qidian.baseble.ble.ConnectEvent
|
||||
import com.qidian.baseble.callback.scan.IScanCallback
|
||||
import com.qidian.baseble.callback.scan.ScanCallback
|
||||
import com.qidian.baseble.common.PropertyType
|
||||
import com.qidian.baseble.model.BluetoothLeDevice
|
||||
import com.qidian.baseble.model.BluetoothLeDeviceStore
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.AppApplication
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.bluetooth.dfu.DfuService
|
||||
import com.qidian.zhongkesmart.config.Config
|
||||
import com.qidian.zhongkesmart.dialog.InputThresholdDialog
|
||||
import com.qidian.zhongkesmart.dialog.OpenmBlueToothDialog
|
||||
import com.qidian.zhongkesmart.dialog.OpenmWifiDialog
|
||||
import com.qidian.zhongkesmart.dialog.WifiPswDialog
|
||||
import com.qidian.zhongkesmart.receiver.WifiReceiver
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import com.vise.xsnow.event.Subscribe
|
||||
import kotlinx.android.synthetic.main.activity_bluetooth.*
|
||||
import kotlinx.android.synthetic.main.activity_wi_fi.*
|
||||
import kotlinx.android.synthetic.main.activity_wi_fi.li_nowchoose
|
||||
import kotlinx.android.synthetic.main.activity_wi_fi.recycle_wifi
|
||||
import kotlinx.android.synthetic.main.activity_wi_fi.tv_nowchoose_name
|
||||
import kotlinx.android.synthetic.main.layout_sys_bluetooth11.*
|
||||
import kotlinx.android.synthetic.main.layout_sys_bluetooth2.*
|
||||
import kotlinx.android.synthetic.main.layout_tiepain_details.*
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
import net.idik.lib.slimadapter.SlimInjector
|
||||
import net.idik.lib.slimadapter.viewinjector.IViewInjector
|
||||
import no.nordicsemi.android.dfu.DfuServiceInitiator
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
import java.io.File
|
||||
|
||||
class BluetoothActivity : BaseActivity(), EasyPermissions.PermissionCallbacks {
|
||||
var wifiReceiver: WifiReceiver? = null
|
||||
//wifi状态 默认关闭 0 开启 1 连接 2
|
||||
var IsOpen = 0
|
||||
var mData_BlueTooth = ArrayList<BluetoothLeDevice>()
|
||||
var mData_BlueAddress = ArrayList<String>()
|
||||
var mAdapterBluetooth: SlimAdapter? = null
|
||||
var mDevice: BluetoothLeDevice? = null
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_bluetooth
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
LoadUtils.setLinearLayoutManager(this, recycle_wifi, false)
|
||||
mAdapterBluetooth =
|
||||
SlimAdapter.create()
|
||||
.register<BluetoothLeDevice>(
|
||||
R.layout.item_bluetooth_activity,
|
||||
object : SlimInjector<BluetoothLeDevice> {
|
||||
override fun onInject(
|
||||
data: BluetoothLeDevice,
|
||||
injector: IViewInjector<out IViewInjector<*>>
|
||||
) {
|
||||
injector.text(R.id.tv_wifi_name, BlueToothUtils.instance!!.getName(data))
|
||||
injector.clicked(R.id.li_wifi) {
|
||||
mDevice = data
|
||||
SPUtil.setValue(DataServer.MRelayMac,mDevice!!.address)
|
||||
SPUtil.setValue(DataServer.MRelayName,mDevice!!.name)
|
||||
li_nowchoose.visibility = View.VISIBLE
|
||||
tv_nowchoose_name.text = BlueToothUtils.instance!!.getName(data)
|
||||
tv_nowchoose_status.text = "连接中"
|
||||
Handler().postDelayed({
|
||||
tv_nowchoose_status.text = "连接成功"
|
||||
// startActivity(Intent(this@BluetoothActivity, HomeActivity::class.java))
|
||||
ActivityManager.getAppManager().finishAllActivity()
|
||||
AppApplication.mContext!!.startActivity(
|
||||
Intent(
|
||||
AppApplication.mContext,
|
||||
HomeActivity::class.java
|
||||
).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
)
|
||||
},2000)
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
.attachTo(recycle_wifi)
|
||||
mAdapterBluetooth!!.updateData(mData_BlueTooth).notifyDataSetChanged()
|
||||
|
||||
//注册监听Wifi连接广播
|
||||
askPermissionOfBluetooth()
|
||||
//注册蓝牙广播
|
||||
this.registerReceiver(mReceiver, makeFilter())
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取蓝牙权限
|
||||
*/
|
||||
private fun askPermissionOfBluetooth() {
|
||||
EasyPermissions.requestPermissions(
|
||||
this,
|
||||
"请允许获取您的位置权限",
|
||||
DataServer.ACCESS_BlueTooth_CODE,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
)
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_BlueTooth_CODE) {
|
||||
aboutlueTooth()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_BlueTooth_CODE) {
|
||||
ToastUtil.showToast("蓝牙权限获取失败,APP功能不可用!")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 1、蓝牙是否打开
|
||||
* 1-1、未打开-提示打开
|
||||
*
|
||||
* 1-2、打开-跳转
|
||||
*/
|
||||
fun aboutlueTooth() {
|
||||
//1、未打开蓝牙-直接提示打开蓝牙
|
||||
if (!BlueToothUtils.instance!!.IsOpenBlueTooth()) {
|
||||
BlueToothUtils.instance!!.OpenBuleTooth(this@BluetoothActivity)
|
||||
} else {
|
||||
//打开过
|
||||
startSearchDevices()
|
||||
}
|
||||
}
|
||||
|
||||
//搜索设备
|
||||
fun startSearchDevices() {
|
||||
mData_BlueAddress.clear()
|
||||
mData_BlueTooth.clear()
|
||||
mAdapterBluetooth!!.notifyDataSetChanged()
|
||||
showDialog()
|
||||
startScan()
|
||||
}
|
||||
|
||||
//注册蓝牙监听广播
|
||||
/**
|
||||
* 蓝牙广播过滤器
|
||||
* 蓝牙状态改变
|
||||
* 找到设备
|
||||
* 搜索完成
|
||||
* 开始扫描
|
||||
* 状态改变
|
||||
*/
|
||||
fun makeFilter(): IntentFilter? {
|
||||
val filter = IntentFilter()
|
||||
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED) //蓝牙状态改变的广播
|
||||
return filter
|
||||
}
|
||||
|
||||
//连接成功 li_bluetooth_connect.visibility = View.VISIBLE
|
||||
private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val action = intent.action
|
||||
when (action) {
|
||||
//蓝牙状态改变的广播
|
||||
BluetoothAdapter.ACTION_STATE_CHANGED -> {
|
||||
Log.i("BlueTooth==", "ACTION_STATE_CHANGED:蓝牙状态改变")
|
||||
var blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0)
|
||||
when (blueState) {
|
||||
//蓝牙-2、扫描
|
||||
BluetoothAdapter.STATE_ON -> {
|
||||
Log.i("BlueTooth==", "蓝牙打开")
|
||||
startSearchDevices()
|
||||
}
|
||||
//蓝牙关闭
|
||||
BluetoothAdapter.STATE_ON -> {
|
||||
Log.i("BlueTooth==", "蓝牙已经关闭")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始扫描
|
||||
*/
|
||||
private fun startScan() {
|
||||
//蓝牙相关配置修改
|
||||
ViseBle.config().scanTimeout = 12*1000 //扫描超时时间,-1设置为永久扫描
|
||||
// ViseBle.config().scanTimeout = -1 //扫描超时时间,-1设置为永久扫描
|
||||
ViseBle.getInstance().startScan(periodScanCallback)
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
/**
|
||||
* 贴片详情
|
||||
*/
|
||||
R.id.iv_back -> {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描回调
|
||||
*/
|
||||
private val periodScanCallback: ScanCallback = ScanCallback(object : IScanCallback {
|
||||
override fun onDeviceFound(bluetoothLeDevice: BluetoothLeDevice) {
|
||||
if(bluetoothLeDevice.name!=null&&bluetoothLeDevice.name.startsWith("ZJ",false)) {
|
||||
if (!TextUtils.isEmpty(bluetoothLeDevice.address)) {
|
||||
if (!mData_BlueAddress.contains(bluetoothLeDevice.address)) {
|
||||
dismissDialog()
|
||||
mData_BlueTooth.add(bluetoothLeDevice)
|
||||
mData_BlueAddress.add(bluetoothLeDevice.address)
|
||||
mAdapterBluetooth!!.notifyDataSetChanged()
|
||||
Log.i(
|
||||
"BlueTooth==",
|
||||
"periodScanCallback:发现设备" + BlueToothUtils.instance!!.getName(
|
||||
bluetoothLeDevice
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScanFinish(bluetoothLeDeviceStore: BluetoothLeDeviceStore?) {
|
||||
Log.i("BlueTooth==", "periodScanCallback:扫描结束")
|
||||
dismissDialog()
|
||||
}
|
||||
|
||||
override fun onScanTimeout() {
|
||||
Log.i("BlueTooth==", "periodScanCallback:扫描超时")
|
||||
dismissDialog()
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
override fun onDestroy() {
|
||||
if(periodScanCallback!=null) {
|
||||
ViseBle.getInstance().stopScan(periodScanCallback)
|
||||
}
|
||||
this.unregisterReceiver(mReceiver)
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import com.qidian.zxing.lib_zxing.activity.CaptureFragment
|
||||
import com.qidian.zxing.lib_zxing.activity.CodeUtils
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.app.Activity
|
||||
import android.hardware.Camera
|
||||
import android.view.Surface
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
|
||||
|
||||
class CaptureActivity : BaseActivity() {
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_capture
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
ImmersionBar.with(this).reset().statusBarDarkFont(true).init()
|
||||
// ImmersionBar.with(this).statusBarDarkFont(isWhiteTheme).fitsSystemWindows(true).init()
|
||||
val captureFragment = CaptureFragment()
|
||||
CodeUtils.setFragmentArgs(captureFragment, R.layout.my_camera)
|
||||
captureFragment.analyzeCallback = analyzeCallback
|
||||
supportFragmentManager.beginTransaction().replace(R.id.fl_my_container, captureFragment)
|
||||
.commit()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
private var analyzeCallback: CodeUtils.AnalyzeCallback = object : CodeUtils.AnalyzeCallback {
|
||||
override fun onAnalyzeSuccess(mBitmap: Bitmap, result: String) {
|
||||
val resultIntent = Intent()
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS)
|
||||
bundle.putString(CodeUtils.RESULT_STRING, result)
|
||||
resultIntent.putExtras(bundle)
|
||||
this@CaptureActivity.setResult(Activity.RESULT_OK, resultIntent)
|
||||
this@CaptureActivity.finish()
|
||||
}
|
||||
|
||||
override fun onAnalyzeFailed() {
|
||||
val resultIntent = Intent()
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED)
|
||||
bundle.putString(CodeUtils.RESULT_STRING, "")
|
||||
resultIntent.putExtras(bundle)
|
||||
this@CaptureActivity.setResult(Activity.RESULT_OK, resultIntent)
|
||||
this@CaptureActivity.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.net.ApiUrl
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import kotlinx.android.synthetic.main.activity_connect_mode.*
|
||||
import kotlinx.android.synthetic.main.activity_service.*
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
class ConnectModeActivity : BaseActivity(),EasyPermissions.PermissionCallbacks {
|
||||
|
||||
var mode = 1
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_connect_mode
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
askPermissionOfBluetooth()
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.iv_direct -> {
|
||||
mode = 1
|
||||
iv_direct.setImageResource(R.mipmap.direct_connect_mode_select_)
|
||||
iv_agent.setImageResource(R.mipmap.agent_connect_mode_unselect_)
|
||||
}
|
||||
R.id.iv_agent -> {
|
||||
mode = 2
|
||||
iv_direct.setImageResource(R.mipmap.direct_connect_mode_unselect_)
|
||||
iv_agent.setImageResource(R.mipmap.agent_connect_mode_select_)
|
||||
}
|
||||
R.id.imv_jump -> {
|
||||
SPUtil.setValue(DataServer.MConnectMode, mode)
|
||||
DataServer.connectMode = mode
|
||||
if(mode==2) {
|
||||
var relayMac = SPUtil.getValue(DataServer.MRelayMac,String::class.java)
|
||||
if(relayMac!=null&&!TextUtils.isEmpty(relayMac)) {
|
||||
startActivity(Intent(this@ConnectModeActivity, HomeActivity::class.java))
|
||||
finish()
|
||||
}else{
|
||||
startActivity(Intent(this@ConnectModeActivity, BluetoothActivity::class.java))
|
||||
}
|
||||
}else{
|
||||
startActivity(Intent(this@ConnectModeActivity, HomeActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取蓝牙权限
|
||||
*/
|
||||
private fun askPermissionOfBluetooth() {
|
||||
EasyPermissions.requestPermissions(
|
||||
this,
|
||||
"请允许获取您的位置权限",
|
||||
DataServer.ACCESS_BlueTooth_CODE,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
)
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_BlueTooth_CODE) {
|
||||
ToastUtil.showToast("蓝牙权限获取失败,APP功能不可用!")
|
||||
}
|
||||
}
|
||||
}
|
||||
1540
app/src/main/java/com/qidian/zhongkesmart/activity/HomeActivity.kt
Normal file
1540
app/src/main/java/com/qidian/zhongkesmart/activity/HomeActivity.kt
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,23 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
|
||||
class InfoActivity : BaseActivity() {
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_infi
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
override fun isImmersion(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,103 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.wifi.WifiManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import com.qidian.zhongkesmart.MainActivity
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.manager.BasicSettingManager
|
||||
import com.qidian.zhongkesmart.model.ActionInfo
|
||||
import com.qidian.zhongkesmart.model.DeviceInfo
|
||||
import com.qidian.zhongkesmart.receiver.WifiReceiver
|
||||
import com.qidian.zhongkesmart.utils.DataServer
|
||||
import com.qidian.zhongkesmart.utils.ObjectBoxUtils
|
||||
import com.qidian.zhongkesmart.utils.SPUtil
|
||||
import com.qidian.zhongkesmart.utils.WifiUtil
|
||||
import kotlinx.android.synthetic.main.activity_launch.*
|
||||
|
||||
/*开机页*/
|
||||
class LaunchActivity : BaseActivity() {
|
||||
val handler = Handler()
|
||||
val waitTime: Long = 3000
|
||||
var drawable: AnimationDrawable? = null
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_launch
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
StartAnimaton()
|
||||
handler.postDelayed(Runnable {
|
||||
goOnIntent()
|
||||
}, waitTime)
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
|
||||
fun goOnIntent() {
|
||||
// startActivity(Intent(this, MainActivity::class.java))
|
||||
var ddList = ObjectBoxUtils.getAllData(DeviceInfo::class.java)
|
||||
var dList = ObjectBoxUtils.getAllData(ActionInfo::class.java)
|
||||
Log.e("BlueTooth", "device:"+ddList!!.size.toString()+" action:"+dList!!.size.toString())
|
||||
if (WifiUtil.getWifiName(this).isNullOrEmpty()) {
|
||||
startActivity(Intent(this, WiFiActivity::class.java))
|
||||
} else {
|
||||
// startActivity(Intent(this, ServiceActivity::class.java))
|
||||
var mode = SPUtil.getValue(DataServer.MConnectMode,Integer::class.java)
|
||||
if(mode!=null&&mode.toInt()!=0) {
|
||||
if(mode.toInt()==2) {
|
||||
DataServer.connectMode = 2
|
||||
var relayMac = SPUtil.getValue(DataServer.MRelayMac,String::class.java)
|
||||
if(relayMac!=null&&!TextUtils.isEmpty(relayMac)) {
|
||||
startActivity(Intent(this@LaunchActivity, HomeActivity::class.java))
|
||||
}else{
|
||||
startActivity(Intent(this@LaunchActivity, ConnectModeActivity::class.java))
|
||||
}
|
||||
}else{
|
||||
DataServer.connectMode = 1
|
||||
startActivity(Intent(this@LaunchActivity, HomeActivity::class.java))
|
||||
}
|
||||
}else{
|
||||
DataServer.connectMode = 0
|
||||
startActivity(Intent(this@LaunchActivity, ConnectModeActivity::class.java))
|
||||
}
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
fun StartAnimaton() {
|
||||
drawable = resources?.getDrawable(R.drawable.lanchanimation) as AnimationDrawable
|
||||
// 放入imageView
|
||||
imv_lancher!!.setBackgroundDrawable(drawable)
|
||||
// 开始
|
||||
drawable!!.start()
|
||||
}
|
||||
|
||||
fun StopAnimation() {
|
||||
if (drawable!!.isRunning) {
|
||||
drawable!!.stop()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
StopAnimation()
|
||||
}
|
||||
|
||||
override fun isImmersion(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,835 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.CountDownTimer
|
||||
import android.os.Handler
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.blankj.utilcode.util.ToastUtils
|
||||
import com.github.mikephil.charting.data.Entry
|
||||
import com.netease.yunxin.kit.alog.BasicInfo
|
||||
import com.qidian.baseble.ble.BluetoothDeviceManager
|
||||
import com.qidian.baseble.ble.DeviceSettingEvent
|
||||
import com.qidian.baseble.utils.HexUtil
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.dialog.*
|
||||
import com.qidian.zhongkesmart.model.DeviceInfo
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import com.vise.xsnow.event.Subscribe
|
||||
import kotlinx.android.synthetic.main.activity_model_init.*
|
||||
import kotlinx.android.synthetic.main.activity_my_equipment_details.*
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class ModelInitActivity : BaseActivity() {
|
||||
override var TAG = ModelInitActivity::class.java.simpleName
|
||||
var mMac=""
|
||||
//0待学习 1模型一学习第一步 2模型一学习第二步 3模型二学习第一步 4模型二学习第二步
|
||||
var mStep = 0
|
||||
var deviceInfo:DeviceInfo? = null
|
||||
var model1Threshold = 0
|
||||
var model2Threshold =0
|
||||
var values = ArrayList<Entry>()
|
||||
var xValues = ArrayList<String>()
|
||||
var countDownTimer: CountDownTimer? = null
|
||||
var countDownTimerS: CountDownTimer? = null
|
||||
var timeString = ""
|
||||
var isShowVerifyToast = false
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_model_init
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
mMac=intent.getStringExtra("mac").toString()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
// var myEquipmentData= ToolUtil.getHistory(DataServer.mBindHistory,this)
|
||||
var myEquipmentData= ObjectBoxUtils.getDeviceByMac(mMac)
|
||||
myEquipmentData!!.forEach {
|
||||
if(it!!.mac==mMac){
|
||||
deviceInfo = it
|
||||
tv_location.text = "贴件位置:"+it.name
|
||||
}
|
||||
}
|
||||
tv_title.text = deviceInfo!!.type+"模型初始化"
|
||||
tv_mac.text = "MAC地址:$mMac"
|
||||
tv_version.text = "固件版本:${deviceInfo!!.fVersion}"
|
||||
if(deviceInfo!!.model1Init){
|
||||
v_open_status.background = getDrawable(R.drawable.shape_model_init_circel_black)
|
||||
tv_open_status.text = "上次学习时间:${deviceInfo!!.model1Time}"
|
||||
tv_open_status.setTextColor(getColor(R.color.color_333333))
|
||||
iv_open_threshold.visibility = View.VISIBLE
|
||||
}else{
|
||||
v_open_status.background = getDrawable(R.drawable.shape_model_init_circel_gray)
|
||||
tv_open_status.text = "未学习"
|
||||
tv_open_status.setTextColor(getColor(R.color.color_333333))
|
||||
iv_open_threshold.visibility = View.GONE
|
||||
}
|
||||
if(deviceInfo!!.model2Init){
|
||||
v_close_status.background = getDrawable(R.drawable.shape_model_init_circel_black)
|
||||
tv_close_status.text = "上次学习时间:${deviceInfo!!.model2Time}"
|
||||
tv_close_status.setTextColor(getColor(R.color.color_333333))
|
||||
iv_close_threshold.visibility = View.VISIBLE
|
||||
}else{
|
||||
v_close_status.background = getDrawable(R.drawable.shape_model_init_circel_gray)
|
||||
tv_close_status.text = "未学习"
|
||||
tv_close_status.setTextColor(getColor(R.color.color_333333))
|
||||
iv_close_threshold.visibility = View.GONE
|
||||
}
|
||||
setImage()
|
||||
if(iv_open_threshold.visibility == View.VISIBLE&&iv_close_threshold.visibility == View.VISIBLE){
|
||||
tv_verify.background = getDrawable(R.drawable.shape_model_init_verify_btn_blue_bg)
|
||||
tv_verify.setTextColor(getColor(R.color.white))
|
||||
}else{
|
||||
tv_verify.background = getDrawable(R.drawable.shape_model_init_verify_btn_gray_bg)
|
||||
tv_verify.setTextColor(Color.parseColor("#ffa1a1a1"))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
if(countDownTimer!=null) {
|
||||
countDownTimer!!.cancel()
|
||||
countDownTimer = null
|
||||
}
|
||||
if(countDownTimerS!=null) {
|
||||
countDownTimerS!!.cancel()
|
||||
countDownTimerS = null
|
||||
}
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
fun setImage(){
|
||||
//"门", "窗帘", "主水管", "水管", "马桶", "电视", "电冰箱", "煤气灶", "抽油烟机", "宠物", "植物", "挎包"
|
||||
when (deviceInfo!!.type) {
|
||||
"门" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.door_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.door_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.door_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.door_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.door_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.door_close_select_small)
|
||||
}
|
||||
"窗帘" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.curtain_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.curtain_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.curtain_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.curtain_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.curtain_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.curtain_close_select_small)
|
||||
}
|
||||
"主水管" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.stopcock_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.stopcock_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.stopcock_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.stopcock_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.stopcock_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.stopcock_close_select_small)
|
||||
}
|
||||
"水管" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.stopcock_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.stopcock_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.stopcock_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.stopcock_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.stopcock_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.stopcock_close_select_small)
|
||||
}
|
||||
"马桶" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.toilet_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.toilet_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.toilet_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.toilet_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.toilet_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.toilet_close_select_small)
|
||||
}
|
||||
"电视" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.tv_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.tv_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.tv_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.tv_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.tv_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.tv_close_select_small)
|
||||
}
|
||||
"电冰箱" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.fridge_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.fridge_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.fridge_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.fridge_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.fridge_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.fridge_close_select_small)
|
||||
}
|
||||
"煤气灶" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.cooker_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.cooker_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.cooker_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.cooker_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.cooker_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.cooker_close_select_small)
|
||||
}
|
||||
"抽油烟机" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.extractor_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.extractor_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.extractor_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.extractor_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.extractor_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.extractor_close_select_small)
|
||||
}
|
||||
"宠物" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.pet_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.pet_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.pet_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.pet_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.pet_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.pet_close_select_small)
|
||||
}
|
||||
"植物" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.plant_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.plant_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.plant_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.plant_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.plant_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.plant_close_select_small)
|
||||
}
|
||||
"挎包" -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
iv_open.setImageResource(R.mipmap.bag_open_select_large)
|
||||
iv_close.setImageResource(R.mipmap.bag_close_select_large)
|
||||
}
|
||||
1 ->{
|
||||
iv_close.setImageResource(R.mipmap.bag_close_unselect)
|
||||
}
|
||||
3 ->{
|
||||
iv_open.setImageResource(R.mipmap.bag_open_unselect)
|
||||
}
|
||||
}
|
||||
iv_open_study.setImageResource(R.mipmap.bag_open_select_small)
|
||||
iv_close_study.setImageResource(R.mipmap.bag_close_select_small)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.iv_back -> {
|
||||
showDialog()
|
||||
//广播版退出配置模式,手动断开连接
|
||||
if(DataServer.connectMode==1) {
|
||||
if (BluetoothDeviceManager.getInstance()
|
||||
.isConnected(DataServer.MDevice)
|
||||
) {
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.disconnect(DataServer.MDevice)
|
||||
}
|
||||
}
|
||||
onBackPressed()
|
||||
DataServer.nBlueToothVerifyMac = ""
|
||||
}
|
||||
|
||||
R.id.iv_open_threshold -> {
|
||||
SetThresholdDialog.instance!!.getShareDialog(this,
|
||||
object : SetThresholdDialog.PopupYearWindowCallBack {
|
||||
override fun doWork(value: Int) {
|
||||
showDialog()
|
||||
model1Threshold = value
|
||||
//设置阈值
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setParam(mMac, true,254,value)
|
||||
}
|
||||
},"打开",deviceInfo!!.model1Threshold)
|
||||
}
|
||||
|
||||
R.id.tv_open_next -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
mStep = 1
|
||||
setImage()
|
||||
rl_open.background = getDrawable(R.drawable.shape_model_init_blue_border_bg)
|
||||
tv_open_next.text = "下一步"
|
||||
tv_close_next.visibility = View.GONE
|
||||
v_close_bottom.visibility = View.GONE
|
||||
iv_open.visibility = View.GONE
|
||||
ll_open.visibility = View.VISIBLE
|
||||
tv_open_cancel.visibility = View.VISIBLE
|
||||
iv_open_num.setImageResource(R.mipmap.study_num_icon)
|
||||
tv_open_num.text = "准备学习"
|
||||
tv_open_num.setTextColor(getColor(R.color.color_333333))
|
||||
v_open_study.background = getDrawable(R.drawable.shape_model_init_square_blue)
|
||||
tv_open_des1.text = "学习前请将${deviceInfo!!.type}操作为关闭状态"
|
||||
tv_open_des1.setTextColor(getColor(R.color.color_333333))
|
||||
tv_open_des2.visibility = View.GONE
|
||||
v_open_top.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_open_bottom.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_open_center.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
}
|
||||
1 ->{
|
||||
mStep = 2
|
||||
rl_open.background = getDrawable(R.drawable.shape_model_init_blue_bg)
|
||||
tv_open_title.setTextColor(getColor(R.color.white))
|
||||
v_open_status.background = getDrawable(R.drawable.shape_model_init_circel_green)
|
||||
tv_open_status.text = "正在学习"
|
||||
tv_open_status.setTextColor(getColor(R.color.white))
|
||||
tv_open_next.visibility = View.GONE
|
||||
tv_open_cancel.visibility = View.GONE
|
||||
tv_open_no_response.visibility = View.VISIBLE
|
||||
iv_open_num.setImageResource(R.mipmap.study_num_icon2)
|
||||
tv_open_num.text = "学习动作"
|
||||
tv_open_num.setTextColor(getColor(R.color.white))
|
||||
v_open_study.background = getDrawable(R.drawable.shape_model_init_square_green)
|
||||
tv_open_des1.text = "在贴件LED绿色闪烁后请将 ${deviceInfo!!.type} 操作为开启状态"
|
||||
tv_open_des1.setTextColor(getColor(R.color.white))
|
||||
tv_open_des2.visibility = View.VISIBLE
|
||||
v_open_top.setBackgroundColor(Color.parseColor("#006FDE"))
|
||||
v_open_bottom.setBackgroundColor(Color.parseColor("#006FDE"))
|
||||
v_open_center.setBackgroundColor(Color.parseColor("#006FDE"))
|
||||
|
||||
Handler().postDelayed({
|
||||
//通知贴件开始学习
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setParam(mMac, true,255,0)
|
||||
countDownTimer = object : CountDownTimer(32 * 100, 100) {
|
||||
//1000ms运行一次
|
||||
override fun onFinish() {
|
||||
countDownTimer = null
|
||||
}
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
var unit = (millisUntilFinished/100).toInt()
|
||||
when (unit - 2){
|
||||
5,10,15,20,25 ->{
|
||||
rl_open.background = getDrawable(R.drawable.shape_model_init_green_bg)
|
||||
}
|
||||
|
||||
1,6,11,16,21,26 ->{
|
||||
rl_open.background = getDrawable(R.drawable.shape_model_init_blue_bg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
//5秒之后结束学习
|
||||
Handler().postDelayed({
|
||||
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
|
||||
val curDate = Date(System.currentTimeMillis()) //获取当前时间
|
||||
timeString = formatter.format(curDate)
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setParamTime(mMac, false,255,0,curDate)
|
||||
countDownTimerS = object : CountDownTimer(60 * 1000, 1000) {
|
||||
//1000ms运行一次
|
||||
override fun onFinish() {
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("模型学习失败")
|
||||
countDownTimerS = null
|
||||
}
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
}
|
||||
}.start()
|
||||
},5000)
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
R.id.tv_open_cancel -> {
|
||||
CancelModeInitDialog.instance!!.getShareDialog(this,
|
||||
object : CancelModeInitDialog.PopupYearWindowCallBack {
|
||||
override fun doWork() {
|
||||
mStep = 0
|
||||
setImage()
|
||||
rl_open.background = getDrawable(R.drawable.shape_model_init_gray_bg)
|
||||
tv_open_title.setTextColor(getColor(R.color.color_333333))
|
||||
v_open_status.background = getDrawable(R.drawable.shape_model_init_circel_gray)
|
||||
tv_open_status.text = "未学习"
|
||||
tv_open_status.setTextColor(getColor(R.color.color_333333))
|
||||
tv_open_next.text = "开始学习"
|
||||
tv_open_next.visibility = View.VISIBLE
|
||||
tv_close_next.visibility = View.VISIBLE
|
||||
v_close_bottom.visibility = View.VISIBLE
|
||||
iv_open.visibility = View.VISIBLE
|
||||
ll_open.visibility = View.GONE
|
||||
tv_open_cancel.visibility = View.GONE
|
||||
tv_open_no_response.visibility = View.GONE
|
||||
v_open_top.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_open_bottom.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_open_center.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
R.id.tv_open_no_response ->{
|
||||
mStep = 0
|
||||
setImage()
|
||||
rl_open.background = getDrawable(R.drawable.shape_model_init_gray_bg)
|
||||
tv_open_title.setTextColor(getColor(R.color.color_333333))
|
||||
v_open_status.background = getDrawable(R.drawable.shape_model_init_circel_gray)
|
||||
tv_open_status.text = "未学习"
|
||||
tv_open_status.setTextColor(getColor(R.color.color_333333))
|
||||
tv_open_next.text = "开始学习"
|
||||
tv_open_next.visibility = View.VISIBLE
|
||||
tv_close_next.visibility = View.VISIBLE
|
||||
v_close_bottom.visibility = View.VISIBLE
|
||||
iv_open.visibility = View.VISIBLE
|
||||
ll_open.visibility = View.GONE
|
||||
tv_open_cancel.visibility = View.GONE
|
||||
tv_open_no_response.visibility = View.GONE
|
||||
v_open_top.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_open_bottom.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_open_center.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("消息发送失败,请确认贴件状态")
|
||||
}
|
||||
|
||||
R.id.iv_close_threshold -> {
|
||||
SetThresholdDialog.instance!!.getShareDialog(this,
|
||||
object : SetThresholdDialog.PopupYearWindowCallBack {
|
||||
override fun doWork(value: Int) {
|
||||
showDialog()
|
||||
model2Threshold = value
|
||||
//设置阈值
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setParam(mMac, true,252,value)
|
||||
}
|
||||
},"关闭",deviceInfo!!.model2Threshold)
|
||||
}
|
||||
|
||||
R.id.tv_close_next -> {
|
||||
when (mStep){
|
||||
0 ->{
|
||||
mStep = 3
|
||||
setImage()
|
||||
rl_close.background = getDrawable(R.drawable.shape_model_init_blue_border_bg)
|
||||
tv_close_next.text = "下一步"
|
||||
tv_open_next.visibility = View.GONE
|
||||
v_open_bottom.visibility = View.GONE
|
||||
iv_close.visibility = View.GONE
|
||||
ll_close.visibility = View.VISIBLE
|
||||
tv_close_cancel.visibility = View.VISIBLE
|
||||
iv_close_num.setImageResource(R.mipmap.study_num_icon)
|
||||
tv_close_num.text = "准备学习"
|
||||
tv_close_num.setTextColor(getColor(R.color.color_333333))
|
||||
v_close_study.background = getDrawable(R.drawable.shape_model_init_square_blue)
|
||||
tv_close_des1.text = "学习前请将${deviceInfo!!.type}操作为开启状态"
|
||||
tv_close_des1.setTextColor(getColor(R.color.color_333333))
|
||||
tv_close_des2.visibility = View.GONE
|
||||
v_close_top.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_close_bottom.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_close_center.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
}
|
||||
3 ->{
|
||||
mStep = 4
|
||||
rl_close.background = getDrawable(R.drawable.shape_model_init_blue_bg)
|
||||
tv_close_title.setTextColor(getColor(R.color.white))
|
||||
v_close_status.background = getDrawable(R.drawable.shape_model_init_circel_green)
|
||||
tv_close_status.text = "正在学习"
|
||||
tv_close_status.setTextColor(getColor(R.color.white))
|
||||
tv_close_next.visibility = View.GONE
|
||||
tv_close_cancel.visibility = View.GONE
|
||||
tv_close_no_response.visibility = View.VISIBLE
|
||||
iv_close_num.setImageResource(R.mipmap.study_num_icon2)
|
||||
tv_close_num.text = "学习动作"
|
||||
tv_close_num.setTextColor(getColor(R.color.white))
|
||||
v_close_study.background = getDrawable(R.drawable.shape_model_init_square_green)
|
||||
tv_close_des1.text = "在贴件LED绿色闪烁后请将 ${deviceInfo!!.type} 操作为关闭状态"
|
||||
tv_close_des1.setTextColor(getColor(R.color.white))
|
||||
tv_close_des2.visibility = View.VISIBLE
|
||||
v_close_top.setBackgroundColor(Color.parseColor("#006FDE"))
|
||||
v_close_bottom.setBackgroundColor(Color.parseColor("#006FDE"))
|
||||
v_close_center.setBackgroundColor(Color.parseColor("#006FDE"))
|
||||
Handler().postDelayed({
|
||||
//通知贴件开始学习
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setParam(mMac, true,253,0)
|
||||
countDownTimer = object : CountDownTimer(32 * 100, 100) {
|
||||
//1000ms运行一次
|
||||
override fun onFinish() {
|
||||
countDownTimer = null
|
||||
}
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
var unit = (millisUntilFinished/100).toInt()
|
||||
when (unit - 2){
|
||||
5,10,15,20,25 ->{
|
||||
rl_close.background = getDrawable(R.drawable.shape_model_init_green_bg)
|
||||
}
|
||||
|
||||
1,6,11,16,21,26 ->{
|
||||
rl_close.background = getDrawable(R.drawable.shape_model_init_blue_bg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
//5秒之后结束学习
|
||||
Handler().postDelayed({
|
||||
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
|
||||
val curDate = Date(System.currentTimeMillis()) //获取当前时间
|
||||
timeString = formatter.format(curDate)
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setParamTime(mMac, false,253,0,curDate)
|
||||
countDownTimerS = object : CountDownTimer(60 * 1000, 1000) {
|
||||
//1000ms运行一次
|
||||
override fun onFinish() {
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("模型学习失败")
|
||||
countDownTimerS = null
|
||||
}
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
}
|
||||
}.start()
|
||||
},5000)
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R.id.tv_close_cancel -> {
|
||||
CancelModeInitDialog.instance!!.getShareDialog(this,
|
||||
object : CancelModeInitDialog.PopupYearWindowCallBack {
|
||||
override fun doWork() {
|
||||
mStep = 0
|
||||
setImage()
|
||||
rl_close.background = getDrawable(R.drawable.shape_model_init_gray_bg)
|
||||
tv_close_title.setTextColor(getColor(R.color.color_333333))
|
||||
v_close_status.background = getDrawable(R.drawable.shape_model_init_circel_gray)
|
||||
tv_close_status.text = "未学习"
|
||||
tv_close_status.setTextColor(getColor(R.color.color_333333))
|
||||
tv_close_next.text = "开始学习"
|
||||
tv_close_next.visibility = View.VISIBLE
|
||||
tv_open_next.visibility = View.VISIBLE
|
||||
v_open_bottom.visibility = View.VISIBLE
|
||||
iv_close.visibility = View.VISIBLE
|
||||
ll_close.visibility = View.GONE
|
||||
tv_close_cancel.visibility = View.GONE
|
||||
tv_close_no_response.visibility = View.GONE
|
||||
v_close_top.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_close_bottom.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_close_center.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
R.id.tv_close_no_response ->{
|
||||
mStep = 0
|
||||
setImage()
|
||||
rl_close.background = getDrawable(R.drawable.shape_model_init_gray_bg)
|
||||
tv_close_title.setTextColor(getColor(R.color.color_333333))
|
||||
v_close_status.background = getDrawable(R.drawable.shape_model_init_circel_gray)
|
||||
tv_close_status.text = "未学习"
|
||||
tv_close_status.setTextColor(getColor(R.color.color_333333))
|
||||
tv_close_next.text = "开始学习"
|
||||
tv_close_next.visibility = View.VISIBLE
|
||||
tv_open_next.visibility = View.VISIBLE
|
||||
v_open_bottom.visibility = View.VISIBLE
|
||||
iv_close.visibility = View.VISIBLE
|
||||
ll_close.visibility = View.GONE
|
||||
tv_close_cancel.visibility = View.GONE
|
||||
tv_close_no_response.visibility = View.GONE
|
||||
v_close_top.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_close_bottom.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_close_center.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("消息发送失败,请确认贴件状态")
|
||||
}
|
||||
|
||||
R.id.tv_verify -> {
|
||||
if(iv_open_threshold.visibility == View.VISIBLE&&iv_close_threshold.visibility == View.VISIBLE){
|
||||
xValues.clear()
|
||||
values.clear()
|
||||
showDialog()
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setMode(mMac, true,2)
|
||||
countDownTimerS = object : CountDownTimer(60 * 1000, 1000) {
|
||||
//1000ms运行一次
|
||||
override fun onFinish() {
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("进入验证模式失败,请确认贴件状态,并重新进入")
|
||||
countDownTimerS = null
|
||||
}
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun showDeviceSettingData(event: DeviceSettingEvent?) {
|
||||
try {
|
||||
if (event?.data != null && event.mac != null&&event.flag!=null) {
|
||||
if(Utils.formatMac(event.mac, ":").equals(mMac)){
|
||||
if(event.flag==4) {
|
||||
var start = HexUtil.byteToInt(event?.data[0])
|
||||
when (HexUtil.byteToInt(event?.data[1])) {
|
||||
0 -> {
|
||||
when (HexUtil.byteToInt(event?.data[2])) {
|
||||
1 -> {
|
||||
Log.i(TAG, event.mac + "频率设置成功")
|
||||
}
|
||||
255 -> {
|
||||
if(start==0) {
|
||||
countDownTimerS!!.cancel()
|
||||
countDownTimerS = null
|
||||
Log.i(TAG, event.mac + "算法模型1学习成功")
|
||||
ToastUtil.showToast("“打开”模型学习成功")
|
||||
// var timeString = TimeUtil.getNowTime()
|
||||
mStep = 0
|
||||
setImage()
|
||||
rl_open.background =
|
||||
getDrawable(R.drawable.shape_model_init_gray_bg)
|
||||
tv_open_title.setTextColor(getColor(R.color.color_333333))
|
||||
v_open_status.background =
|
||||
getDrawable(R.drawable.shape_model_init_circel_black)
|
||||
tv_open_status.text = "上次学习时间:${timeString}"
|
||||
tv_open_status.setTextColor(getColor(R.color.color_333333))
|
||||
tv_open_next.text = "开始学习"
|
||||
tv_open_next.visibility = View.VISIBLE
|
||||
tv_close_next.visibility = View.VISIBLE
|
||||
v_close_bottom.visibility = View.VISIBLE
|
||||
iv_open.visibility = View.VISIBLE
|
||||
ll_open.visibility = View.GONE
|
||||
tv_open_cancel.visibility = View.GONE
|
||||
tv_open_no_response.visibility = View.GONE
|
||||
v_open_top.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_open_bottom.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_open_center.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
iv_open_threshold.visibility = View.VISIBLE
|
||||
|
||||
if (iv_open_threshold.visibility == View.VISIBLE && iv_close_threshold.visibility == View.VISIBLE) {
|
||||
tv_verify.background =
|
||||
getDrawable(R.drawable.shape_model_init_verify_btn_blue_bg)
|
||||
tv_verify.setTextColor(getColor(R.color.white))
|
||||
} else {
|
||||
tv_verify.background =
|
||||
getDrawable(R.drawable.shape_model_init_verify_btn_gray_bg)
|
||||
tv_verify.setTextColor(Color.parseColor("#ffa1a1a1"))
|
||||
}
|
||||
}
|
||||
}
|
||||
254 -> {
|
||||
deviceInfo!!.model1Threshold = model1Threshold
|
||||
Log.i(TAG, event.mac + "算法模型1阈值设置成功")
|
||||
ToastUtil.showToast("“打开”模型阈值设置成功")
|
||||
dismissDialog()
|
||||
}
|
||||
253 -> {
|
||||
if(start==0) {
|
||||
countDownTimerS!!.cancel()
|
||||
countDownTimerS = null
|
||||
Log.i(TAG, event.mac + "算法模型2学习成功")
|
||||
ToastUtil.showToast("“关闭”模型学习成功")
|
||||
// var timeString = TimeUtil.getNowTime()
|
||||
mStep = 0
|
||||
setImage()
|
||||
rl_close.background =
|
||||
getDrawable(R.drawable.shape_model_init_gray_bg)
|
||||
tv_close_title.setTextColor(getColor(R.color.color_333333))
|
||||
v_close_status.background =
|
||||
getDrawable(R.drawable.shape_model_init_circel_black)
|
||||
tv_close_status.text = "上次学习时间:${timeString}"
|
||||
tv_close_status.setTextColor(getColor(R.color.color_333333))
|
||||
tv_close_next.text = "开始学习"
|
||||
tv_close_next.visibility = View.VISIBLE
|
||||
tv_open_next.visibility = View.VISIBLE
|
||||
v_open_bottom.visibility = View.VISIBLE
|
||||
iv_close.visibility = View.VISIBLE
|
||||
ll_close.visibility = View.GONE
|
||||
tv_close_cancel.visibility = View.GONE
|
||||
tv_close_no_response.visibility = View.GONE
|
||||
v_close_top.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_close_bottom.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
v_close_center.setBackgroundColor(Color.parseColor("#C6CFD9"))
|
||||
iv_close_threshold.visibility = View.VISIBLE
|
||||
|
||||
if (iv_open_threshold.visibility == View.VISIBLE && iv_close_threshold.visibility == View.VISIBLE) {
|
||||
tv_verify.background =
|
||||
getDrawable(R.drawable.shape_model_init_verify_btn_blue_bg)
|
||||
tv_verify.setTextColor(getColor(R.color.white))
|
||||
} else {
|
||||
tv_verify.background =
|
||||
getDrawable(R.drawable.shape_model_init_verify_btn_gray_bg)
|
||||
tv_verify.setTextColor(Color.parseColor("#ffa1a1a1"))
|
||||
}
|
||||
}
|
||||
}
|
||||
252 -> {
|
||||
deviceInfo!!.model2Threshold = model2Threshold
|
||||
Log.i(TAG, event.mac + "算法模型2阈值设置成功")
|
||||
ToastUtil.showToast("“关闭”模型阈值设置成功")
|
||||
dismissDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
252 -> Log.i(TAG, event.mac + "设备忙碌")
|
||||
251 -> Log.i(TAG, event.mac + "保存参数失败")
|
||||
250 -> Log.i(TAG, event.mac + "算法模型学习失败")
|
||||
249 -> Log.i(TAG, event.mac + "指令无效")
|
||||
}
|
||||
}else if(event.flag == 5){
|
||||
when (HexUtil.byteToInt(event.data[2])) {
|
||||
0 -> {
|
||||
when (HexUtil.byteToInt(event.data[1])) {
|
||||
0 -> Log.i(TAG, event.mac + "正常工作成功")
|
||||
1 -> Log.i(TAG, event.mac + "强制休眠成功")
|
||||
2 -> {
|
||||
when (HexUtil.byteToInt(event.data[0])) {
|
||||
0 -> {
|
||||
dismissDialog()
|
||||
countDownTimerS!!.cancel()
|
||||
countDownTimerS = null
|
||||
Log.i(TAG, event.mac + "结束模型验证成功")
|
||||
ToastUtil.showToast("退出模型验证模式")
|
||||
}
|
||||
1 -> {
|
||||
dismissDialog()
|
||||
countDownTimerS!!.cancel()
|
||||
countDownTimerS = null
|
||||
Log.i(TAG, event.mac + "开启模型验证成功")
|
||||
ToastUtil.showToast("进入模型验证模式")
|
||||
DataServer.nBlueToothVerifyMac = mMac
|
||||
// values.add(Entry(0F, 0F)) //其中两个数字对应的分别是 X轴 Y轴
|
||||
// values.add(Entry(1F, 1F))
|
||||
// values.add(Entry(2F, 0F))
|
||||
// values.add(Entry(3F, 1F))
|
||||
// values.add(Entry(4F, 0F))
|
||||
ModeInitVerifyDialog.instance!!.getShareDialog(this,
|
||||
object : ModeInitVerifyDialog.PopupYearWindowCallBack {
|
||||
override fun doWork() {
|
||||
showDialog()
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setMode(mMac, false,2)
|
||||
countDownTimerS = object : CountDownTimer(180 * 1000, 1000) {
|
||||
//1000ms运行一次
|
||||
override fun onFinish() {
|
||||
dismissDialog()
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("退出模型验证模式")
|
||||
countDownTimerS = null
|
||||
}
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
if(millisUntilFinished/1000<120) {
|
||||
if (!isShowVerifyToast) {
|
||||
isShowVerifyToast = true
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("退出验证模式失败,120s后自动退出")
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
},values,xValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
3 -> Log.i(TAG, event.mac + "开启模型2验证成功")
|
||||
}
|
||||
}
|
||||
252 -> Log.i(TAG, event.mac + "设备忙碌")
|
||||
251 -> Log.i(TAG, event.mac + "保存参数失败")
|
||||
250 -> Log.i(TAG, event.mac + "算法模型学习失败")
|
||||
249 -> Log.i(TAG, event.mac + "指令无效")
|
||||
}
|
||||
}else if(event.flag == 6){
|
||||
xValues!!.add(TimeUtil.getNowTimeHourMinuteSecond()!!)
|
||||
when (HexUtil.byteToInt(event.data[1])) {
|
||||
255 -> {
|
||||
values!!.add(Entry((xValues.size-1).toFloat(), 1F))
|
||||
}
|
||||
254 -> {
|
||||
values!!.add(Entry((xValues.size-1).toFloat(), 0F))
|
||||
}
|
||||
}
|
||||
ModeInitVerifyDialog.instance!!.updateData(xValues,values)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: java.lang.Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,498 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.CountDownTimer
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.qidian.baseble.ViseBle
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.config.EventCode
|
||||
import com.qidian.zhongkesmart.dialog.*
|
||||
import com.qidian.zhongkesmart.model.ActionInfo
|
||||
import com.qidian.zhongkesmart.model.BindBlueToothData
|
||||
import com.qidian.zhongkesmart.model.DeviceInfo
|
||||
import com.qidian.zhongkesmart.model.GetTokenM
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import com.qidian.zhongkesmart.utils.ObjectBoxUtils.addData
|
||||
import com.qidian.zhongkesmart.utils.TimeUtil.getNowTime
|
||||
import com.qidian.zjlw.presenter.Contract
|
||||
import com.qidian.zjlw.presenter.MainPresenter
|
||||
import com.qidian.zxing.lib_zxing.activity.CodeUtils
|
||||
import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener
|
||||
import com.scwang.smartrefresh.layout.listener.OnRefreshListener
|
||||
import kotlinx.android.synthetic.main.activity_base.*
|
||||
import kotlinx.android.synthetic.main.activity_my_equipment.*
|
||||
import kotlinx.android.synthetic.main.empty_layout.*
|
||||
import kotlinx.android.synthetic.main.item_myequipment.*
|
||||
import kotlinx.android.synthetic.main.layout_list.*
|
||||
import kotlinx.android.synthetic.main.view_status.*
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
import net.idik.lib.slimadapter.SlimInjector
|
||||
import net.idik.lib.slimadapter.viewinjector.IViewInjector
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
/*我的设备*/
|
||||
class MyEquipmentActivity : BaseActivity(), EasyPermissions.PermissionCallbacks,
|
||||
Contract.GovernmentView {
|
||||
var mData = ArrayList<DeviceInfo>()
|
||||
private val mPresenter by lazy { MainPresenter() }
|
||||
private val REQUEST_CODE = 100
|
||||
var mTJMac = ""
|
||||
var countDownTimer: CountDownTimer? = null
|
||||
var isResume = false
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_my_equipment
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
mPresenter.attachView(this)
|
||||
refreshLayout_list.setOnRefreshListener(mOnRefreshListener)
|
||||
refreshLayout_list.setOnLoadMoreListener(mOnLoadMoreListener)
|
||||
LoadUtils.loadingasGridview(this, recycle_list, 3)
|
||||
mAdapter =
|
||||
SlimAdapter.create()
|
||||
.register<DeviceInfo>(
|
||||
R.layout.item_myequipment,
|
||||
object : SlimInjector<DeviceInfo> {
|
||||
override fun onInject(
|
||||
data: DeviceInfo,
|
||||
injector: IViewInjector<out IViewInjector<*>>
|
||||
) {
|
||||
injector.with<ImageView>(R.id.imv_myequipment) {
|
||||
it.setImageResource(ToolUtil.getMyEquitmentPageImage(data))
|
||||
}
|
||||
injector.text(R.id.tv_myequipment_open_status, ToolUtil.getMyEquitmentOpenStatus(data.mac))
|
||||
injector.text(R.id.tv_myequipment_name, data.type)
|
||||
injector.text(R.id.tv_myequipment_type, data.name)
|
||||
injector.text(R.id.tv_myequipment_bluetype, "低功耗蓝牙")
|
||||
injector.with<TextView>(R.id.tv_myequipment_status) {
|
||||
//是否在线
|
||||
if (data.isOnline) {
|
||||
injector.text(R.id.tv_myequipment_status, "正常")
|
||||
it.setTextColor(Color.parseColor("#0079F5"))
|
||||
} else {
|
||||
injector.text(R.id.tv_myequipment_status, "离线")
|
||||
it.setTextColor(Color.parseColor("#99333333"))
|
||||
}
|
||||
}
|
||||
Log.e(TAG,data.power)
|
||||
// Log.e(TAG,Integer.valueOf(data.power,16).toString())
|
||||
// injector.text(R.id.tv_myequipment_power, "电量:${data.power}%")
|
||||
if(data.power == ""){
|
||||
injector.text(
|
||||
R.id.tv_myequipment_power,
|
||||
"0%"
|
||||
)
|
||||
}else {
|
||||
injector.text(
|
||||
R.id.tv_myequipment_power,
|
||||
"${Integer.valueOf(data.power, 10)}%"
|
||||
)
|
||||
}
|
||||
injector.clicked(R.id.li_myequipment) {
|
||||
startActivity(
|
||||
Intent(
|
||||
this@MyEquipmentActivity,
|
||||
MyEquipmentDetailsActivity::class.java
|
||||
).putExtra("mac", data.mac)
|
||||
)
|
||||
}
|
||||
injector.with<LinearLayout>(R.id.li_myequipment) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
.attachTo(recycle_list)
|
||||
getData()
|
||||
//添加设备
|
||||
tv_button.setOnClickListener {
|
||||
if (DataServer.mHttpToken.isNullOrEmpty()) {
|
||||
ToastUtil.showToast("您还未绑定网关")
|
||||
} else {
|
||||
askPermissionOfCamera()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定贴件信息
|
||||
*/
|
||||
fun getData() {
|
||||
var dList = ObjectBoxUtils.getAllData(DeviceInfo::class.java)
|
||||
var rList = ArrayList<DeviceInfo>()
|
||||
dList!!.forEach {
|
||||
if(it.isBind){
|
||||
rList.add(it)
|
||||
}
|
||||
}
|
||||
if (rList.isNullOrEmpty()) {
|
||||
recycle_list.visibility = View.GONE
|
||||
tv_myequipment_num.visibility = View.GONE
|
||||
layEmpty.visibility = View.VISIBLE
|
||||
} else {
|
||||
mData.clear()
|
||||
mData.addAll(rList)
|
||||
mAdapter!!.updateData(mData).notifyDataSetChanged()
|
||||
recycle_list.visibility = View.VISIBLE
|
||||
tv_myequipment_num.visibility = View.VISIBLE
|
||||
layEmpty.visibility = View.GONE
|
||||
tv_myequipment_num.text = "${mData.size}个"
|
||||
}
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
override fun isShowTitle(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新
|
||||
*/
|
||||
private val mOnRefreshListener = OnRefreshListener {
|
||||
refreshLayout_list.finishRefresh()
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载
|
||||
*/
|
||||
private val mOnLoadMoreListener = OnLoadMoreListener {
|
||||
refreshLayout_list.finishLoadMore()
|
||||
/*if (!isLoadingMore) {
|
||||
isLoadingMore = true
|
||||
currentPage++
|
||||
getData()
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.tv_button -> {
|
||||
recycle_list.visibility = View.VISIBLE
|
||||
tv_myequipment_num.visibility = View.VISIBLE
|
||||
layEmpty.visibility = View.GONE
|
||||
}
|
||||
|
||||
R.id.iv_back -> {
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
R.id.imv_index_add -> {
|
||||
if (DataServer.mHttpToken.isNullOrEmpty()) {
|
||||
ToastUtil.showToast("您还未绑定网关")
|
||||
} else {
|
||||
askPermissionOfCamera()
|
||||
}
|
||||
// for (i in 0 until 2000) {
|
||||
// val actionInfo = ActionInfo()
|
||||
// actionInfo.mac = "C7:3D:41:CB:A8:36"
|
||||
// if(i%2==0) {
|
||||
// actionInfo.data = byteArrayOf(0x00, 0xff.toByte())
|
||||
// }else{
|
||||
// actionInfo.data = byteArrayOf(0x00, 0xfe.toByte())
|
||||
// }
|
||||
// actionInfo.time = getNowTime()!!
|
||||
// addData(actionInfo, ActionInfo::class.java)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun askPermissionOfCamera() {
|
||||
EasyPermissions.requestPermissions(
|
||||
this,
|
||||
"二维码扫码,请允许获取您的摄像头权限",
|
||||
DataServer.ACCESS_CAMERA_CODE,
|
||||
Manifest.permission.CAMERA
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_CAMERA_CODE) {
|
||||
val intent =
|
||||
Intent(this, com.qidian.zxing.lib_zxing.activity.CaptureActivity::class.java)
|
||||
startActivityForResult(intent, REQUEST_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_CAMERA_CODE) {
|
||||
ToastUtil.showToast("摄像头权限获取失败,扫码功能不可用!")
|
||||
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
intent.data = Uri.fromParts("package", packageName, null)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode == REQUEST_CODE) {
|
||||
//处理扫描结果(在界面上显示)
|
||||
if (null != data) {
|
||||
val bundle = data.extras
|
||||
if (bundle != null) {
|
||||
if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
|
||||
val result = bundle.getString(CodeUtils.RESULT_STRING)
|
||||
Log.i("Zxing_Result", result!!)
|
||||
// var mTJMac = ToolUtil.formatMac(result!!)
|
||||
mTJMac = result!!
|
||||
FindNewEquipmentDialog.instance!!.getShareDialog(this,
|
||||
mTJMac,
|
||||
object : FindNewEquipmentDialog.PopupYearWindowCallBack {
|
||||
//新增
|
||||
override fun doWork(roomName: String?, type: String?) {
|
||||
if(!ToolUtil.isContainsTJData(roomName!!,type!!, mTJMac,this@MyEquipmentActivity)){
|
||||
mPresenter.getbindDevice(
|
||||
this@MyEquipmentActivity,
|
||||
mTJMac,
|
||||
roomName!!,
|
||||
type!!,
|
||||
|
||||
)
|
||||
}else{
|
||||
ToastUtil.showToast("请勿重复添加")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//修改
|
||||
override fun doChangeWork(roomName: String?, type: String?) {
|
||||
if(!ToolUtil.isContainsTJData(roomName!!,type!!, mTJMac,this@MyEquipmentActivity)) {
|
||||
mPresenter.getChangeDevice(
|
||||
this@MyEquipmentActivity,
|
||||
mTJMac,
|
||||
roomName,
|
||||
type
|
||||
)
|
||||
}else{
|
||||
ToastUtil.showToast("请勿重复添加")
|
||||
}
|
||||
}
|
||||
|
||||
//解绑
|
||||
override fun doUnBindWork() {
|
||||
mPresenter.removebindDevice(this@MyEquipmentActivity, mTJMac)
|
||||
}
|
||||
|
||||
override fun doConnectTj() {
|
||||
if(DataServer.connectMode==2) {
|
||||
if (!ViseBle.getInstance().deviceMirrorPool.isConnectDevice) {
|
||||
FindNewEquipmentDialog.instance!!.connectFail()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
WakeUpDeviceDialog.instance!!.getShareDialog(this@MyEquipmentActivity,
|
||||
object : WakeUpDeviceDialog.PopupYearWindowCallBack {
|
||||
override fun doCancel() {
|
||||
countDownTimer!!.cancel()
|
||||
countDownTimer = null
|
||||
DataServer.nBlueToothVerifyMac = ""
|
||||
DataServer.nBlueToothMac = ""
|
||||
}
|
||||
})
|
||||
//广播模式下,需要连接贴件
|
||||
if(DataServer.connectMode==1){
|
||||
DataServer.nBlueToothMac = mTJMac
|
||||
}
|
||||
DataServer.nBlueToothVerifyMac = mTJMac
|
||||
countDownTimer = object : CountDownTimer(60 * 1000, 1000) {
|
||||
//1000ms运行一次
|
||||
override fun onFinish() {
|
||||
ToastUtil.showToast("进入配置模式失败,请重新尝试")
|
||||
WakeUpDeviceDialog.instance!!.setDismiss()
|
||||
DataServer.nBlueToothVerifyMac = ""
|
||||
DataServer.nBlueToothMac = ""
|
||||
countDownTimer = null
|
||||
}
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
override fun doDismiss() {
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
} else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
|
||||
ToastUtil.showToast("解析二维码失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//修改信息
|
||||
override fun showChangeResult(messModel: Any?, mac: String, type: String?, roomName: String?) {
|
||||
ToastUtil.showToast("修改成功")
|
||||
FindNewEquipmentDialog.instance!!.bindSuccess()
|
||||
//修改本地该条记录
|
||||
ToolUtil.ChangeHistory(
|
||||
this,
|
||||
DataServer.mBindHistory,
|
||||
mac, BindBlueToothData(
|
||||
mac,
|
||||
BlueToothUtils.instance!!.getBlueToothPower(mac),
|
||||
roomName!!,
|
||||
type!!, TimeUtil.getNowTime()!!
|
||||
)
|
||||
)
|
||||
//修改该贴件接收蓝牙数据里面的type类型 (震动型、移动型)
|
||||
ToolUtil.changeMacBlueToothHistory(mac, this)
|
||||
|
||||
var list = ObjectBoxUtils.getDeviceByMac(mac)
|
||||
var deviceInfo:DeviceInfo?;
|
||||
if (list != null && list.isNotEmpty()) {
|
||||
deviceInfo = list[0]
|
||||
deviceInfo!!.isBind = true
|
||||
deviceInfo!!.name = roomName!!
|
||||
deviceInfo!!.type = type!!
|
||||
} else {
|
||||
deviceInfo = DeviceInfo()
|
||||
deviceInfo.mac = mac
|
||||
deviceInfo.isBind = true
|
||||
deviceInfo.name = roomName!!
|
||||
deviceInfo.type = type!!
|
||||
}
|
||||
ObjectBoxUtils.updateData(deviceInfo, DeviceInfo::class.java)
|
||||
|
||||
getData()
|
||||
}
|
||||
|
||||
//新增绑定
|
||||
override fun showAddResult(messModel: Any?, mac: String, type: String?, roomName: String?) {
|
||||
ToastUtil.showToast("绑定成功")
|
||||
FindNewEquipmentDialog.instance!!.bindSuccess()
|
||||
//存本地
|
||||
ToolUtil.addHistory(
|
||||
this,
|
||||
DataServer.mBindHistory,
|
||||
BindBlueToothData(
|
||||
mac,
|
||||
BlueToothUtils.instance!!.getBlueToothPower(mac),
|
||||
roomName!!,
|
||||
type!!, TimeUtil.getNowTime()!!
|
||||
)
|
||||
)
|
||||
var list = ObjectBoxUtils.getDeviceByMac(mac)
|
||||
var deviceInfo: DeviceInfo?;
|
||||
if (list != null && list.isNotEmpty()) {
|
||||
deviceInfo = list[0]
|
||||
deviceInfo!!.isBind = true
|
||||
deviceInfo!!.time = TimeUtil.getNowTime()!!
|
||||
deviceInfo!!.name = roomName!!
|
||||
deviceInfo!!.type = type!!
|
||||
} else {
|
||||
deviceInfo = DeviceInfo()
|
||||
deviceInfo.mac = mac
|
||||
deviceInfo.isBind = true
|
||||
deviceInfo.name = roomName!!
|
||||
deviceInfo.type = type!!
|
||||
deviceInfo.time = TimeUtil.getNowTime()!!
|
||||
}
|
||||
ObjectBoxUtils.updateData(deviceInfo, DeviceInfo::class.java)
|
||||
getData()
|
||||
}
|
||||
|
||||
|
||||
//解除绑定
|
||||
override fun showRemoveResult(messModel: Any?, mac: String) {
|
||||
ToastUtil.showToast("解除绑定成功")
|
||||
FindNewEquipmentDialog.instance!!.setDismiss()
|
||||
//清除本地该条记录
|
||||
ToolUtil.deleteHistory(
|
||||
this,
|
||||
DataServer.mBindHistory,
|
||||
mac
|
||||
)
|
||||
//将本地存储的蓝牙接收数据中的该贴件的信息删除
|
||||
ToolUtil.clearMacBlueToothHistory(mac)
|
||||
ObjectBoxUtils.deleteALLDataD(ObjectBoxUtils.getDeviceByMac(mac))
|
||||
ObjectBoxUtils.deleteALLDataA(ObjectBoxUtils.getActionByMac(mac))
|
||||
getData()
|
||||
}
|
||||
|
||||
//获取token
|
||||
override fun showTokenResult(messModel: Any?) {
|
||||
var model = messModel as GetTokenM
|
||||
var mToken = model.token
|
||||
DataServer.mHttpToken = mToken
|
||||
askPermissionOfCamera()
|
||||
}
|
||||
|
||||
override fun showAfter() {
|
||||
}
|
||||
|
||||
|
||||
override fun receiveEvent(event: EventBusUtil.MessageEvent) {
|
||||
super.receiveEvent(event)
|
||||
when (event.code) {
|
||||
/**
|
||||
* 蓝牙数据推送-正常离线状态改变时候更新数据
|
||||
*/
|
||||
EventCode.BLUETOOTHDATA_Refresh -> {
|
||||
if(isResume) {
|
||||
mAdapter!!.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 贴件唤醒成功
|
||||
*/
|
||||
EventCode.DEVICE_WAKE_UP_SUCCEED -> {
|
||||
if(isResume) {
|
||||
if (WakeUpDeviceDialog.instance!!.isShowing()) {
|
||||
WakeUpDeviceDialog.instance!!.setDismiss()
|
||||
FindNewEquipmentDialog.instance!!.setDismiss()
|
||||
countDownTimer!!.cancel()
|
||||
countDownTimer = null
|
||||
startActivity(
|
||||
Intent(
|
||||
this@MyEquipmentActivity,
|
||||
SettingModeActivity::class.java
|
||||
).putExtra("mac", mTJMac)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
isResume = true
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
isResume = false
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
try {
|
||||
FindNewEquipmentDialog.instance!!.setDismiss()
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,298 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Color
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.blankj.utilcode.util.TimeUtils
|
||||
import com.github.mikephil.charting.data.BarData
|
||||
import com.github.mikephil.charting.data.BarDataSet
|
||||
import com.github.mikephil.charting.data.BarEntry
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.model.*
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import kotlinx.android.synthetic.main.activity_my_equipment.*
|
||||
import kotlinx.android.synthetic.main.activity_my_equipment_details.*
|
||||
import kotlinx.android.synthetic.main.empty_layout.*
|
||||
import kotlinx.android.synthetic.main.layout_barchart.*
|
||||
import kotlinx.android.synthetic.main.layout_list.*
|
||||
|
||||
|
||||
/*我的设备详情*/
|
||||
class MyEquipmentDetailsActivity : BaseActivity() {
|
||||
var xValues = ArrayList<String>()
|
||||
val values = ArrayList<BarEntry>()
|
||||
val values1 = ArrayList<BarEntry>()
|
||||
var mTabs = arrayOf("今日", "本周", "本月", "本年")
|
||||
var mMac=""
|
||||
var mTodayData=ArrayList<TimeDataWithTime>()
|
||||
var mWeekData=ArrayList<TimeDataWithTime>()
|
||||
var mMonthData=ArrayList<TimeDataWithTime>()
|
||||
var mYearData=ArrayList<TimeDataWithTime>()
|
||||
var deviceInfo: DeviceInfo? = null
|
||||
var tapPositon = 0
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_my_equipment_details
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
mMac=intent.getStringExtra("mac").toString()
|
||||
deviceInfo = ObjectBoxUtils.getDeviceByMac(mMac)!![0]
|
||||
tv_left_title.text = "${deviceInfo!!.name}-${deviceInfo!!.type}"
|
||||
//是否在线
|
||||
if(deviceInfo!!.isOnline){
|
||||
tv_myequipment_status.text="正常"
|
||||
tv_myequipment_mark.setBackgroundResource(R.drawable.ed_yuan0fba61)
|
||||
}else{
|
||||
tv_myequipment_status.text="离线"
|
||||
tv_myequipment_mark.setBackgroundResource(R.drawable.ed_yuangray)
|
||||
}
|
||||
//电量
|
||||
// tv_myequipment_power.text="${BlueToothUtils.instance!!.getBlueToothPower(mMac)}%"
|
||||
if(deviceInfo!!.power==""){
|
||||
tv_myequipment_power.text="0%"
|
||||
}else {
|
||||
tv_myequipment_power.text =
|
||||
"${Integer.valueOf(deviceInfo!!.power, 10)}%"
|
||||
}
|
||||
//Tab
|
||||
mTabs.forEach {
|
||||
tablayout_type.addTab(tablayout_type.newTab().setText(it))
|
||||
}
|
||||
tablayout_type.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabReselected(p0: TabLayout.Tab?) {
|
||||
}
|
||||
|
||||
override fun onTabUnselected(p0: TabLayout.Tab?) {
|
||||
}
|
||||
|
||||
override fun onTabSelected(p0: TabLayout.Tab?) {
|
||||
showDialog()
|
||||
tapPositon = p0!!.position
|
||||
startViewThread(tapPositon)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
//查取位置用途信息
|
||||
// var myEquipmentData= ToolUtil.getHistory(DataServer.mBindHistory,this)
|
||||
// myEquipmentData.forEach {
|
||||
// if(it.mac==mMac){
|
||||
//
|
||||
// }
|
||||
// }
|
||||
showDialog()
|
||||
startThread()
|
||||
}
|
||||
|
||||
@SuppressLint("HandlerLeak")
|
||||
var handler: Handler = object : Handler() {
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
|
||||
|
||||
Log.e("Handle==", "ing")
|
||||
Log.e("Handle==", "tapPositon "+tapPositon)
|
||||
Log.e("Handle==", "xValues.size "+xValues.size)
|
||||
Log.e("Handle==", "values.size "+values.size)
|
||||
Log.e("Handle==", "values1.size "+values1.size)
|
||||
this.removeMessages(0)
|
||||
dismissDialog()
|
||||
|
||||
barchart.zoom(0f, 1f, 0f, 0f)
|
||||
when(tapPositon){
|
||||
0->{//今日
|
||||
barchart.zoom(0f, 1f, 0f, 0f)
|
||||
barchart.zoom(2f, 1f, 0f, 0f)
|
||||
}
|
||||
1->{//本周
|
||||
barchart.zoom(0f, 1f, 0f, 0f)
|
||||
barchart.zoom(1f, 1f, 0f, 0f)
|
||||
}
|
||||
2->{//本月
|
||||
barchart.zoom(0f, 1f, 0f, 0f)
|
||||
barchart.zoom(3f, 1f, 0f, 0f)
|
||||
}
|
||||
3->{//本年
|
||||
barchart.zoom(0f, 1f, 0f, 0f)
|
||||
barchart.zoom(1f, 1f, 0f, 0f)
|
||||
}
|
||||
}
|
||||
var set = BarDataSet(values, "开启次数")
|
||||
set!!.color = Color.parseColor("#516AFC")
|
||||
var set1 = BarDataSet(values1, "关闭次数")
|
||||
set1!!.color = Color.parseColor("#516A33")
|
||||
val dataSetbar: ArrayList<IBarDataSet> = ArrayList()
|
||||
dataSetbar.add(set)
|
||||
dataSetbar.add(set1)
|
||||
var data = BarData(dataSetbar)
|
||||
data.barWidth = 0.5f
|
||||
//有数据时候传true 无数据时候传false
|
||||
if (values.size > 0) {
|
||||
ChartUtils.initBarChart(
|
||||
barchart,
|
||||
xValues,
|
||||
data!!,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
} else {
|
||||
ChartUtils.initBarChart(
|
||||
barchart,
|
||||
xValues,
|
||||
data!!,
|
||||
true,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun startThread() {
|
||||
Thread(object : Runnable {
|
||||
override fun run() {
|
||||
//读取与写入
|
||||
getData()
|
||||
handler.sendEmptyMessage(0)
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
|
||||
override fun isShowTitle(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getData(){
|
||||
//查取图表信息
|
||||
var aList = ObjectBoxUtils.getActionByMac(mMac)
|
||||
aList!!.forEach {
|
||||
var openTime = TimeUtils.string2Millis(it.time)
|
||||
if(TimeUtil.isInToday(openTime)){
|
||||
mTodayData.add(TimeDataWithTime(openTime,0,"", it.data!!))
|
||||
// showLog(mTodayData)
|
||||
}
|
||||
if(TimeUtil.isInWeek(openTime)){
|
||||
mWeekData.add(TimeDataWithTime(openTime,0,"", it.data!!))
|
||||
// showLog(mWeekData)
|
||||
}
|
||||
if(TimeUtil.isInMonth(openTime)){
|
||||
mMonthData.add(TimeDataWithTime(openTime,0,"", it.data!!))
|
||||
// showLog(mMonthData)
|
||||
}
|
||||
if(TimeUtil.isInYear(openTime)){
|
||||
mYearData.add(TimeDataWithTime(openTime,0,"", it.data!!))
|
||||
// showLog(mYearData)
|
||||
}
|
||||
}
|
||||
getViewData(tapPositon)
|
||||
}
|
||||
|
||||
fun startViewThread(poi:Int){
|
||||
Thread(object : Runnable {
|
||||
override fun run() {
|
||||
//读取与写入
|
||||
getViewData(poi)
|
||||
handler.sendEmptyMessage(0)
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
|
||||
|
||||
@Synchronized
|
||||
fun getViewData(poi: Int) {
|
||||
xValues.clear()
|
||||
values.clear()
|
||||
values1.clear()
|
||||
//设置缩放比例
|
||||
// barchart.zoom(0f, 1f, 0f, 0f)
|
||||
var list=ArrayList<LineViewData1>()
|
||||
when(poi){
|
||||
0->{//今日
|
||||
list.addAll(TimeUtil.formatTodayDataNew(mTodayData))
|
||||
// barchart.zoom(0f, 1f, 0f, 0f)
|
||||
// barchart.zoom(2f, 1f, 0f, 0f)
|
||||
}
|
||||
1->{//本周
|
||||
list.addAll(TimeUtil.formatWeekDataNew(mWeekData))
|
||||
// barchart.zoom(0f, 1f, 0f, 0f)
|
||||
// barchart.zoom(1f, 1f, 0f, 0f)
|
||||
}
|
||||
2->{//本月
|
||||
list.addAll(TimeUtil.formatMonthDataNew(mMonthData))
|
||||
// barchart.zoom(0f, 1f, 0f, 0f)
|
||||
// barchart.zoom(3f, 1f, 0f, 0f)
|
||||
}
|
||||
3->{//本年
|
||||
list.addAll(TimeUtil.formatYearDataNew(mYearData))
|
||||
// barchart.zoom(0f, 1f, 0f, 0f)
|
||||
// barchart.zoom(1f, 1f, 0f, 0f)
|
||||
}
|
||||
}
|
||||
// showLog(list)
|
||||
for(i in 0 until list.size){
|
||||
//X轴显示
|
||||
xValues.add(list[i].timeLocation)
|
||||
//柱状图数据
|
||||
// values.add(BarEntry(i * 1f, (list[i].mSize).toFloat()))
|
||||
values.add(BarEntry(i * 1f, (list[i].mSizeO).toFloat()))
|
||||
values1.add(BarEntry(i * 1f, (list[i].mSizeC).toFloat()))
|
||||
}
|
||||
/* for (i in 0..10) {
|
||||
//X轴显示
|
||||
xValues.add("0${i}:00")
|
||||
//柱状图数据
|
||||
values.add(BarEntry(i * 1f, i * poi * 10f))
|
||||
}*/
|
||||
|
||||
// var set = BarDataSet(values, "开启次数")
|
||||
// set!!.color = Color.parseColor("#516AFC")
|
||||
//
|
||||
// var set1 = BarDataSet(values1, "关闭次数")
|
||||
// set1!!.color = Color.parseColor("#516A33")
|
||||
// val dataSetbar: ArrayList<IBarDataSet> = ArrayList()
|
||||
// dataSetbar.add(set)
|
||||
// dataSetbar.add(set1)
|
||||
// var data = BarData(dataSetbar)
|
||||
// data.barWidth = 0.5f
|
||||
// //有数据时候传true 无数据时候传false
|
||||
// if (values.size > 0) {
|
||||
// ChartUtils.initBarChart(
|
||||
// barchart,
|
||||
// xValues,
|
||||
// data!!,
|
||||
// true,
|
||||
// false,
|
||||
// )
|
||||
// } else {
|
||||
// ChartUtils.initBarChart(
|
||||
// barchart,
|
||||
// xValues,
|
||||
// data!!,
|
||||
// true,
|
||||
// )
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
fun showLog(list: Any){
|
||||
var json = ToolUtil.getJson(list)
|
||||
Log.i("我的设备数据==", json!!)
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.iv_back -> {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,394 @@
|
||||
package com.qidian.zhongkesmart.activity;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.os.CountDownTimer;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.blankj.utilcode.util.NetworkUtils;
|
||||
import com.blankj.utilcode.util.SPStaticUtils;
|
||||
import com.blankj.utilcode.util.ToastUtils;
|
||||
import com.qidian.zhongkesmart.R;
|
||||
import com.qidian.zhongkesmart.activity.adapter.RecentUserAdapter;
|
||||
import com.qidian.zhongkesmart.config.EventCode;
|
||||
import com.qidian.zhongkesmart.model.CallServiceManager;
|
||||
import com.qidian.zhongkesmart.model.LoginServiceManager;
|
||||
import com.qidian.zhongkesmart.model.ProfileManager;
|
||||
import com.qidian.zhongkesmart.model.UserCacheManager;
|
||||
import com.qidian.zhongkesmart.model.UserModel;
|
||||
import com.qidian.zhongkesmart.model.base.BaseService;
|
||||
import com.qidian.zhongkesmart.utils.EventBusUtil;
|
||||
import com.qidian.zhongkesmart.views.VerifyCodeView;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class SelectCallUserActivity extends AppCompatActivity implements View.OnClickListener {
|
||||
private static final String TAG = SelectCallUserActivity.class.getSimpleName();
|
||||
@BindView(R.id.tv_base_title)
|
||||
TextView tvBaseTitle;
|
||||
@BindView(R.id.edt_phone_number)
|
||||
EditText edtPhoneNumber;
|
||||
@BindView(R.id.tv_self_number)
|
||||
TextView tvSelfNumber;
|
||||
@BindView(R.id.tv_empty)
|
||||
TextView tvEmpty;
|
||||
@BindView(R.id.rv_search_result)
|
||||
RecyclerView rvSearchResult;
|
||||
@BindView(R.id.tv_recently_search)
|
||||
TextView tvRecentlySearch;
|
||||
@BindView(R.id.rv_recent_user)
|
||||
RecyclerView rvRecentUser;
|
||||
@BindView(R.id.iv_clear)
|
||||
ImageView ivClear;
|
||||
@BindView(R.id.rl_base_title)
|
||||
RelativeLayout rlBaseTitle;
|
||||
@BindView(R.id.rl_back)
|
||||
RelativeLayout rlBack;
|
||||
@BindView(R.id.btn_search)
|
||||
Button btnSearch;
|
||||
|
||||
private final String UserPhoneId = "UserPhoneId";
|
||||
private static final int PHONE_NUMBER_MAX_LENGTH = 11;
|
||||
private static final int SMS_CODE_LENGTH = 4;
|
||||
private static final int THOUSAND_MS = 1000;
|
||||
private static final int SIXTY_THOUSAND_MS = 60000;
|
||||
private CountDownTimer countDownTimer;
|
||||
|
||||
private RecentUserAdapter userAdapter;
|
||||
private RecentUserAdapter searchAdapter;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_select_call_user);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
initView();
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
rlBack = findViewById(R.id.rl_back);
|
||||
rlBack.setOnClickListener(this);
|
||||
btnSearch = findViewById(R.id.btn_search);
|
||||
btnSearch.setOnClickListener(this);
|
||||
tvBaseTitle = findViewById(R.id.tv_base_title);
|
||||
edtPhoneNumber = findViewById(R.id.edt_phone_number);
|
||||
tvSelfNumber = findViewById(R.id.tv_self_number);
|
||||
tvEmpty = findViewById(R.id.tv_empty);
|
||||
rvSearchResult = findViewById(R.id.rv_search_result);
|
||||
rlBaseTitle = findViewById(R.id.rl_base_title);
|
||||
ivClear = findViewById(R.id.iv_clear);
|
||||
ivClear.setOnClickListener(this);
|
||||
rvRecentUser = findViewById(R.id.rv_recent_user);
|
||||
tvRecentlySearch = findViewById(R.id.tv_recently_search);
|
||||
rlBaseTitle.setVisibility(View.VISIBLE);
|
||||
tvBaseTitle.setText("语音通话");
|
||||
edtPhoneNumber.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (!TextUtils.isEmpty(editable)) {
|
||||
ivClear.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
ivClear.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rvRecentUser.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true));
|
||||
|
||||
rvSearchResult = findViewById(R.id.rv_search_result);
|
||||
rvSearchResult.setLayoutManager(new LinearLayoutManager(this));
|
||||
searchAdapter = new RecentUserAdapter(this);
|
||||
rvSearchResult.setAdapter(searchAdapter);
|
||||
|
||||
if (TextUtils.isEmpty(SPStaticUtils.getString("UserPhoneId"))) {
|
||||
showInputPhoneDialog();
|
||||
} else {
|
||||
initData();
|
||||
}
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
UserModel currentUser = ProfileManager.getInstance().getUserModel();
|
||||
tvSelfNumber.setText(String.format(getString(R.string.your_phone_number_is), currentUser.mobile));
|
||||
|
||||
UserCacheManager.getInstance().getLastSearchUser(users -> runOnUiThread(() -> {
|
||||
if (userAdapter == null) {
|
||||
userAdapter = new RecentUserAdapter(SelectCallUserActivity.this);
|
||||
}
|
||||
rvRecentUser.setAdapter(userAdapter);
|
||||
userAdapter.updateUsers(users);
|
||||
if (users != null && !users.isEmpty()) {
|
||||
tvRecentlySearch.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
EventBusUtil.sendEvent(new EventBusUtil.MessageEvent(EventCode.FINISH_CALL_VIDEO));
|
||||
}
|
||||
|
||||
private void showInputPhoneDialog() {
|
||||
View root = View.inflate(this, R.layout.pop_input_phone_id, null);
|
||||
@SuppressLint("RestrictedApi")
|
||||
AlertDialog alert = new AlertDialog.Builder(this, R.style.transparentDialogDark)
|
||||
.setView(root, 0, 0, 0, 0)
|
||||
.setCancelable(false).create();
|
||||
|
||||
LinearLayout llClose = root.findViewById(R.id.li_close);
|
||||
llClose.setOnClickListener(view -> {
|
||||
finish();
|
||||
});
|
||||
|
||||
EditText mEdtPhoneNumber = root.findViewById(R.id.edt_phone_number);
|
||||
|
||||
TextView tvS = root.findViewById(R.id.tv_pop_sure);
|
||||
tvS.setOnClickListener(view -> {
|
||||
String phoneNumber = mEdtPhoneNumber.getText().toString().trim();
|
||||
if (!TextUtils.isEmpty(phoneNumber)) {
|
||||
if (phoneNumber.length() < PHONE_NUMBER_MAX_LENGTH) {
|
||||
ToastUtils.showShort(R.string.login_phone_number_cant_less_than_eleven);
|
||||
return;
|
||||
}
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
ToastUtils.showShort(R.string.network_connect_error_please_try_again);
|
||||
return;
|
||||
}
|
||||
LoginServiceManager.getInstance().sendMessage(phoneNumber, new BaseService.ResponseCallBack<Void>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void response) {
|
||||
showVerifyCodeDialog(phoneNumber);
|
||||
alert.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code) {
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ToastUtils.showShort(R.string.login_phone_number_cant_null);
|
||||
}
|
||||
// alert.dismiss();
|
||||
// showVerifyCodeDialog("18810640267");
|
||||
});
|
||||
|
||||
|
||||
alert.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
Window window = alert.getWindow();
|
||||
window.setGravity(Gravity.CENTER);
|
||||
|
||||
if (!SelectCallUserActivity.this.isFinishing())
|
||||
alert.show();
|
||||
}
|
||||
|
||||
private void showVerifyCodeDialog(String phoneNumber) {
|
||||
View root = View.inflate(this, R.layout.pop_verify_phone_code, null);
|
||||
@SuppressLint("RestrictedApi")
|
||||
AlertDialog alert = new AlertDialog.Builder(this, R.style.transparentDialogDark)
|
||||
.setView(root, 0, 0, 0, 0)
|
||||
.setCancelable(false).create();
|
||||
|
||||
LinearLayout llClose = root.findViewById(R.id.li_close);
|
||||
llClose.setOnClickListener(view -> {
|
||||
finish();
|
||||
});
|
||||
|
||||
VerifyCodeView verifyCodeView;//验证码输入框
|
||||
TextView tvMsmComment;
|
||||
TextView tvTimeCountDown;
|
||||
TextView tvResendMsm;
|
||||
|
||||
verifyCodeView = root.findViewById(R.id.vcv_sms);
|
||||
tvMsmComment = root.findViewById(R.id.tv_msm_comment);
|
||||
tvTimeCountDown = root.findViewById(R.id.tv_time_discount);
|
||||
tvResendMsm = root.findViewById(R.id.tv_resend_msm);
|
||||
|
||||
tvMsmComment.setText(getString(R.string.login_sms_code_has_been_sent) + phoneNumber + getString(R.string.login_please_input_sms_code));
|
||||
|
||||
tvTimeCountDown.setText(R.string.sixty_second);
|
||||
tvResendMsm.setVisibility(View.VISIBLE);
|
||||
tvTimeCountDown.setEnabled(false);
|
||||
|
||||
countDownTimer = new CountDownTimer(SIXTY_THOUSAND_MS, THOUSAND_MS) {
|
||||
@Override
|
||||
public void onTick(long l) {
|
||||
tvTimeCountDown.setText((l / THOUSAND_MS) + getString(R.string.login_second));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
tvTimeCountDown.setText(R.string.login_resend);
|
||||
tvTimeCountDown.setEnabled(true);
|
||||
tvResendMsm.setVisibility(View.GONE);
|
||||
}
|
||||
};
|
||||
countDownTimer.start();
|
||||
|
||||
tvTimeCountDown.setOnClickListener(v -> {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
ToastUtils.showShort(R.string.network_connect_error_please_try_again);
|
||||
return;
|
||||
}
|
||||
if (!TextUtils.isEmpty(phoneNumber)) {
|
||||
LoginServiceManager.getInstance().sendMessage(phoneNumber, new BaseService.ResponseCallBack<Void>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void response) {
|
||||
ToastUtils.showLong(R.string.login_sms_code_send_success);
|
||||
tvTimeCountDown.setText(R.string.sixty_second);
|
||||
tvResendMsm.setVisibility(View.VISIBLE);
|
||||
tvTimeCountDown.setEnabled(false);
|
||||
|
||||
countDownTimer = new CountDownTimer(SIXTY_THOUSAND_MS, THOUSAND_MS) {
|
||||
@Override
|
||||
public void onTick(long l) {
|
||||
tvTimeCountDown.setText((l / THOUSAND_MS) + getString(R.string.login_second));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
tvTimeCountDown.setText(R.string.login_resend);
|
||||
tvTimeCountDown.setEnabled(true);
|
||||
tvResendMsm.setVisibility(View.GONE);
|
||||
}
|
||||
};
|
||||
|
||||
countDownTimer.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code) {
|
||||
ToastUtils.showLong(R.string.login_sms_code_send_fail);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
TextView tvS = root.findViewById(R.id.tv_pop_sure);
|
||||
tvS.setOnClickListener(view -> {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
ToastUtils.showShort(R.string.network_connect_error_please_try_again);
|
||||
return;
|
||||
}
|
||||
String smsCode = verifyCodeView.getResult();
|
||||
if (!TextUtils.isEmpty(smsCode) && smsCode.length() == SMS_CODE_LENGTH) {
|
||||
if (!TextUtils.isEmpty(phoneNumber) && !TextUtils.isEmpty(smsCode)) {
|
||||
LoginServiceManager.getInstance().loginWithSms(phoneNumber, smsCode, new BaseService.ResponseCallBack<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void response) {
|
||||
SPStaticUtils.put("UserPhoneId", phoneNumber);
|
||||
ToastUtils.showLong(R.string.login_success);
|
||||
alert.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code) {
|
||||
ToastUtils.showLong(R.string.login_fail);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ToastUtils.showShort(R.string.login_please_input_correct_sms_code);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
alert.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
Window window = alert.getWindow();
|
||||
window.setGravity(Gravity.CENTER);
|
||||
|
||||
if (!SelectCallUserActivity.this.isFinishing())
|
||||
alert.show();
|
||||
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
params.width = 580;
|
||||
window.setAttributes(params);
|
||||
}
|
||||
|
||||
@OnClick({R.id.rl_back, R.id.iv_clear, R.id.btn_search})
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.rl_back:
|
||||
onBackPressed();
|
||||
break;
|
||||
case R.id.iv_clear:
|
||||
edtPhoneNumber.setText("");
|
||||
break;
|
||||
case R.id.btn_search:
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(SelectCallUserActivity.this, R.string.nertc_no_network, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
String phoneNumber = edtPhoneNumber.getText().toString().trim();
|
||||
if (!TextUtils.isEmpty(phoneNumber)) {
|
||||
CallServiceManager.getInstance().searchUserWithPhoneNumber(phoneNumber, new BaseService.ResponseCallBack<UserModel>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(UserModel response) {
|
||||
hideKeyBoard();
|
||||
if (response != null) {
|
||||
tvEmpty.setVisibility(View.GONE);
|
||||
rvSearchResult.setVisibility(View.VISIBLE);
|
||||
if (searchAdapter != null) {
|
||||
searchAdapter.updateItem(response);
|
||||
}
|
||||
UserCacheManager.getInstance().addUser(response);
|
||||
} else {
|
||||
ToastUtils.showLong(R.string.nertc_cant_find_this_user);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void hideKeyBoard() {
|
||||
View view = getCurrentFocus();
|
||||
if (view != null) {
|
||||
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
|
||||
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,249 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
/*设置服务器*/
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.text.Editable
|
||||
import android.text.TextUtils
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.blankj.utilcode.util.ToastUtils
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.model.ActionInfo
|
||||
import com.qidian.zhongkesmart.model.DeviceInfo
|
||||
import com.qidian.zhongkesmart.model.GetCodeM
|
||||
import com.qidian.zhongkesmart.model.GetTokenM
|
||||
import com.qidian.zhongkesmart.net.*
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import kotlinx.android.synthetic.main.activity_service.*
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
|
||||
|
||||
class ServiceActivity : BaseActivity(),EasyPermissions.PermissionCallbacks {
|
||||
var ishaveContent = false
|
||||
var mCode = ""
|
||||
var mToken = ""
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_service
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
ced_server_location!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
count: Int,
|
||||
after: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
if (s!!.isNotEmpty()) {
|
||||
// InputLimitUtil.ShowEdittextStyle(ced_server_location!!, tv_woprn_01!!, "")
|
||||
ced_server_location.setHintTextColor(Color.parseColor("#ffff3737"))
|
||||
}
|
||||
changeNextPic()
|
||||
}
|
||||
|
||||
})
|
||||
ced_server_portnumber!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
count: Int,
|
||||
after: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
if (s!!.isNotEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle2(ced_server_portnumber!!, tv_woprn_02!!, "")
|
||||
}
|
||||
changeNextPic()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
//测试默认值
|
||||
ced_server_location.setText("https://ifhs.fedhealth.cn/")
|
||||
ced_server_location.hint="请输入服务器地址,例如:https://ifhs.fedhealth.cn/"
|
||||
ced_server_portnumber.hint="请输入端口号,例如:15900"
|
||||
|
||||
askPermissionOfBluetooth()
|
||||
}
|
||||
|
||||
/*判断是否都为空 端口号可为空*/
|
||||
fun changeNextPic() {
|
||||
ishaveContent =
|
||||
ced_server_location.text!!.isNotEmpty() /*&& ced_server_portnumber.text!!.isNotEmpty()*/
|
||||
if (ishaveContent) {
|
||||
imv_service_jump.setBackgroundResource(R.drawable.shape_wifi_psw_join_bg)
|
||||
imv_service_jump.setTextColor(Color.parseColor("#ffffffff"))
|
||||
imv_service_jump.isEnabled = true
|
||||
} else {
|
||||
imv_service_jump.setBackgroundResource(R.drawable.shape_wifi_psw_join_gray_bg)
|
||||
imv_service_jump.setTextColor(Color.parseColor("#ff333333"))
|
||||
imv_service_jump.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.imv_service_jump -> {
|
||||
if (ced_server_location.text!!.isEmpty() /*|| ced_server_portnumber.text!!.isEmpty()*/) {
|
||||
if (ced_server_location.text!!.isEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle(
|
||||
ced_server_location,
|
||||
tv_woprn_01,
|
||||
"请输入服务器地址"
|
||||
)
|
||||
}
|
||||
/*if (ced_server_portnumber.text!!.isEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle2(
|
||||
ced_server_portnumber,
|
||||
tv_woprn_02,
|
||||
"请输入端口号"
|
||||
)
|
||||
}*/
|
||||
return
|
||||
}
|
||||
ApiUrl.setDomain(ToolUtil.getIpStr(ced_server_location.text!!.toString(),ced_server_portnumber.text!!.toString()))
|
||||
Log.i("OkGo", ApiUrl.domain)
|
||||
getHttpCode()
|
||||
// getHttpLogin()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 网关登录
|
||||
*/
|
||||
//获取code
|
||||
fun getHttpCode() {
|
||||
Log.i("UUID==", DeviceUuidFactory.getAndroidID(this))
|
||||
var map = HashMap<String, String>()
|
||||
map["id"] = DeviceUuidFactory.getAndroidID(this)
|
||||
HttpRequest.init(this).get(ApiUrl.getCode)
|
||||
.setMap(map)
|
||||
.excute(object : HttpCallBack() {
|
||||
override fun success(message: String?, `object`: Any?) {
|
||||
Log.e("响应数据", message!!)
|
||||
mCode = `object`.toString()
|
||||
getHttpLogin()
|
||||
}
|
||||
|
||||
override fun failed(code: String?, info: String?): Boolean {
|
||||
ToastUtils.make().setBgColor(getColor(R.color.color_E1132C)).setTextColor(getColor(R.color.white)).setDurationIsLong(true).show("无法连接服务器")
|
||||
Handler().postDelayed({getHttpCode()},120*1000)
|
||||
return super.failed(code, info)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
//网关登录 获取token存本地 这里如果绑定了就有token 不绑定就没有token 不影响后面测试网关是否连接成功
|
||||
fun getHttpLogin() {
|
||||
var map = HashMap<String?, String?>()
|
||||
map["code"] = mCode
|
||||
map["id"] = DeviceUuidFactory.getAndroidID(this)
|
||||
HttpRequest.init(this).postJson(ApiUrl.getLogin, map,"",false)
|
||||
.setClazz(GetTokenM::class.java)
|
||||
.excute(object : HttpCallBack() {
|
||||
override fun success(message: String?, `object`: Any?) {
|
||||
var model = `object` as GetTokenM
|
||||
mToken = model.token
|
||||
DataServer.mHttpToken = mToken
|
||||
}
|
||||
|
||||
override fun after() {
|
||||
super.after()
|
||||
getLoginSuccess()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//测试网关是否连接成功
|
||||
fun getLoginSuccess() {
|
||||
HttpRequest.init(this).get(ApiUrl.getLoginSuccess)
|
||||
.setClazz(GetCodeM::class.java)
|
||||
.excute(object : HttpCallBack() {
|
||||
override fun success(message: String?, `object`: Any?) {
|
||||
Log.e("响应数据", message!!)
|
||||
// var ddList = ObjectBoxUtils.getAllData(DeviceInfo::class.java)
|
||||
// var dList = ObjectBoxUtils.getAllData(ActionInfo::class.java)
|
||||
// Log.e("BlueTooth", "device:"+ddList!!.size.toString()+" action:"+dList!!.size.toString())
|
||||
//// ObjectBoxUtils.deleteALLData(ActionInfo::class.java)
|
||||
//// ObjectBoxUtils.deleteALLDataD(ObjectBoxUtils.getDeviceByMac("C7:3D:41:CB:A8:36"))
|
||||
//// ObjectBoxUtils.deleteALLDataA(ObjectBoxUtils.getActionByMac("C7:3D:41:CB:A8:36"))
|
||||
// var mode = SPUtil.getValue(DataServer.MConnectMode,Integer::class.java)
|
||||
// if(mode!=null&&mode.toInt()!=0) {
|
||||
//// ObjectBoxUtils.deleteDatabase()
|
||||
//// ToolUtil.clearHistory(this@ServiceActivity, DataServer.mBindHistory)
|
||||
//// SPUtil.setValue(DataServer.MConnectMode, 2)
|
||||
//// SPUtil.setValue(DataServer.MRelayMac,"")
|
||||
//// DataServer.connectMode =1
|
||||
//// //设置连接的贴件
|
||||
//// DataServer.nBlueToothMac = "C5:76:AB:D0:3B:D5"
|
||||
//// startActivity(Intent(this@ServiceActivity, HomeActivity::class.java))
|
||||
//// startActivity(Intent(this@ServiceActivity, ModelInitActivity::class.java).putExtra("mac", "D5:3B:D0:AB:76:C5"))
|
||||
// if(mode.toInt()==2) {
|
||||
// DataServer.connectMode = 2
|
||||
// var relayMac = SPUtil.getValue(DataServer.MRelayMac,String::class.java)
|
||||
// if(relayMac!=null&&!TextUtils.isEmpty(relayMac)) {
|
||||
// startActivity(Intent(this@ServiceActivity, HomeActivity::class.java))
|
||||
// }else{
|
||||
// startActivity(Intent(this@ServiceActivity, ConnectModeActivity::class.java))
|
||||
// }
|
||||
// }else{
|
||||
// DataServer.connectMode = 1
|
||||
// startActivity(Intent(this@ServiceActivity, HomeActivity::class.java))
|
||||
// }
|
||||
// }else{
|
||||
// DataServer.connectMode = 0
|
||||
// startActivity(Intent(this@ServiceActivity, ConnectModeActivity::class.java))
|
||||
// }
|
||||
finish()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取蓝牙权限
|
||||
*/
|
||||
private fun askPermissionOfBluetooth() {
|
||||
EasyPermissions.requestPermissions(
|
||||
this,
|
||||
"请允许获取您的位置权限",
|
||||
DataServer.ACCESS_BlueTooth_CODE,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
)
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_BlueTooth_CODE) {
|
||||
ToastUtil.showToast("蓝牙权限获取失败,APP功能不可用!")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.qidian.baseble.ble.BluetoothDeviceManager
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.dialog.SelectFrequencyDialog
|
||||
import com.qidian.zhongkesmart.dialog.SetLockDialog
|
||||
import com.qidian.zhongkesmart.utils.EditUtil
|
||||
import com.qidian.zhongkesmart.utils.ToastUtil
|
||||
import com.tuo.customview.VerificationCodeView
|
||||
import kotlinx.android.synthetic.main.activity_set_lock.*
|
||||
|
||||
/*设置解锁页面*/
|
||||
class SetLockActivity : BaseActivity() {
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_set_lock
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
// icv_1.setInputCompleteListener(object : VerificationCodeView.InputCompleteListener {
|
||||
// override fun inputComplete() {
|
||||
// Log.i("icv_input", icv_1.inputContent)
|
||||
// if(icv_1.inputContent.length==4){
|
||||
// if(icv_1.inputContent == "0000"){
|
||||
// //隐藏键盘
|
||||
// EditUtil.hideInput(this@SetLockActivity)
|
||||
// startActivity(Intent(this@SetLockActivity, SettingActivity::class.java))
|
||||
// finish()
|
||||
// }else{
|
||||
// ToastUtil.showToast("密码输入错误")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun deleteContent() {
|
||||
// }
|
||||
//
|
||||
// })
|
||||
iv_icv.setOnClickListener(View.OnClickListener {
|
||||
SetLockDialog.instance!!.getShareDialog(this,
|
||||
object : SetLockDialog.PopupYearWindowCallBack {
|
||||
override fun doWork() {
|
||||
startActivity(Intent(this@SetLockActivity, SettingActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
override fun isShowTitle(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.iv_back -> {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.fragments.SystemFragment
|
||||
import com.qidian.zhongkesmart.fragments.TieJianFragment
|
||||
import com.qidian.zhongkesmart.fragments.WangGuanFragment
|
||||
import com.qidian.zhongkesmart.utils.DataServer
|
||||
import kotlinx.android.synthetic.main.activity_set_seconed.*
|
||||
import kotlinx.android.synthetic.main.base_title_layout.*
|
||||
|
||||
class SetSeconedActivity : BaseActivity() {
|
||||
val tabTitles = arrayOf("贴件设置", "网关设置", "系统设置")
|
||||
var mJFragmentInstance: TieJianFragment? = null
|
||||
var mWGFragmentInstance: WangGuanFragment? = null
|
||||
var mSystemFragmentInstance: SystemFragment? = null
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_set_seconed
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
DataServer.SetPageTag=""
|
||||
setTitle("设置")
|
||||
val fragmentArray = ArrayList<Fragment>()
|
||||
mJFragmentInstance = TieJianFragment.newInstance()
|
||||
fragmentArray.add(mJFragmentInstance!!)
|
||||
mWGFragmentInstance = WangGuanFragment.newInstance()
|
||||
fragmentArray.add(mWGFragmentInstance!!)
|
||||
mSystemFragmentInstance = SystemFragment.newInstance()
|
||||
fragmentArray.add(mSystemFragmentInstance!!)
|
||||
tablayout.setViewPager(viewpager, tabTitles, this, fragmentArray)
|
||||
/**解决默认第一个没加粗问题**/
|
||||
tablayout.setCurrentTab(1)
|
||||
tablayout.setCurrentTab(0)
|
||||
viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
|
||||
override fun onPageScrolled(
|
||||
position: Int,
|
||||
positionOffset: Float,
|
||||
positionOffsetPixels: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
if (position == 2) {
|
||||
//证书信息
|
||||
// mQCFragmentInstance!!.showData(mCertificateList)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
resetBack()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* SetPageTag
|
||||
* 贴件设置:
|
||||
* 贴件列表 1-1
|
||||
* 贴件详情 1-2
|
||||
* 贴件修改 1-3
|
||||
*/
|
||||
//重写回退事件
|
||||
fun resetBack(){
|
||||
rl_back?.setOnClickListener {
|
||||
when(DataServer.SetPageTag){
|
||||
"1-1"->{
|
||||
onBackPressed()
|
||||
}
|
||||
"1-2"->{
|
||||
mJFragmentInstance!!.showTJListPage()
|
||||
}
|
||||
"1-3"->{
|
||||
mJFragmentInstance!!.showTJDetailsPage()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun isImmersion(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun isShowTitle(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,109 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.CountDownTimer
|
||||
import android.os.Handler
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.qidian.baseble.ble.BluetoothDeviceManager
|
||||
import com.qidian.baseble.ble.DeviceSettingEvent
|
||||
import com.qidian.baseble.utils.HexUtil
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.dialog.CancelSettingModeDialog
|
||||
import com.qidian.zhongkesmart.dialog.SelectFrequencyDialog
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import com.vise.xsnow.event.Subscribe
|
||||
import kotlinx.android.synthetic.main.activity_service.*
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class SettingModeActivity : BaseActivity() {
|
||||
override var TAG = SettingModeActivity::class.java.simpleName
|
||||
var mMac=""
|
||||
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_setting_mode
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
mMac=intent.getStringExtra("mac").toString()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
//获取模型学习时间
|
||||
BluetoothDeviceManager.getInstance().getTime(mMac,255)
|
||||
Handler().postDelayed({
|
||||
BluetoothDeviceManager.getInstance().getTime(mMac,253)
|
||||
},200)
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.tv_frequency -> {
|
||||
var deviceInfo = ObjectBoxUtils.getDeviceByMac(mMac)!![0].frequency
|
||||
SelectFrequencyDialog.instance!!.getShareDialog(this,
|
||||
object : SelectFrequencyDialog.PopupYearWindowCallBack {
|
||||
override fun doWork(item: Int) {
|
||||
showDialog()
|
||||
//修改频率
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.setParam(mMac, true,1,item)
|
||||
}
|
||||
},deviceInfo)
|
||||
}
|
||||
|
||||
R.id.tv_model_init -> {
|
||||
startActivity(Intent(this@SettingModeActivity, ModelInitActivity::class.java).putExtra("mac", mMac))
|
||||
finish()
|
||||
}
|
||||
|
||||
R.id.tv_exit -> {
|
||||
CancelSettingModeDialog.instance!!.getShareDialog(this,
|
||||
object : CancelSettingModeDialog.PopupYearWindowCallBack {
|
||||
override fun doWork() {
|
||||
//广播版退出配置模式,手动断开连接
|
||||
if(DataServer.connectMode==1) {
|
||||
if (BluetoothDeviceManager.getInstance()
|
||||
.isConnected(DataServer.MDevice)
|
||||
) {
|
||||
BluetoothDeviceManager.getInstance()
|
||||
.disconnect(DataServer.MDevice)
|
||||
}
|
||||
}
|
||||
DataServer.nBlueToothVerifyMac = ""
|
||||
finish()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun showDeviceSettingData(event: DeviceSettingEvent?) {
|
||||
try {
|
||||
if (event?.data != null && event.mac != null&&event.flag!=null&&event.flag==4) {
|
||||
if(Utils.formatMac(event.mac, ":").equals(mMac)){
|
||||
when (HexUtil.byteToInt(event?.data[1])) {
|
||||
0 -> {
|
||||
when (HexUtil.byteToInt(event?.data[2])) {
|
||||
1 -> {
|
||||
dismissDialog()
|
||||
ToastUtil.showToast("频率设置成功")
|
||||
SelectFrequencyDialog.instance!!.setDismiss()
|
||||
Log.i(TAG, event.mac + "频率设置成功")
|
||||
}
|
||||
}
|
||||
}
|
||||
252 -> Log.i(TAG, event.mac + "设备忙碌")
|
||||
251 -> Log.i(TAG, event.mac + "保存参数失败")
|
||||
250 -> Log.i(TAG, event.mac + "算法模型学习失败")
|
||||
249 -> Log.i(TAG, event.mac + "指令无效")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: java.lang.Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,289 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.graphics.Color
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.RadioGroup
|
||||
import com.github.mikephil.charting.data.BarData
|
||||
import com.github.mikephil.charting.data.BarDataSet
|
||||
import com.github.mikephil.charting.data.BarEntry
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.model.DeviceInfo
|
||||
import com.qidian.zhongkesmart.model.LineViewData
|
||||
import com.qidian.zhongkesmart.model.TimeData
|
||||
import com.qidian.zhongkesmart.model.TimeDataWithTime
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import kotlinx.android.synthetic.main.activity_smart_analysis.*
|
||||
import kotlinx.android.synthetic.main.layout_barchart.*
|
||||
|
||||
/*智能分析*/
|
||||
class SmartAnalysisActivity : BaseActivity() {
|
||||
var xValues = ArrayList<String>()
|
||||
val values = ArrayList<BarEntry>()
|
||||
var data: BarData? = null
|
||||
var set: BarDataSet? = null
|
||||
var mTabs= arrayOf("今日","本周","本月","本年")
|
||||
var sleepMac = ""
|
||||
var sportMac = ""
|
||||
var mTodayData=ArrayList<TimeDataWithTime>()
|
||||
var mWeekData=ArrayList<TimeDataWithTime>()
|
||||
var mMonthData=ArrayList<TimeDataWithTime>()
|
||||
var mYearData=ArrayList<TimeDataWithTime>()
|
||||
var tapPositon = 0
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_smart_analysis
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
// setTitle("智能分析")
|
||||
tv_yaxis_title.text = "时长(小时)"
|
||||
// getData(0)
|
||||
getData()
|
||||
getBasicData(sleepMac)
|
||||
getBarData(sleepMac)
|
||||
//Tab
|
||||
mTabs.forEach {
|
||||
tablayout_type1.addTab(tablayout_type1.newTab().setText(it))
|
||||
}
|
||||
tablayout_type1.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabReselected(p0: TabLayout.Tab?) {
|
||||
}
|
||||
|
||||
override fun onTabUnselected(p0: TabLayout.Tab?) {
|
||||
}
|
||||
|
||||
override fun onTabSelected(p0: TabLayout.Tab?) {
|
||||
tapPositon = p0!!.position
|
||||
getViewData(tapPositon)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
radioGroup.setOnCheckedChangeListener(object : RadioGroup.OnCheckedChangeListener {
|
||||
override fun onCheckedChanged(group: RadioGroup?, checkedId: Int) {
|
||||
when (checkedId) {
|
||||
R.id.raiobutton_cgq -> {
|
||||
getBasicData(sleepMac)
|
||||
getBarData(sleepMac)
|
||||
}
|
||||
R.id.raiobutton_healthycondition -> {
|
||||
getBasicData(sportMac)
|
||||
getBarData(sportMac)
|
||||
}
|
||||
R.id.raiobutton_advice -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
fun getData(poi:Int) {
|
||||
xValues.clear()
|
||||
values.clear()
|
||||
when(poi){
|
||||
0 ->{
|
||||
for (i in 0..23) {
|
||||
//X轴显示
|
||||
xValues.add(if (i<10) "0${i}:00" else "${i}:00")
|
||||
//柱状图数据
|
||||
values.add(BarEntry(i * 1f, (1..20).random()*1f))
|
||||
}
|
||||
}
|
||||
1 ->{
|
||||
for (i in 0..6) {
|
||||
//X轴显示
|
||||
xValues.add("星期${i+1}")
|
||||
//柱状图数据
|
||||
values.add(BarEntry(i * 1f, (60..200).random()*1f))
|
||||
}
|
||||
}
|
||||
2 ->{
|
||||
for (i in 0..29) {
|
||||
//X轴显示
|
||||
xValues.add("${i+1}日")
|
||||
//柱状图数据
|
||||
values.add(BarEntry(i * 1f, (60..200).random()*1f))
|
||||
}
|
||||
}
|
||||
3 ->{
|
||||
for (i in 0..11) {
|
||||
//X轴显示
|
||||
xValues.add("${i+1}月")
|
||||
//柱状图数据
|
||||
values.add(BarEntry(i * 1f, (500..1000).random()*1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var set = BarDataSet(values, "")
|
||||
set!!.color = Color.parseColor("#516AFC")
|
||||
var data = BarData(set)
|
||||
//有数据时候传true 无数据时候传false
|
||||
if (values.size > 0) {
|
||||
ChartUtils.initBarChart(
|
||||
barchart,
|
||||
xValues,
|
||||
data!!,
|
||||
false,
|
||||
)
|
||||
} else {
|
||||
ChartUtils.initBarChart(
|
||||
barchart,
|
||||
xValues,
|
||||
data!!,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
override fun isShowTitle(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找贴件信息
|
||||
*/
|
||||
fun getData() {
|
||||
var list =ObjectBoxUtils.getAllData(DeviceInfo::class.java)
|
||||
if (list.isNullOrEmpty()) {
|
||||
sleepMac = ""
|
||||
sportMac = ""
|
||||
} else {
|
||||
list.forEach{
|
||||
if(it.name=="卧室"&&it.type=="窗帘"){
|
||||
sleepMac = it.mac
|
||||
}
|
||||
if(it.name=="客厅"&&it.type=="门"){
|
||||
sportMac = it.mac
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getBasicData(mMac:String){
|
||||
if(!mMac.isNullOrEmpty()) {
|
||||
var deviceInfo = ObjectBoxUtils.getDeviceByMac(mMac)!![0]
|
||||
//是否在线
|
||||
if (deviceInfo.isOnline) {
|
||||
tv_myequipment_status.text = "正常"
|
||||
tv_myequipment_mark.setBackgroundResource(R.drawable.ed_yuan0fba61)
|
||||
} else {
|
||||
tv_myequipment_status.text = "离线"
|
||||
tv_myequipment_mark.setBackgroundResource(R.drawable.ed_yuangray)
|
||||
}
|
||||
//电量
|
||||
if (deviceInfo.power == "") {
|
||||
tv_myequipment_power.text = "0%"
|
||||
} else {
|
||||
tv_myequipment_power.text =
|
||||
"${Integer.valueOf(deviceInfo.power, 10)}%"
|
||||
}
|
||||
}else{
|
||||
tv_myequipment_status.text = "离线"
|
||||
tv_myequipment_mark.setBackgroundResource(R.drawable.ed_yuangray)
|
||||
tv_myequipment_power.text = "0%"
|
||||
}
|
||||
}
|
||||
|
||||
fun getBarData(mMac: String){
|
||||
if(!mMac.isNullOrEmpty()) {
|
||||
mTodayData.clear()
|
||||
mWeekData.clear()
|
||||
mMonthData.clear()
|
||||
mYearData.clear()
|
||||
//查取图表信息
|
||||
var aList = Utils.refreshActionData(ObjectBoxUtils.getActionByMac(mMac))
|
||||
aList!!.forEach {
|
||||
if (TimeUtil.isInToday(it.openTime)) {
|
||||
mTodayData.add(it)
|
||||
showLog(mTodayData)
|
||||
}
|
||||
if (TimeUtil.isInWeek(it.openTime)) {
|
||||
mWeekData.add(it)
|
||||
showLog(mWeekData)
|
||||
}
|
||||
if (TimeUtil.isInMonth(it.openTime)) {
|
||||
mMonthData.add(it)
|
||||
showLog(mMonthData)
|
||||
}
|
||||
if (TimeUtil.isInYear(it.openTime)) {
|
||||
mYearData.add(it)
|
||||
showLog(mYearData)
|
||||
}
|
||||
}
|
||||
}
|
||||
getViewData(tapPositon)
|
||||
}
|
||||
fun getViewData(poi: Int) {
|
||||
xValues.clear()
|
||||
values.clear()
|
||||
//设置缩放比例
|
||||
barchart.zoom(0f, 1f, 0f, 0f)
|
||||
var list=ArrayList<LineViewData>()
|
||||
when(poi){
|
||||
0->{//今日
|
||||
list.addAll(TimeUtil.formatTodayDurationData(mTodayData))
|
||||
barchart.zoom(2f, 1f, 0f, 0f)
|
||||
}
|
||||
1->{//本周
|
||||
list.addAll(TimeUtil.formatWeekDurationData(mWeekData))
|
||||
barchart.zoom(0f, 0f, 0f, 0f)
|
||||
}
|
||||
2->{//本月
|
||||
list.addAll(TimeUtil.formatMonthDurationData(mMonthData))
|
||||
barchart.zoom(3f, 1f, 0f, 0f)
|
||||
}
|
||||
3->{//本年
|
||||
list.addAll(TimeUtil.formatYearDurationData(mYearData))
|
||||
barchart.zoom(0.05f, 1f, 0f, 0f)
|
||||
}
|
||||
}
|
||||
showLog(list)
|
||||
for(i in 0 until list.size){
|
||||
//X轴显示
|
||||
xValues.add(list[i].timeLocation)
|
||||
//柱状图数据
|
||||
values.add(BarEntry(i * 1f, (list[i].mSize).toFloat()))
|
||||
}
|
||||
|
||||
var set = BarDataSet(values, "")
|
||||
set!!.color = Color.parseColor("#516AFC")
|
||||
var data = BarData(set)
|
||||
data.barWidth = 0.5f
|
||||
//有数据时候传true 无数据时候传false
|
||||
if (values.size > 0) {
|
||||
ChartUtils.initBarChart(
|
||||
barchart,
|
||||
xValues,
|
||||
data!!,
|
||||
false,
|
||||
)
|
||||
} else {
|
||||
ChartUtils.initBarChart(
|
||||
barchart,
|
||||
xValues,
|
||||
data!!,
|
||||
true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun showLog(list: Any){
|
||||
var json = ToolUtil.getJson(list)
|
||||
Log.i("我的设备数据==", json!!)
|
||||
}
|
||||
|
||||
fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.iv_back -> {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,236 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.amap.api.services.weather.LocalWeatherForecastResult
|
||||
import com.amap.api.services.weather.LocalWeatherLiveResult
|
||||
import com.amap.api.services.weather.WeatherSearch
|
||||
import com.amap.api.services.weather.WeatherSearchQuery
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.model.BindBlueToothData
|
||||
import com.qidian.zhongkesmart.model.FamilyInfo
|
||||
import com.qidian.zhongkesmart.model.GetCodeM
|
||||
import com.qidian.zhongkesmart.net.ApiUrl
|
||||
import com.qidian.zhongkesmart.net.HttpCallBack
|
||||
import com.qidian.zhongkesmart.net.HttpRequest
|
||||
import com.qidian.zhongkesmart.utils.DataServer
|
||||
import com.qidian.zhongkesmart.utils.TimeUtil
|
||||
import com.qidian.zhongkesmart.utils.ToastUtil
|
||||
import com.qidian.zhongkesmart.utils.ToolUtil
|
||||
import com.zhy.view.flowlayout.FlowLayout
|
||||
import com.zhy.view.flowlayout.TagAdapter
|
||||
import kotlinx.android.synthetic.main.layout_standby.*
|
||||
|
||||
|
||||
class StandByActivity : BaseActivity()/*, WeatherSearch.OnWeatherSearchListener */{
|
||||
var flowlayoutAdapter: TagAdapter<BindBlueToothData>? = null
|
||||
var mStansByList = ArrayList<BindBlueToothData>()
|
||||
var drawable01: AnimationDrawable? = null
|
||||
var drawable02: AnimationDrawable? = null
|
||||
var showWinkAnnimationTime = 0
|
||||
var imv_stansby: ImageView? = null
|
||||
|
||||
var getTimeNum = 0
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_stand_by
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
DataServer.standByPageIsShow = true
|
||||
handler.sendEmptyMessageDelayed(0, 1000)
|
||||
li_santdby.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
tv_standby_time.text = TimeUtil.getNowTimeHourMinute()
|
||||
tv_standby_timelong.text =
|
||||
"${TimeUtil.getNowTimeMonthDayFormat()} ${TimeUtil.getWeekDay(System.currentTimeMillis())}";
|
||||
tv_standby_weather.text=DataServer.mWeatherData
|
||||
|
||||
tv_go_setting.setOnClickListener{
|
||||
startActivity(Intent(this, SetLockActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
getFamilyInfo()
|
||||
showStandByPage()
|
||||
}
|
||||
|
||||
fun showStandByPage() {
|
||||
mStansByList.clear()
|
||||
mStansByList.addAll(ToolUtil.getHistory(DataServer.mBindHistory, this))
|
||||
flowlayoutAdapter = object : TagAdapter<BindBlueToothData>(mStansByList) {
|
||||
override fun getView(parent: FlowLayout?, position: Int, s: BindBlueToothData): View? {
|
||||
val view: View = LayoutInflater.from(this@StandByActivity).inflate(
|
||||
R.layout.item_standby, null
|
||||
)
|
||||
imv_stansby = view.findViewById<ImageView>(R.id.imv_stansby)
|
||||
var tv_stansby = view.findViewById<TextView>(R.id.tv_stansby)
|
||||
var tv_mark = view.findViewById<TextView>(R.id.tv_mark)
|
||||
tv_stansby.text = s.type
|
||||
imv_stansby!!.setImageResource(ToolUtil.getDJPageImage(s.type))
|
||||
if (ToolUtil.getTJIsOnLineState(s.mac)) {
|
||||
tv_mark.setBackgroundResource(R.drawable.ed_yuan0fba61)
|
||||
} else {
|
||||
tv_mark.setBackgroundResource(R.drawable.ed_yuangray)
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
override fun setSelected(position: Int, s: BindBlueToothData): Boolean {
|
||||
return s == s
|
||||
}
|
||||
}
|
||||
id_flowlayout.adapter = flowlayoutAdapter
|
||||
id_flowlayout.setOnTagClickListener { view, position, parent ->
|
||||
true
|
||||
}
|
||||
startStandByAnimation01()
|
||||
if (mStansByList.isEmpty()) {
|
||||
li_standby_background.visibility = View.GONE
|
||||
} else {
|
||||
li_standby_background.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
//先显示眨眼睛动画 30分钟后显示一次左右看
|
||||
fun startStandByAnimation01() {
|
||||
drawable01 = resources?.getDrawable(R.drawable.standbyanimation01) as AnimationDrawable
|
||||
// 放入imageView
|
||||
imv_standby!!.setBackgroundDrawable(drawable01)
|
||||
// 开始
|
||||
drawable01!!.start()
|
||||
showWinkAnnimationTime = 0
|
||||
}
|
||||
|
||||
@SuppressLint("HandlerLeak")
|
||||
var handler: Handler = object : Handler() {
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
this.removeMessages(0)
|
||||
sendEmptyMessageDelayed(0, 1000)
|
||||
getTime()
|
||||
Log.i("Handle==", "ing")
|
||||
aboutWindAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
fun getTime() {
|
||||
getTimeNum++
|
||||
if (getTimeNum == 30) {
|
||||
tv_standby_time.text = TimeUtil.getNowTimeHourMinute()
|
||||
tv_standby_timelong.text =
|
||||
"${TimeUtil.getNowTimeMonthDayFormat()} ${TimeUtil.getWeekDay(System.currentTimeMillis())}";
|
||||
getTimeNum = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun aboutWindAnimation() {
|
||||
showWinkAnnimationTime++
|
||||
if (showWinkAnnimationTime * 1000 == DataServer.mShowWinkAnnimationTimeBZ) {
|
||||
showWinkAnnimationTime = 0
|
||||
startStandByAnimation02()
|
||||
}
|
||||
}
|
||||
|
||||
//30分钟后显示一次左右看
|
||||
fun startStandByAnimation02() {
|
||||
drawable02 = resources?.getDrawable(R.drawable.standbyanimation02) as AnimationDrawable
|
||||
// 放入imageView
|
||||
imv_standby!!.setBackgroundDrawable(drawable02)
|
||||
// 开始
|
||||
drawable02!!.start()
|
||||
}
|
||||
|
||||
override fun isImmersion(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
//停止动画
|
||||
if (drawable01 != null && drawable01!!.isRunning) {
|
||||
drawable01?.stop()
|
||||
}
|
||||
//停止动画
|
||||
if (drawable02 != null && drawable02!!.isRunning) {
|
||||
drawable02?.stop()
|
||||
}
|
||||
//结束定时线程
|
||||
if (handler.hasMessages(0)) {
|
||||
handler.removeMessages(0)
|
||||
}
|
||||
DataServer.standByPageIsShow = false
|
||||
}
|
||||
|
||||
fun getFamilyInfo(){
|
||||
HttpRequest.init(this).get(ApiUrl.getFamilyInfo)
|
||||
.setClazz(FamilyInfo::class.java)
|
||||
.setAuthHeaders()
|
||||
.excute(object : HttpCallBack() {
|
||||
override fun success(message: String?, `object`: Any?) {
|
||||
var familyInfo = `object` as FamilyInfo
|
||||
tv_family_name.text = familyInfo.familyName
|
||||
}
|
||||
|
||||
override fun failed(code: String?, info: String?): Boolean {
|
||||
ToastUtil.showToast("$code $info")
|
||||
return super.failed(code, info)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 高德
|
||||
* 获取天气
|
||||
*/
|
||||
/* var mquery: WeatherSearchQuery? = null
|
||||
var mweathersearch: WeatherSearch? = null
|
||||
fun getWeatherData() {
|
||||
//检索参数为城市和天气类型,实况天气为WEATHER_TYPE_LIVE、天气预报为WEATHER_TYPE_FORECAST
|
||||
//检索参数为城市和天气类型,实况天气为WEATHER_TYPE_LIVE、天气预报为WEATHER_TYPE_FORECAST
|
||||
mquery = WeatherSearchQuery("北京", WeatherSearchQuery.WEATHER_TYPE_LIVE)
|
||||
mweathersearch = WeatherSearch(this)
|
||||
mweathersearch!!.setOnWeatherSearchListener(this)
|
||||
mweathersearch!!.query = mquery
|
||||
mweathersearch!!.searchWeatherAsyn() //异步搜索
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onWeatherLiveSearched(weatherLiveResult: LocalWeatherLiveResult?, rCode: Int) {
|
||||
if (rCode == 1000) {
|
||||
if (weatherLiveResult != null && weatherLiveResult.getLiveResult() != null) {
|
||||
var weatherlive = weatherLiveResult.getLiveResult();
|
||||
// reporttime1.setText(weatherlive.getReportTime()+"发布");
|
||||
// weather.setText(weatherlive.getWeather());
|
||||
// Temperature.setText(weatherlive.getTemperature()+"°");
|
||||
// wind.setText(weatherlive.getWindDirection()+"风 "+weatherlive.getWindPower()+"级");
|
||||
// humidity.setText("湿度 "+weatherlive.getHumidity()+"%");
|
||||
Log.i("天气预报==", weatherlive.getWeather())
|
||||
} else {
|
||||
Log.i("天气预报==", "暂无结果")
|
||||
}
|
||||
} else {
|
||||
Log.i("天气预报==", "查询失败${rCode}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWeatherForecastSearched(p0: LocalWeatherForecastResult?, p1: Int) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
@ -0,0 +1,254 @@
|
||||
package com.qidian.zhongkesmart.activity
|
||||
/*设置Wifi页面*/
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Uri
|
||||
import android.net.wifi.ScanResult
|
||||
import android.net.wifi.WifiManager
|
||||
import android.provider.Settings
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.qidian.zhongkesmart.MainActivity
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.base.BaseActivity
|
||||
import com.qidian.zhongkesmart.config.EventCode
|
||||
import com.qidian.zhongkesmart.dialog.*
|
||||
import com.qidian.zhongkesmart.manager.BasicSettingManager
|
||||
import com.qidian.zhongkesmart.receiver.WifiReceiver
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import com.scwang.smartrefresh.layout.listener.OnRefreshListener
|
||||
import kotlinx.android.synthetic.main.activity_wi_fi.*
|
||||
import kotlinx.android.synthetic.main.empty_layout.*
|
||||
import kotlinx.android.synthetic.main.layout_list.*
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
import net.idik.lib.slimadapter.SlimInjector
|
||||
import net.idik.lib.slimadapter.viewinjector.IViewInjector
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
class WiFiActivity : BaseActivity(), EasyPermissions.PermissionCallbacks {
|
||||
var mData = ArrayList<ScanResult>()
|
||||
var wifiReceiver: WifiReceiver? = null
|
||||
//wifi状态 默认关闭 0 开启 1 连接 2
|
||||
var IsOpen = 0
|
||||
var isShowHome = false
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_wi_fi
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
//注册监听Wifi连接广播
|
||||
registerBroadcast()
|
||||
askPermissionOfWiFi()
|
||||
LoadUtils.setLinearLayoutManager(this, recycle_wifi, false)
|
||||
mAdapter =
|
||||
SlimAdapter.create()
|
||||
.register<ScanResult>(R.layout.item_wifi1, object : SlimInjector<ScanResult> {
|
||||
override fun onInject(
|
||||
data: ScanResult,
|
||||
injector: IViewInjector<out IViewInjector<*>>
|
||||
) {
|
||||
injector.text(R.id.tv_wifi_name, data.SSID)
|
||||
injector.clicked(R.id.li_wifi) {
|
||||
WifiPswDialog.instance!!.getShareDialog(this@WiFiActivity, data.SSID)
|
||||
}
|
||||
}
|
||||
})
|
||||
.attachTo(recycle_wifi)
|
||||
//初始化dialog
|
||||
OpenmWifiDialog.instance!!.getShareDialog(this,
|
||||
object : OpenmWifiDialog.PopupYearWindowCallBack {
|
||||
override fun doWork() {
|
||||
// WifiUtil.openWifiSetting(this@WiFiActivity)
|
||||
//4、采用弹窗方式 应用内操作wifi
|
||||
startActivityForResult(Intent(Settings.Panel.ACTION_WIFI), 0)
|
||||
}
|
||||
|
||||
override fun doCancel() {
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/*关于Wifi*/
|
||||
fun getWifiStatus() {
|
||||
if(WifiUtil.isWifiEnabled(this)){
|
||||
Log.i("WiFi==", "wifi连接:" + WifiUtil.getWifiName(this))
|
||||
IsOpen = 2
|
||||
li_nowchoose.visibility = View.VISIBLE
|
||||
tv_nowchoose_name.text=WifiUtil.getWifiName(this)
|
||||
}else{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取wifi权限
|
||||
*/
|
||||
private fun askPermissionOfWiFi() {
|
||||
EasyPermissions.requestPermissions(
|
||||
this,
|
||||
"请允许获取您的WiFi权限",
|
||||
DataServer.ACCESS_WiFi_CODE,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
Manifest.permission.CHANGE_WIFI_STATE,
|
||||
Manifest.permission.BLUETOOTH_SCAN,
|
||||
Manifest.permission.BLUETOOTH_CONNECT,
|
||||
Manifest.permission.BLUETOOTH_ADVERTISE,
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_WiFi_CODE) {
|
||||
//申请成功
|
||||
registerBroadcast()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == DataServer.ACCESS_WiFi_CODE) {
|
||||
ToastUtil.showToast("WiFi权限获取失败,APP功能不可用!")
|
||||
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
intent.data = Uri.fromParts("package", packageName, null)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册Wifi监听广播
|
||||
*/
|
||||
fun registerBroadcast() {
|
||||
wifiReceiver = WifiReceiver()
|
||||
val filter = IntentFilter()
|
||||
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
|
||||
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
|
||||
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
|
||||
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
|
||||
filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)
|
||||
this.registerReceiver(wifiReceiver, filter)
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun receiveEvent(event: EventBusUtil.MessageEvent) {
|
||||
super.receiveEvent(event)
|
||||
when (event.code) {
|
||||
EventCode.WIFI_CONFIRM_OPEN -> {
|
||||
Log.i("WiFi==", "wifi开关打开")
|
||||
OpenmWifiDialog.instance!!.setDismiss()
|
||||
IsOpen = 1
|
||||
showDialog()
|
||||
}
|
||||
EventCode.WIFI_CONFIRM_OFF -> {
|
||||
Log.i("WiFi==", "wifi开关关闭")
|
||||
li_nowchoose.visibility = View.GONE
|
||||
OpenmWifiDialog.instance!!.setShow()
|
||||
IsOpen = 0
|
||||
dimissDialog()
|
||||
}
|
||||
EventCode.WIFI_CONFIRM_CONNECT -> {
|
||||
Log.i("WiFi==", "wifi连接:" + event.data)
|
||||
IsOpen = 2
|
||||
li_nowchoose.visibility = View.VISIBLE
|
||||
tv_nowchoose_name.text=event.data.toString()
|
||||
WifiPswDialog.instance!!.setDismiss()
|
||||
if(!isShowHome) {
|
||||
isShowHome = true
|
||||
var mode = SPUtil.getValue(DataServer.MConnectMode,Integer::class.java)
|
||||
if(mode!=null&&mode.toInt()!=0) {
|
||||
if(mode.toInt()==2) {
|
||||
DataServer.connectMode = 2
|
||||
var relayMac = SPUtil.getValue(DataServer.MRelayMac,String::class.java)
|
||||
if(relayMac!=null&&!TextUtils.isEmpty(relayMac)) {
|
||||
startActivity(Intent(this@WiFiActivity, HomeActivity::class.java))
|
||||
}else{
|
||||
startActivity(Intent(this@WiFiActivity, ConnectModeActivity::class.java))
|
||||
}
|
||||
}else{
|
||||
DataServer.connectMode = 1
|
||||
startActivity(Intent(this@WiFiActivity, HomeActivity::class.java))
|
||||
}
|
||||
}else{
|
||||
DataServer.connectMode = 0
|
||||
startActivity(Intent(this@WiFiActivity, ConnectModeActivity::class.java))
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
//列表
|
||||
EventCode.WIFI_CONFIRM_DATA -> {
|
||||
dimissDialog()
|
||||
Log.i("WiFi==", "wifi连接:" + event.data)
|
||||
var model=event.data as List<ScanResult>
|
||||
showData(model)
|
||||
}
|
||||
//连接失败
|
||||
EventCode.WIFI_CONFIRM_FAIL-> {
|
||||
WifiPswDialog.instance!!.showFail()
|
||||
}
|
||||
}
|
||||
aboutViews()
|
||||
}
|
||||
|
||||
/*显示wifi列表*/
|
||||
fun showData(model:List<ScanResult>){
|
||||
mData.clear()
|
||||
// mData.addAll(model)
|
||||
model.forEach{
|
||||
if(it.SSID.isNotEmpty()){
|
||||
mData.add(it)
|
||||
}
|
||||
|
||||
}
|
||||
mAdapter!!.updateData(mData).notifyDataSetChanged()
|
||||
}
|
||||
|
||||
/*关于不同连接状态界面不同展示*/
|
||||
fun aboutViews() {
|
||||
when (IsOpen) {
|
||||
//关闭
|
||||
0 -> {
|
||||
recycle_wifi.visibility = View.GONE
|
||||
layEmpty.visibility = View.VISIBLE
|
||||
tv_emptytext.text = "您还未打开wifi或者附近暂无可用网络"
|
||||
tv_button.visibility = View.GONE
|
||||
}
|
||||
//开启
|
||||
1 -> {
|
||||
recycle_wifi.visibility = View.VISIBLE
|
||||
layEmpty.visibility = View.GONE
|
||||
}
|
||||
2 -> {
|
||||
recycle_wifi.visibility = View.VISIBLE
|
||||
layEmpty.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
unregisterReceiver(wifiReceiver)
|
||||
dimissDialog()
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun dimissDialog(){
|
||||
if (loadingDialog != null) loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
package com.qidian.zhongkesmart.activity.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.blankj.utilcode.util.NetworkUtils;
|
||||
import com.blankj.utilcode.util.ToastUtils;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.netease.nimlib.sdk.avsignalling.constant.ChannelType;
|
||||
import com.netease.yunxin.nertc.ui.CallKitUI;
|
||||
import com.netease.yunxin.nertc.ui.base.CallParam;
|
||||
import com.qidian.zhongkesmart.R;
|
||||
import com.qidian.zhongkesmart.config.EventCode;
|
||||
import com.qidian.zhongkesmart.model.ProfileManager;
|
||||
import com.qidian.zhongkesmart.model.UserModel;
|
||||
import com.qidian.zhongkesmart.utils.EventBusUtil;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class RecentUserAdapter extends RecyclerView.Adapter<RecentUserAdapter.ViewHolder> {
|
||||
|
||||
private final List<UserModel> mUsers = new ArrayList<>();
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
//创建ViewHolder
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public ImageView ivUser;
|
||||
public TextView tvNickname;
|
||||
public TextView tvCall;
|
||||
|
||||
public ViewHolder(View v) {
|
||||
super(v);
|
||||
ivUser = v.findViewById(R.id.iv_user);
|
||||
tvNickname = v.findViewById(R.id.tv_nickname);
|
||||
tvCall = v.findViewById(R.id.tv_call);
|
||||
}
|
||||
}
|
||||
|
||||
public RecentUserAdapter(Context context) {
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
public void updateUsers(List<UserModel> users) {
|
||||
if (users == null) {
|
||||
return;
|
||||
}
|
||||
this.mUsers.clear();
|
||||
mUsers.addAll(users);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void updateItem(UserModel user) {
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
this.mUsers.clear();
|
||||
mUsers.add(user);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
if (mUsers != null) {
|
||||
holder.tvNickname.setText(mUsers.get(position).mobile);
|
||||
Glide.with(mContext).load(mUsers.get(position).avatar).apply(RequestOptions.bitmapTransform(new RoundedCorners(7))).into(holder.ivUser);
|
||||
holder.itemView.setOnClickListener(view -> {
|
||||
UserModel currentUser = ProfileManager.getInstance().getUserModel();
|
||||
if (currentUser == null || TextUtils.isEmpty(currentUser.imAccid)) {
|
||||
Toast.makeText(mContext, "当前用户登录存在问题,请注销后重新登录", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
UserModel searchedUser = mUsers.get(position);
|
||||
if (currentUser.imAccid.equals(searchedUser.imAccid) || currentUser.mobile.equals(searchedUser.mobile)) {
|
||||
Toast.makeText(mContext, "不能呼叫自己!", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if (NetworkUtils.isConnected()) {
|
||||
// 自定义透传字段,被叫用户在收到呼叫邀请时通过参数进行解析
|
||||
JSONObject extraInfo = new JSONObject();
|
||||
|
||||
try {
|
||||
extraInfo.putOpt("key", "call");
|
||||
extraInfo.putOpt("value", "testValue");
|
||||
extraInfo.putOpt("userName", currentUser.mobile);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
EventBusUtil.sendEvent(new EventBusUtil.MessageEvent(EventCode.START_CALL_VIDEO));
|
||||
CallKitUI.startSingleCall(mContext,
|
||||
CallParam.createSingleCallParam(ChannelType.VIDEO.getValue(), currentUser.imAccid, searchedUser.imAccid, extraInfo.toString()));
|
||||
} else {
|
||||
ToastUtils.showShort(R.string.network_connect_error_please_try_again);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mUsers.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_item_layout, parent, false);
|
||||
return new ViewHolder(v);
|
||||
}
|
||||
}
|
||||
161
app/src/main/java/com/qidian/zhongkesmart/base/AppApplication.kt
Normal file
161
app/src/main/java/com/qidian/zhongkesmart/base/AppApplication.kt
Normal file
@ -0,0 +1,161 @@
|
||||
package com.qidian.zhongkesmart.base
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.os.Process
|
||||
import android.text.TextUtils
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.Log
|
||||
import com.netease.nimlib.sdk.NIMClient
|
||||
import com.netease.nimlib.sdk.SDKOptions
|
||||
import com.netease.nimlib.sdk.auth.LoginInfo
|
||||
import com.qidian.baseble.ViseBle
|
||||
import com.qidian.baseble.ble.BluetoothDeviceManager
|
||||
import com.qidian.zhongkesmart.BuildConfig
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.model.MyObjectBox
|
||||
import com.qidian.zhongkesmart.model.ProfileManager
|
||||
import com.qidian.zhongkesmart.model.UserModel
|
||||
import com.qidian.zhongkesmart.utils.BlueToothUtils
|
||||
import com.qidian.zxing.lib_zxing.activity.ZXingLibrary
|
||||
import com.qweather.sdk.view.HeConfig
|
||||
import com.scwang.smartrefresh.layout.SmartRefreshLayout
|
||||
import com.scwang.smartrefresh.layout.footer.ClassicsFooter
|
||||
import com.scwang.smartrefresh.layout.header.ClassicsHeader
|
||||
import com.tencent.bugly.crashreport.CrashReport
|
||||
import io.objectbox.BoxStore
|
||||
import io.objectbox.android.AndroidObjectBrowser
|
||||
import java.io.BufferedReader
|
||||
import java.io.FileReader
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
class AppApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
mContext = applicationContext
|
||||
initSmartRefreshLayout()
|
||||
//获取屏幕宽高
|
||||
val dm: DisplayMetrics = this.resources.displayMetrics
|
||||
widthPixels = dm.widthPixels
|
||||
heightPixels = dm.heightPixels
|
||||
|
||||
val context = applicationContext
|
||||
// 获取当前包名
|
||||
val packageName = context.packageName
|
||||
// 获取当前进程名
|
||||
val processName =
|
||||
getProcessName(Process.myPid())
|
||||
//二维码
|
||||
ZXingLibrary.initDisplayOpinion(this)
|
||||
//蓝牙
|
||||
// BluetoothContext.set(this)
|
||||
BlueToothUtils.instance!!.init(this)
|
||||
//蓝牙相关配置修改
|
||||
|
||||
|
||||
//蓝牙相关配置修改
|
||||
ViseBle.config()
|
||||
.setScanTimeout(12*1000) //扫描超时时间,-1设置为永久扫描
|
||||
.setScanRepeatInterval(7 * 1000) //扫描间隔5秒
|
||||
.setConnectTimeout(5 * 1000) //连接超时时间
|
||||
.setOperateTimeout(5 * 1000) //设置数据操作超时时间
|
||||
// 这个地方设置的无效了 具体在这个地方 DeviceMirror line 80
|
||||
.setConnectRetryCount(0) //设置连接失败重试次数
|
||||
.setConnectRetryInterval(1000) //设置连接失败重试间隔时间
|
||||
.setOperateRetryCount(0) //设置数据操作失败重试次数
|
||||
.setOperateRetryInterval(1000).maxConnectCount = 1 //设置最大连接设备数量
|
||||
|
||||
//蓝牙信息初始化,全局唯一,必须在应用初始化时调用
|
||||
//蓝牙信息初始化,全局唯一,必须在应用初始化时调用
|
||||
ViseBle.getInstance().init(this)
|
||||
BluetoothDeviceManager.getInstance().init(this)
|
||||
|
||||
//和风天气预报
|
||||
HeConfig.init("HE2208261412031552", "ab9f3f03140047d586a036e1b6fefaf0")
|
||||
//切换至开发版服务
|
||||
HeConfig.switchToDevService()
|
||||
|
||||
CrashReport.initCrashReport(getApplicationContext(), "836dfa24ad", false);
|
||||
|
||||
NIMClient.init(this, loginInfo(), options())
|
||||
|
||||
initObjectBox()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
var mContext: Context? = null
|
||||
var widthPixels = 0
|
||||
var heightPixels = 0
|
||||
//数据库
|
||||
var boxStore: BoxStore? = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新加载相关
|
||||
*/
|
||||
private fun initSmartRefreshLayout() {
|
||||
SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, layout ->
|
||||
// layout.setPrimaryColorsId(R.color.white, R.color.black)//全局设置主题颜色
|
||||
layout.setPrimaryColorsId(R.color.tran, R.color.gray1);//全局设置主题颜色
|
||||
ClassicsHeader(context)//指定为经典Header,默认是 贝塞尔雷达Header
|
||||
}
|
||||
SmartRefreshLayout.setDefaultRefreshFooterCreator { context, layout ->
|
||||
//指定为经典Footer,默认是 BallPulseFooter
|
||||
ClassicsFooter(context).setDrawableSize(20f)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getProcessName(pid: Int): String? {
|
||||
var reader: BufferedReader? = null
|
||||
try {
|
||||
reader = BufferedReader(FileReader("/proc/$pid/cmdline"))
|
||||
var processName: String = reader.readLine()
|
||||
if (!TextUtils.isEmpty(processName)) {
|
||||
processName = processName.trim { it <= ' ' }
|
||||
}
|
||||
return processName
|
||||
} catch (throwable: Throwable) {
|
||||
throwable.printStackTrace()
|
||||
} finally {
|
||||
try {
|
||||
if (reader != null) {
|
||||
reader.close()
|
||||
}
|
||||
} catch (exception: IOException) {
|
||||
exception.printStackTrace()
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// 如果返回值为 null,则全部使用默认参数。
|
||||
private fun options(): SDKOptions? {
|
||||
val options = SDKOptions()
|
||||
//此处仅设置appkey,其他设置请自行参看信令文档设置 :https://dev.yunxin.163.com/docs/product/信令/SDK开发集成/Android开发集成/初始化
|
||||
options.appKey = BuildConfig.APP_KEY
|
||||
return options
|
||||
}
|
||||
|
||||
// 如果已经存在用户登录信息,返回LoginInfo,否则返回null即可
|
||||
private fun loginInfo(): LoginInfo? {
|
||||
val userModel: UserModel? = ProfileManager.getInstance().getUserModel()
|
||||
return if (userModel != null && !TextUtils.isEmpty(userModel.imToken) && !TextUtils.isEmpty(userModel.imAccid)) {
|
||||
LoginInfo(java.lang.String.valueOf(userModel.imAccid), userModel.imToken)
|
||||
} else null
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据库
|
||||
*/
|
||||
private fun initObjectBox() {
|
||||
//MyObjectBox找不到,必须先创建一个对象,然后重新编译,才可以
|
||||
boxStore = MyObjectBox.builder().androidContext(this).build()
|
||||
// if (BuildConfig.DEBUG) {
|
||||
// // 开启一个浏览服务
|
||||
// val started = AndroidObjectBrowser(boxStore).start(this)
|
||||
// Log.i("ObjectBrowser", "Started: $started")
|
||||
// }
|
||||
}
|
||||
}
|
||||
242
app/src/main/java/com/qidian/zhongkesmart/base/BaseActivity.kt
Normal file
242
app/src/main/java/com/qidian/zhongkesmart/base/BaseActivity.kt
Normal file
@ -0,0 +1,242 @@
|
||||
package com.qidian.zhongkesmart.base
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.dialog.AlarmAnimationDialog
|
||||
import com.qidian.zhongkesmart.dialog.AlarmAnimationDialog2
|
||||
import com.qidian.zhongkesmart.receiver.WinCallback
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import com.vise.xsnow.event.BusManager
|
||||
import kotlinx.android.synthetic.main.activity_base.*
|
||||
import kotlinx.android.synthetic.main.base_title_layout.*
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
|
||||
abstract class BaseActivity : AppCompatActivity() {
|
||||
var mAdapter: SlimAdapter? = null
|
||||
val loadingDialog: Dialog by lazy { DialogUtil.loadingDialog(this) }
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
//activity压栈
|
||||
ActivityManager.getAppManager().addActivity(this)
|
||||
setContentView(R.layout.activity_base)
|
||||
//Eventbus
|
||||
EventBusUtil.register(this)
|
||||
|
||||
BusManager.getBus().register(this)
|
||||
val inflate = LayoutInflater.from(this).inflate(getLayoutId(), ll_content, false)
|
||||
ll_content.addView(inflate, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
layInit()
|
||||
initView()
|
||||
initData()
|
||||
initStatusBar()//设置状态栏
|
||||
// getUse()
|
||||
}
|
||||
|
||||
open fun layInit() {
|
||||
rl_back?.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置页面标题
|
||||
* @param title 标题
|
||||
*/
|
||||
fun setTitle(title: String) {
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
rl_base_title.visibility = View.VISIBLE
|
||||
tv_base_title.text = title
|
||||
} else {
|
||||
rl_base_title.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
//设置状态栏
|
||||
fun initStatusBar() {
|
||||
if (isImmersion()) {
|
||||
view_status_base.visibility = View.GONE
|
||||
setStatusBar(isDarkBar())
|
||||
} else {
|
||||
view_status_base.visibility = View.VISIBLE
|
||||
StatusBarUtil.setHeight(this, view_status_base)
|
||||
setStatusBar(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun setStatusBar(isDark: Boolean) {
|
||||
ImmersionBar.with(this).reset().statusBarDarkFont(isDark).init()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
if (isShowTitle()) {
|
||||
rl_base_title.visibility = View.VISIBLE
|
||||
} else {
|
||||
rl_base_title.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
//页面布局
|
||||
abstract fun getLayoutId(): Int
|
||||
|
||||
//view初始化
|
||||
abstract fun initView()
|
||||
|
||||
//数据初始化
|
||||
abstract fun initData()
|
||||
|
||||
/**
|
||||
* 沉浸式显示 不显示标头
|
||||
* 默认false ture为显示沉浸式
|
||||
*/
|
||||
open fun isImmersion(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 沉浸式显示 状态栏文字颜色
|
||||
* 默认ture 黑色 false为白色
|
||||
*/
|
||||
open fun isDarkBar(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 标题头是否显示
|
||||
* 默认true显示 false为不显示
|
||||
*/
|
||||
open fun isShowTitle(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
open fun onRightBtnClickListener() {}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
ActivityManager.getAppManager().finishActivity(this)
|
||||
EventBusUtil.unregister(this)
|
||||
BusManager.getBus().unregister(this)
|
||||
if (loadingDialog.isShowing) {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun showDialog() {
|
||||
if (loadingDialog != null && !loadingDialog.isShowing) {
|
||||
loadingDialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
fun dismissDialog() {
|
||||
if (loadingDialog != null && loadingDialog.isShowing) {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
//是否退出app
|
||||
protected open fun isExitApp(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
private var current_time: Long = 0
|
||||
override fun onBackPressed() {
|
||||
if (isExitApp()) {
|
||||
if (current_time > 0 && System.currentTimeMillis() - current_time <= 3000) {
|
||||
super.onBackPressed()
|
||||
} else {
|
||||
ToastUtil.showToast("再按一次退出")
|
||||
current_time = System.currentTimeMillis()
|
||||
}
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventBusCome(event: EventBusUtil.MessageEvent) {
|
||||
if (event != null) {
|
||||
receiveEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收到分发到事件 * * @param event 事件
|
||||
*/
|
||||
open fun receiveEvent(event: EventBusUtil.MessageEvent) {}
|
||||
|
||||
|
||||
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent?): Boolean {
|
||||
// Log.e(
|
||||
// "屏幕操作监听==",
|
||||
// "onTouchEvent: 屏幕被操作"
|
||||
// )
|
||||
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
|
||||
fun showBaseAlarmDialog(type: String?,mac:String) {
|
||||
if(!DataServer.isShowAlarmMac(mac)){
|
||||
AlarmAnimationDialog2.instance!!.getShareDialog(
|
||||
ActivityManager.getAppManager().currentActivity(),
|
||||
type,mac,
|
||||
object : AlarmAnimationDialog2.PopupYearWindowCallBack {
|
||||
override fun doWork() {
|
||||
//解除警报
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
open var TAG = "屏幕操作监听=="
|
||||
|
||||
//监听app是否被操作
|
||||
fun getUse() {
|
||||
val activity: Activity = ActivityManager.getAppManager().currentActivity() ?: return
|
||||
val win: Window = activity.getWindow()
|
||||
// Log.e(
|
||||
// TAG,
|
||||
// "touchOnclick: activity=$activity"
|
||||
// )
|
||||
win.callback = object : WinCallback(win.callback) {
|
||||
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
|
||||
DataServer.ChangeFocusMark = 0
|
||||
// Log.e(
|
||||
// TAG,
|
||||
// "dispatchTouchEvent:activity窗口被触摸"
|
||||
//
|
||||
// )
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
DataServer.ChangeFocusMark = 0
|
||||
// Log.e(
|
||||
// TAG,
|
||||
// "dispatchTouchEvent:activity窗口被触摸"
|
||||
//
|
||||
// )
|
||||
}
|
||||
}
|
||||
return super.dispatchTouchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.qidian.zhongkesmart.bluetooth;
|
||||
|
||||
import com.qidian.zhongkesmart.base.AppApplication;
|
||||
|
||||
/**
|
||||
* Created by dingjikerbo on 2016/8/27.
|
||||
*/
|
||||
public class ClientManager {
|
||||
|
||||
/* private static BluetoothClient mClient;
|
||||
|
||||
public static BluetoothClient getClient() {
|
||||
if (mClient == null) {
|
||||
synchronized (ClientManager.class) {
|
||||
if (mClient == null) {
|
||||
mClient = new BluetoothClient(AppApplication.mContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mClient;
|
||||
}*/
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.qidian.zhongkesmart.bluetooth.dfu;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.qidian.zhongkesmart.config.Config;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import no.nordicsemi.android.dfu.DfuBaseService;
|
||||
|
||||
public class DfuService extends DfuBaseService {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Activity> getNotificationTarget() {
|
||||
/*
|
||||
* As a target activity the NotificationActivity is returned, not the MainActivity. This is because
|
||||
* the notification must create a new task:
|
||||
*
|
||||
* intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
*
|
||||
* when you press it. You can use NotificationActivity to check whether the new activity
|
||||
* is a root activity (that means no other activity was open earlier) or that some
|
||||
* other activity is already open. In the latter case the NotificationActivity will just be
|
||||
* closed. The system will restore the previous activity. However, if the application has been
|
||||
* closed during upload and you click the notification, a NotificationActivity will
|
||||
* be launched as a root activity. It will create and start the main activity and
|
||||
* terminate itself.
|
||||
*
|
||||
* This method may be used to restore the target activity in case the application
|
||||
* was closed or is open. It may also be used to recreate an activity history using
|
||||
* startActivities(...).
|
||||
*/
|
||||
return NotificationActivity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDebug() {
|
||||
// Here return true if you want the service to print more logs in LogCat.
|
||||
// Library's BuildConfig in current version of Android Studio is always set to DEBUG=false, so
|
||||
// make sure you return true or your.app.BuildConfig.DEBUG here.
|
||||
return Config.DebugMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateForegroundNotification(@NonNull final NotificationCompat.Builder builder) {
|
||||
// Customize the foreground service notification here.
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.qidian.zhongkesmart.bluetooth.dfu;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.qidian.zhongkesmart.activity.SettingActivity;
|
||||
|
||||
public class NotificationActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// If this activity is the root activity of the task, the app is not running
|
||||
if (isTaskRoot()) {
|
||||
// Start the app before finishing
|
||||
final Intent intent = new Intent(this, SettingActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtras(getIntent().getExtras()); // copy all extras
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
// Now finish, which will drop you to the activity at which you were at the top of the task stack
|
||||
finish();
|
||||
}
|
||||
}
|
||||
41
app/src/main/java/com/qidian/zhongkesmart/config/Config.java
Normal file
41
app/src/main/java/com/qidian/zhongkesmart/config/Config.java
Normal file
@ -0,0 +1,41 @@
|
||||
package com.qidian.zhongkesmart.config;
|
||||
|
||||
public class Config {
|
||||
|
||||
/**
|
||||
* 开发环境
|
||||
* 发布到 Market 时, 必须要将其置为false, 不显示log
|
||||
*/
|
||||
public static boolean DebugMode = true;
|
||||
|
||||
/**
|
||||
* 下载的安装包文件
|
||||
*/
|
||||
public static final String DOWNLOAD_APK= "smartspeaker.apk";
|
||||
|
||||
/**
|
||||
* 下载的代理固件
|
||||
*/
|
||||
public static final String DOWNLOAD_FIRMWARE_D= "firmware_d.zip";
|
||||
|
||||
/**
|
||||
* 下载的低功耗固件
|
||||
*/
|
||||
public static final String DOWNLOAD_FIRMWARE_L= "firmware_l.zip";
|
||||
|
||||
/**
|
||||
* downloadId保存本地
|
||||
*/
|
||||
public static final String DOWNLOAD_ID_STATUS= "DownloadIdStatus";
|
||||
|
||||
/**
|
||||
* 代理固件下载url
|
||||
*/
|
||||
public static final String DOWNLOAD_FIRMWARE_D_URL= "https://ifhs.fedhealth.cn/gate/SDK1702_d_1.0.4.zip";
|
||||
|
||||
/**
|
||||
* 低功耗固件下载url
|
||||
*/
|
||||
public static final String DOWNLOAD_FIRMWARE_L_URL= "https://ifhs.fedhealth.cn/gate/SDK1702_l_1.0.1.zip";
|
||||
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
package com.qidian.zhongkesmart.config;
|
||||
|
||||
public class EventCode {
|
||||
public final static int WIFI_CONFIRM_OFF = 0x0001;
|
||||
public final static int WIFI_CONFIRM_OPEN = 0x0002;
|
||||
public final static int WIFI_CONFIRM_CONNECT = 0x0003;
|
||||
public final static int WIFI_CONFIRM_DATA = 0x0004;
|
||||
public final static int WIFI_CONFIRM_FAIL = 0x0005;
|
||||
public final static int PERMISSION_ACCESS_COARSE_LOCATION = 0x0006;
|
||||
|
||||
//蓝牙
|
||||
public final static int BLUE_CONFIRM_SUCCESS = 0x0007;
|
||||
public final static int BLUE_CONFIRM_FAIL = 0x0008;
|
||||
public final static int BLUE_CONFIRM_DiSCONNECT = 0x0009;
|
||||
|
||||
/**
|
||||
* 数据推送节点
|
||||
*/
|
||||
//新增数据 1. 贴件新增数据时 * 位移型:新增数据 * 震动型:新增第一条数据
|
||||
public final static int PUSHDATA_NEWGET = 0x0010;
|
||||
//定时任务发现报警时发送一条数据
|
||||
public final static int PUSHDATA_TIMING_ALARM = 0x0011;
|
||||
//电量低 * 20%推送一次,10%推送一次
|
||||
public final static int PUSHDATA_LOW_POWER = 0x0012;
|
||||
//定时任务发现离线时推送一次数据
|
||||
public final static int PUSHDATA_OFFLINE = 0x0013;
|
||||
//蓝牙数据改变-开关、报警、正常离线
|
||||
public final static int BLUETOOTHDATA_Refresh = 0x0013;
|
||||
/**
|
||||
* 焦点变化标志
|
||||
*/
|
||||
public final static int FOCUS_CHANGE = 0x0014;
|
||||
|
||||
/**
|
||||
* 接受到BDBD数据,更新数据条数
|
||||
*/
|
||||
public final static int PUSHDATA_BDBD = 0x0015;
|
||||
|
||||
/**
|
||||
* 贴件唤醒成功,可以进入配置模式
|
||||
*/
|
||||
public final static int DEVICE_WAKE_UP_SUCCEED = 0x0016;
|
||||
|
||||
/**
|
||||
* 开始通话
|
||||
*/
|
||||
public final static int START_CALL_VIDEO = 0x0020;
|
||||
|
||||
/**
|
||||
* 结束通话
|
||||
*/
|
||||
public final static int FINISH_CALL_VIDEO = 0x0021;
|
||||
|
||||
/**
|
||||
* 开始下载
|
||||
*/
|
||||
public final static int DOWNLOAD_START = 0x0031;
|
||||
|
||||
/**
|
||||
* 下载完成
|
||||
*/
|
||||
public final static int DOWNLOAD_FINISH = 0x0032;
|
||||
|
||||
/**
|
||||
* 下载出错
|
||||
*/
|
||||
public final static int DOWNLOAD_ERROR = 0x0033;
|
||||
|
||||
/**
|
||||
* 下载进度
|
||||
*/
|
||||
public final static int DOWNLOAD_PROGRESS = 0x0034;
|
||||
|
||||
|
||||
/**
|
||||
* 通知homeactivity开启扫描
|
||||
*/
|
||||
public final static int START_SCAN = 0x0040;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,141 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.ToolUtil
|
||||
|
||||
/**
|
||||
* 报警动画
|
||||
*/
|
||||
class AlarmAnimationDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
private var mType: String? = null
|
||||
private var mMac: String? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var drawable: AnimationDrawable? = null
|
||||
fun getShareDialog(context: Context?, type: String?,mac:String, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
mType = type
|
||||
mMac = mac
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(1f)
|
||||
dialog!!.heightScale(1f)
|
||||
dialog!!.show()
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var tv_animation_cancel: TextView? = null
|
||||
var tv_animation_text: TextView? = null
|
||||
var imv_animation: ImageView? = null
|
||||
var li_close: LinearLayout? = null
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_animation, null)
|
||||
/*inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)*/
|
||||
imv_animation = inflate.findViewById<View>(R.id.imv_animation) as ImageView
|
||||
tv_animation_text = inflate.findViewById<TextView>(R.id.tv_animation_text) as TextView
|
||||
li_close = inflate.findViewById<View>(R.id.li_close) as LinearLayout
|
||||
tv_animation_cancel = inflate.findViewById<View>(R.id.tv_animation_cancel) as TextView
|
||||
|
||||
StartAnimaton()
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
li_close!!.setOnClickListener {
|
||||
StopAnimation()
|
||||
callBack!!.doWork()
|
||||
dismiss ()
|
||||
}
|
||||
//解除警报
|
||||
tv_animation_cancel!!.setOnClickListener {
|
||||
StopAnimation()
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun StartAnimaton() {
|
||||
//该条贴件数据
|
||||
var bindBean = ToolUtil.getBindMessByMac(mMac!!, activity!!)
|
||||
|
||||
when (mType) {
|
||||
"门" -> {
|
||||
tv_animation_text!!.text="${bindBean!!.name}${bindBean.type}贴件长时间未关闭"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.dooranimation) as AnimationDrawable
|
||||
}
|
||||
"水管" -> {
|
||||
tv_animation_text!!.text="${bindBean!!.name}${bindBean.type}贴件长时间未关闭"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.sganimation) as AnimationDrawable
|
||||
}
|
||||
"电冰箱" -> {
|
||||
tv_animation_text!!.text="${bindBean!!.name}${bindBean.type}贴件长时间未关闭"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.iceanimation) as AnimationDrawable
|
||||
}
|
||||
"煤气灶" -> {
|
||||
tv_animation_text!!.text="${bindBean!!.name}${bindBean.type}贴件长时间未关闭"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.rqzanimation) as AnimationDrawable
|
||||
}
|
||||
"电量低" -> {
|
||||
tv_animation_text!!.text="${bindBean!!.name}${bindBean.type}贴件电量过低"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.poweranimation) as AnimationDrawable
|
||||
}
|
||||
}
|
||||
// 放入imageView
|
||||
imv_animation!!.setBackgroundDrawable(drawable)
|
||||
// 开始
|
||||
drawable!!.start()
|
||||
}
|
||||
|
||||
fun StopAnimation(){
|
||||
if (drawable!!.isRunning) {
|
||||
drawable!!.stop()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: AlarmAnimationDialog? = null
|
||||
|
||||
// @get:Synchronized
|
||||
val instance: AlarmAnimationDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = AlarmAnimationDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,221 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.ActivityManager
|
||||
import com.qidian.zhongkesmart.utils.DataServer
|
||||
import com.qidian.zhongkesmart.utils.ToolUtil
|
||||
|
||||
/**
|
||||
* 报警动画
|
||||
*/
|
||||
class AlarmAnimationDialog2 {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
private var mType: String? = null
|
||||
private var mMac: String? = null
|
||||
var dialog: Dialog? = null
|
||||
var drawable: AnimationDrawable? = null
|
||||
|
||||
/* var tv_animation_cancel: TextView? = null
|
||||
var tv_animation_text: TextView? = null
|
||||
var imv_animation: ImageView? = null
|
||||
var li_close: LinearLayout? = null*/
|
||||
|
||||
fun getShareDialog(
|
||||
context: Context?,
|
||||
type: String?,
|
||||
mac: String,
|
||||
callBack: PopupYearWindowCallBack?
|
||||
) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
mType = type
|
||||
mMac = mac
|
||||
showDialog(mac)
|
||||
DataServer.listAlarmMac.add(mac!!)
|
||||
DataServer.listAlarmDialog.add(dialog!!)
|
||||
Log.i("报警弹窗Mac==", DataServer.listAlarmMac.toString())
|
||||
}
|
||||
|
||||
/*fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
DataServer.removeAlarmMac(mMac!!)
|
||||
}
|
||||
}*/
|
||||
|
||||
fun showDialog(mac:String) {
|
||||
// 构建Dialog
|
||||
// dialog = Dialog(activity!!)
|
||||
dialog = Dialog(activity!!, R.style.dialog_fullscreen_menu)
|
||||
// dialog!!.window!!.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||
val inflate: View =
|
||||
LayoutInflater.from(activity!!).inflate(R.layout.pop_animation, null)
|
||||
|
||||
|
||||
var imv_animation = inflate.findViewById<View>(R.id.imv_animation) as ImageView
|
||||
var tv_animation_text = inflate.findViewById<TextView>(R.id.tv_animation_text) as TextView
|
||||
var li_close = inflate.findViewById<View>(R.id.li_close) as LinearLayout
|
||||
var tv_animation_cancel = inflate.findViewById<View>(R.id.tv_animation_cancel) as TextView
|
||||
|
||||
li_close!!.setOnClickListener {
|
||||
// StopAnimation()
|
||||
if (drawable!!.isRunning) {
|
||||
drawable!!.stop()
|
||||
}
|
||||
callBack!!.doWork()
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
DataServer.removeAlarmMac(mac!!)
|
||||
}
|
||||
}
|
||||
//解除警报
|
||||
tv_animation_cancel!!.setOnClickListener {
|
||||
// StopAnimation()
|
||||
if (drawable!!.isRunning) {
|
||||
drawable!!.stop()
|
||||
}
|
||||
var a = mMac
|
||||
callBack!!.doWork()
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
DataServer.removeAlarmMac(mac!!)
|
||||
}
|
||||
}
|
||||
|
||||
dialog!!.setContentView(inflate)
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
dialog!!.setCancelable(false)
|
||||
|
||||
|
||||
val window: Window? = dialog!!.window
|
||||
window?.let {
|
||||
window.decorView.setPadding(0, 0, 0, 0) // 设置弹窗跟原始padding为0
|
||||
|
||||
val lp: WindowManager.LayoutParams? = window.attributes
|
||||
lp?.let {
|
||||
it.gravity = Gravity.CENTER
|
||||
it.width = WindowManager.LayoutParams.MATCH_PARENT
|
||||
it.height = WindowManager.LayoutParams.MATCH_PARENT
|
||||
it.horizontalMargin = 0F
|
||||
window.attributes = it
|
||||
|
||||
}
|
||||
window.decorView.minimumWidth = activity!!.resources.displayMetrics.widthPixels
|
||||
window.decorView.setBackgroundColor(Color.TRANSPARENT) // 颜色要设置,不然不能全屏,所以设置透明
|
||||
}
|
||||
|
||||
|
||||
dialog!!.show()
|
||||
// StartAnimaton()
|
||||
//该条贴件数据
|
||||
var bindBean = ToolUtil.getBindMessByMac(mMac!!, activity!!)
|
||||
|
||||
when (mType) {
|
||||
"门" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件开启时间过长"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.dooranimation) as AnimationDrawable
|
||||
}
|
||||
"水管" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件开启时间过长"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.sganimation) as AnimationDrawable
|
||||
}
|
||||
"电冰箱" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件开启时间过长"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.iceanimation) as AnimationDrawable
|
||||
}
|
||||
"煤气灶" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件开启时间过长"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.rqzanimation) as AnimationDrawable
|
||||
}
|
||||
"电量低" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件电量过低"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.poweranimation) as AnimationDrawable
|
||||
}
|
||||
}
|
||||
// 放入imageView
|
||||
imv_animation!!.setBackgroundDrawable(drawable)
|
||||
// 开始
|
||||
drawable!!.start()
|
||||
}
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
}
|
||||
|
||||
fun setUiBeforShow() {
|
||||
|
||||
}
|
||||
|
||||
/* fun StartAnimaton() {
|
||||
//该条贴件数据
|
||||
var bindBean = ToolUtil.getBindMessByMac(mMac!!, activity!!)
|
||||
|
||||
when (mType) {
|
||||
"门" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件开启时间过长"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.dooranimation) as AnimationDrawable
|
||||
}
|
||||
"水管" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件开启时间过长"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.sganimation) as AnimationDrawable
|
||||
}
|
||||
"电冰箱" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件开启时间过长"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.iceanimation) as AnimationDrawable
|
||||
}
|
||||
"煤气灶" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件开启时间过长"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.rqzanimation) as AnimationDrawable
|
||||
}
|
||||
"电量低" -> {
|
||||
tv_animation_text!!.text = "${bindBean!!.name}${bindBean.type}贴件电量过低"
|
||||
drawable =
|
||||
activity?.resources?.getDrawable(R.drawable.poweranimation) as AnimationDrawable
|
||||
}
|
||||
}
|
||||
// 放入imageView
|
||||
imv_animation!!.setBackgroundDrawable(drawable)
|
||||
// 开始
|
||||
drawable!!.start()
|
||||
}
|
||||
*/
|
||||
fun StopAnimation() {
|
||||
if (drawable!!.isRunning) {
|
||||
drawable!!.stop()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: AlarmAnimationDialog2? = null
|
||||
|
||||
// @get:Synchronized
|
||||
val instance: AlarmAnimationDialog2?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = AlarmAnimationDialog2()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import java.util.*
|
||||
|
||||
/*取消绑定*/
|
||||
class CancelBindDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.5f)
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
dialog!!.show()
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
// fun doCancel()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var tv_content: TextView? = null
|
||||
var pop_ok: TextView? = null
|
||||
var pop_cancnel: TextView? = null
|
||||
var tv_woprn: TextView? = null
|
||||
var li_close: LinearLayout? = null
|
||||
var ced_pop: ClearEditText? = null
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_cancelbind, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<LinearLayout>(R.id.li_close) as LinearLayout
|
||||
pop_cancnel = inflate.findViewById<View>(R.id.tv_pop_cancel) as TextView
|
||||
pop_ok = inflate.findViewById<View>(R.id.tv_pop_sure) as TextView
|
||||
tv_content
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
pop_ok!!.setOnClickListener(View.OnClickListener {
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
})
|
||||
pop_cancnel!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
li_close!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: CancelBindDialog? = null
|
||||
|
||||
// @get:Synchronized
|
||||
val instance: CancelBindDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = CancelBindDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import java.util.*
|
||||
|
||||
/*取消绑定*/
|
||||
class CancelModeInitDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.5f)
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
dialog!!.show()
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
// fun doCancel()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var tv_content: TextView? = null
|
||||
var pop_ok: TextView? = null
|
||||
var pop_cancnel: TextView? = null
|
||||
var tv_woprn: TextView? = null
|
||||
var li_close: LinearLayout? = null
|
||||
var ced_pop: ClearEditText? = null
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_cancel_mode_init, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<LinearLayout>(R.id.li_close) as LinearLayout
|
||||
pop_cancnel = inflate.findViewById<View>(R.id.tv_pop_cancel) as TextView
|
||||
pop_ok = inflate.findViewById<View>(R.id.tv_pop_sure) as TextView
|
||||
tv_content
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
pop_ok!!.setOnClickListener(View.OnClickListener {
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
})
|
||||
pop_cancnel!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
li_close!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: CancelModeInitDialog? = null
|
||||
|
||||
// @get:Synchronized
|
||||
val instance: CancelModeInitDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = CancelModeInitDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import java.util.*
|
||||
|
||||
/*取消绑定*/
|
||||
class CancelSettingModeDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.5f)
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
dialog!!.show()
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
// fun doCancel()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var tv_content: TextView? = null
|
||||
var pop_ok: TextView? = null
|
||||
var pop_cancnel: TextView? = null
|
||||
var tv_woprn: TextView? = null
|
||||
var li_close: LinearLayout? = null
|
||||
var ced_pop: ClearEditText? = null
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_cancel_setting_mode, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<LinearLayout>(R.id.li_close) as LinearLayout
|
||||
pop_cancnel = inflate.findViewById<View>(R.id.tv_pop_cancel) as TextView
|
||||
pop_ok = inflate.findViewById<View>(R.id.tv_pop_sure) as TextView
|
||||
tv_content
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
pop_ok!!.setOnClickListener(View.OnClickListener {
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
})
|
||||
pop_cancnel!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
li_close!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: CancelSettingModeDialog? = null
|
||||
|
||||
// @get:Synchronized
|
||||
val instance: CancelSettingModeDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = CancelSettingModeDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import java.util.*
|
||||
|
||||
/*取消绑定*/
|
||||
class ChangeConnectModeDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var mTitle = ""
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?,title:String) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
mTitle = title
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.5f)
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
dialog!!.show()
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
// fun doCancel()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var pop_ok: TextView? = null
|
||||
var pop_cancnel: TextView? = null
|
||||
var li_close: LinearLayout? = null
|
||||
var tv_title: TextView? = null
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_change_connect_mode, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<LinearLayout>(R.id.li_close) as LinearLayout
|
||||
pop_cancnel = inflate.findViewById<View>(R.id.tv_pop_cancel) as TextView
|
||||
pop_ok = inflate.findViewById<View>(R.id.tv_pop_sure) as TextView
|
||||
tv_title = inflate.findViewById<View>(R.id.tv_title) as TextView
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
tv_title!!.text = "修改网关的连接模式为${mTitle}吗?点击确定将会重启应用"
|
||||
pop_ok!!.setOnClickListener(View.OnClickListener {
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
})
|
||||
pop_cancnel!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
li_close!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: ChangeConnectModeDialog? = null
|
||||
|
||||
// @get:Synchronized
|
||||
val instance: ChangeConnectModeDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = ChangeConnectModeDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import java.util.*
|
||||
|
||||
/*蓝牙配对*/
|
||||
class ConnectBluetoothDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var mTitle=""
|
||||
var mCode=""
|
||||
|
||||
fun getShareDialog(context: Context?, title:String,code:String,callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
this.mTitle = title
|
||||
this.mCode = code
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.5f)
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
dialog!!.show()
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
// fun doCancel()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var tv_title: TextView? = null
|
||||
var tv_concent: TextView? = null
|
||||
var pop_ok: TextView? = null
|
||||
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_connectbluetooth, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
tv_title = inflate.findViewById<View>(R.id.tv_title) as TextView
|
||||
tv_concent = inflate.findViewById<View>(R.id.tv_concent) as TextView
|
||||
pop_ok = inflate.findViewById<View>(R.id.tv_pop_sure) as TextView
|
||||
tv_title!!.text=mTitle
|
||||
tv_concent!!.text=""+mCode
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
pop_ok!!.setOnClickListener(View.OnClickListener {
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: ConnectBluetoothDialog? = null
|
||||
|
||||
@get:Synchronized
|
||||
val instance: ConnectBluetoothDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = ConnectBluetoothDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import java.util.*
|
||||
|
||||
/*提示是否断开蓝牙*/
|
||||
class DisconnectBlueDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.5f)
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
setShow()
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun setShow(){
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
return
|
||||
}
|
||||
dialog!!.show()
|
||||
}
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var tv_content: TextView? = null
|
||||
var pop_ok: TextView? = null
|
||||
var pop_cancnel: TextView? = null
|
||||
var tv_woprn: TextView? = null
|
||||
var li_close: LinearLayout? = null
|
||||
var ced_pop: ClearEditText? = null
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_openwifi, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
tv_content = inflate.findViewById<View>(R.id.tv_content) as TextView
|
||||
pop_cancnel = inflate.findViewById<View>(R.id.pop_cancnel) as TextView
|
||||
pop_ok = inflate.findViewById<View>(R.id.pop_ok) as TextView
|
||||
tv_content!!.text="是否要断开与该蓝牙的连接?"
|
||||
pop_ok!!.text="确定"
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
pop_ok!!.setOnClickListener(View.OnClickListener {
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
})
|
||||
pop_cancnel!!.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: DisconnectBlueDialog? = null
|
||||
|
||||
@get:Synchronized
|
||||
val instance: DisconnectBlueDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = DisconnectBlueDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,329 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.model.GetCodeM
|
||||
import com.qidian.zhongkesmart.model.GetLoginM
|
||||
import com.qidian.zhongkesmart.model.GetTokenM
|
||||
import com.qidian.zhongkesmart.net.*
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import kotlinx.android.synthetic.main.layout_list.*
|
||||
import java.util.*
|
||||
|
||||
/*设备状态弹窗*/
|
||||
class EquipmentStatusDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var mLoopTime = 180 //默认轮训三分钟
|
||||
// var mLoopTime = 10 //默认轮训三分钟
|
||||
var isLoading = false
|
||||
var mTAG = "设备绑定=="
|
||||
var mCode = ""
|
||||
var li_equipment_need: LinearLayout? = null
|
||||
var li_close: LinearLayout? = null
|
||||
var tv_equipment_status: TextView? = null
|
||||
var tv_equipment_bind: TextView? = null
|
||||
var tv_equipment_text1: TextView? = null
|
||||
var tv_equipment_text2: TextView? = null
|
||||
var tv_needtext: TextView? = null
|
||||
var imv_equipment: ImageView? = null
|
||||
//是否绑定成功了,绑定成功后 二维码type为2
|
||||
var isDeviceStatus = false
|
||||
var isBinding = false
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.6f)
|
||||
dialog!!.show()
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
if (handler.hasMessages(0)) {
|
||||
handler.removeMessages(0)
|
||||
}
|
||||
}
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork(place: String?, use: String?)
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
|
||||
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_equipmentstatus, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<LinearLayout>(R.id.li_close)
|
||||
li_equipment_need = inflate.findViewById<LinearLayout>(R.id.li_equipment_need)
|
||||
tv_needtext = inflate.findViewById<TextView>(R.id.tv_needtext)
|
||||
tv_equipment_status = inflate.findViewById<TextView>(R.id.tv_equipment_status)
|
||||
tv_equipment_bind = inflate.findViewById<TextView>(R.id.tv_equipment_bind)
|
||||
tv_equipment_text1 = inflate.findViewById<TextView>(R.id.tv_equipment_text1)
|
||||
tv_equipment_text2 = inflate.findViewById<TextView>(R.id.tv_equipment_text2)
|
||||
imv_equipment = inflate.findViewById<ImageView>(R.id.imv_equipment)
|
||||
if (DataServer.mHttpToken.isNullOrEmpty()) {
|
||||
isDeviceStatus = false
|
||||
showNeedBind("请先绑定网关")
|
||||
li_equipment_need!!.visibility = View.VISIBLE
|
||||
//开始轮训
|
||||
StartLoop()
|
||||
} else {
|
||||
li_equipment_need!!.visibility = View.GONE
|
||||
isDeviceStatus = true
|
||||
Log.i(mTAG, "mCode=${DataServer.mCode}")
|
||||
if(!DataServer.mCode.isNullOrEmpty())
|
||||
createErCode(DataServer.mCode)//已绑定 直接生成 包含id
|
||||
}
|
||||
|
||||
return inflate
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备绑定
|
||||
* 设备绑定的二维码包含:当前设备ID和绑定状态等信息
|
||||
微信小程序通过扫码获取信息后像服务端发起绑定申请
|
||||
当用户打开该弹窗时,APP需要先判断自己本地是否有token,如果没有则先向服务端申请Code
|
||||
再使用该code轮询调用服务端接口获取token
|
||||
轮询每秒一次,code的有效期为3分钟,3分钟后停止轮询,当获取到token后弹出吐司提示“绑定成功”,停止轮询
|
||||
当超过3分钟后,二维显示“请重新刷新二维码”,点击后刷新后重复上述过程
|
||||
*/
|
||||
/*点击事件处理*/
|
||||
override fun setUiBeforShow() {
|
||||
//设别状态
|
||||
tv_equipment_status!!.setOnClickListener {
|
||||
tv_equipment_status!!.setTextColor(activity!!.resources.getColor(R.color.white))
|
||||
tv_equipment_bind!!.setTextColor(activity!!.resources.getColor(R.color.color_333333))
|
||||
tv_equipment_status!!.setBackgroundResource(R.drawable.ed_0_516afc_full)
|
||||
tv_equipment_bind!!.setBackgroundResource(R.drawable.ed_0_ffc5cbd7_line)
|
||||
tv_equipment_text1!!.text = "获取全部设备状态"
|
||||
tv_equipment_text2!!.text = "使用小程序扫描二维码获取全部设备状态至小程序"
|
||||
if (DataServer.mHttpToken.isNullOrEmpty()) {
|
||||
showNeedBind("请先绑定网关")
|
||||
} else {
|
||||
li_equipment_need!!.visibility = View.GONE
|
||||
}
|
||||
// StopLoop()
|
||||
}
|
||||
//设别绑定
|
||||
tv_equipment_bind!!.setOnClickListener {
|
||||
tv_equipment_bind!!.setTextColor(activity!!.resources.getColor(R.color.white))
|
||||
tv_equipment_status!!.setTextColor(activity!!.resources.getColor(R.color.color_333333))
|
||||
tv_equipment_bind!!.setBackgroundResource(R.drawable.ed_0_516afc_full)
|
||||
tv_equipment_status!!.setBackgroundResource(R.drawable.ed_0_ffc5cbd7_line)
|
||||
tv_equipment_text1!!.text = "使用小程序绑定该设备"
|
||||
tv_equipment_text2!!.text = "使用小程序扫描二维码"
|
||||
li_equipment_need!!.visibility = View.GONE
|
||||
if (DataServer.mHttpToken.isNullOrEmpty()) {
|
||||
//开始轮训
|
||||
StartLoop()
|
||||
}
|
||||
|
||||
}
|
||||
li_close!!.setOnClickListener {
|
||||
setDismiss()
|
||||
StopLoop()
|
||||
}
|
||||
li_equipment_need!!.setOnClickListener {
|
||||
if (tv_needtext!!.text == "请刷新二维码") {
|
||||
li_equipment_need!!.visibility=View.GONE
|
||||
//刷新二维码 再次开始轮训
|
||||
StartLoop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//显示网关提示覆盖布局
|
||||
fun showNeedBind(str: String) {
|
||||
li_equipment_need!!.visibility = View.VISIBLE
|
||||
tv_needtext!!.text = str
|
||||
}
|
||||
|
||||
//开始轮训
|
||||
fun StartLoop() {
|
||||
|
||||
if (handler.hasMessages(0)) {
|
||||
handler.removeMessages(0)
|
||||
}
|
||||
Log.i(mTAG, "开始轮训")
|
||||
//开始轮训token
|
||||
mLoopTime = 180
|
||||
mCode = ""
|
||||
handler.sendEmptyMessageDelayed(0, 1000)
|
||||
}
|
||||
|
||||
//结束轮训
|
||||
fun StopLoop() {
|
||||
if (handler.hasMessages(0)) {
|
||||
handler.removeMessages(0)
|
||||
}
|
||||
Log.i(mTAG, "停止轮训")
|
||||
//开始轮训token
|
||||
mLoopTime = 180
|
||||
mCode = ""
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("HandlerLeak")
|
||||
var handler: Handler = object : Handler() {
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
Log.d("-Tag111", "handler定时")
|
||||
this.removeMessages(0)
|
||||
if (mLoopTime > 0) {
|
||||
mLoopTime--
|
||||
sendEmptyMessageDelayed(0, 1000)
|
||||
if (!isLoading) {
|
||||
//code有效期内不需要再重新获取
|
||||
if (mCode.isNullOrEmpty()) {
|
||||
isLoading = true
|
||||
getHttpCode()
|
||||
} else {
|
||||
isLoading = true
|
||||
getBindingStatus(mCode)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//结束一轮轮训
|
||||
removeMessages(0)
|
||||
Log.i(mTAG, "结束轮训")
|
||||
//显示刷新
|
||||
showNeedBind("请刷新二维码")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 网关登录
|
||||
*/
|
||||
//获取code
|
||||
fun getHttpCode() {
|
||||
var map = HashMap<String, String>()
|
||||
map["id"] = DeviceUuidFactory.getAndroidID(activity)
|
||||
HttpRequest.init(activity).get(ApiUrl.getCode)
|
||||
.setMap(map)
|
||||
.setShowDialog(false)
|
||||
// .setClazz(GetCodeM::class.java)
|
||||
.excute(object : HttpCallBack() {
|
||||
override fun success(message: String?, `object`: Any?) {
|
||||
Log.e("getHttpCode", message!!)
|
||||
mCode = `object`.toString()
|
||||
createErCode(mCode)//未绑定 直接生成 包含id+code
|
||||
if(!isBinding) {
|
||||
getBindingStatus(mCode)
|
||||
}else{
|
||||
getToken((mCode))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//获取网关绑定状态
|
||||
fun getBindingStatus(mCode: String) {
|
||||
var map = HashMap<String?, String?>()
|
||||
map["code"] = mCode
|
||||
map["id"] = DeviceUuidFactory.getAndroidID(activity)
|
||||
HttpRequest.init(activity).postJson(ApiUrl.getBindingStatus,map,"",false)
|
||||
.setShowDialog(false)
|
||||
.excute(object : HttpCallBack() {
|
||||
override fun success(message: String?, `object`: Any?) {
|
||||
Log.e("getBindingStatus", message!!)
|
||||
getHttpCode()
|
||||
isBinding = true
|
||||
this@EquipmentStatusDialog.mCode = ""
|
||||
}
|
||||
|
||||
override fun failed(code: String?, info: String?): Boolean {
|
||||
Log.e("getBindingStatus", code!!)
|
||||
return super.failed(code, info)
|
||||
}
|
||||
|
||||
override fun after() {
|
||||
super.after()
|
||||
isLoading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//网关登录 获取token存本地 这里如果绑定了就有token 不绑定就没有token 不影响后面测试网关是否连接成功
|
||||
fun getToken(mCode: String) {
|
||||
var map = HashMap<String?, String?>()
|
||||
map["code"] = mCode
|
||||
map["id"] = DeviceUuidFactory.getAndroidID(activity)
|
||||
HttpRequest.init(activity).postJson(ApiUrl.getLogin, map, "",false)
|
||||
.setClazz(GetTokenM::class.java)
|
||||
.setShowDialog(false)
|
||||
.excute(object : HttpCallBack() {
|
||||
override fun success(message: String?, `object`: Any?) {
|
||||
var model = `object` as GetTokenM
|
||||
var mToken = model.token
|
||||
Log.i("SJF:model", mToken)
|
||||
|
||||
DataServer.mHttpToken = mToken
|
||||
DataServer.mCode = mCode
|
||||
if (!DataServer.mHttpToken.isNullOrEmpty()) {
|
||||
li_equipment_need!!.visibility = View.GONE
|
||||
}
|
||||
isDeviceStatus = true
|
||||
//createErCode(mCode)
|
||||
StopLoop()
|
||||
// handler.removeMessages(0)
|
||||
ToastUtil.showToast("绑定成功")
|
||||
}
|
||||
|
||||
override fun failed(code: String?, info: String?): Boolean {
|
||||
this@EquipmentStatusDialog.mCode = ""
|
||||
return super.failed(code, info)
|
||||
}
|
||||
|
||||
override fun after() {
|
||||
super.after()
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: EquipmentStatusDialog? = null
|
||||
|
||||
@get:Synchronized
|
||||
val instance: EquipmentStatusDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = EquipmentStatusDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
|
||||
//生成二维码
|
||||
fun createErCode(inputcode:String){
|
||||
var btimap=ToolUtil.createEwm(DeviceUuidFactory.getAndroidID(activity),inputcode,if(isDeviceStatus) 2 else 1)
|
||||
imv_equipment!!.setImageBitmap(btimap)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,459 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.activity.HomeActivity
|
||||
import com.qidian.zhongkesmart.activity.SettingModeActivity
|
||||
import com.qidian.zhongkesmart.model.CommonMLocation
|
||||
import com.qidian.zhongkesmart.model.CommonMUse
|
||||
import com.qidian.zhongkesmart.utils.*
|
||||
import com.scwang.smartrefresh.layout.util.DensityUtil.dp2px
|
||||
import kotlinx.android.synthetic.main.layout_list.*
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
import net.idik.lib.slimadapter.SlimInjector
|
||||
import net.idik.lib.slimadapter.viewinjector.IViewInjector
|
||||
import org.w3c.dom.Text
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/*发现新设备弹窗*/
|
||||
class FindNewEquipmentDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var mChooseType = 0//默认显示设备信息
|
||||
var mMac = ""
|
||||
var ll_setting_mode: LinearLayout? = null
|
||||
var tv_pop_sure: TextView? = null
|
||||
var tv_pop_relievebind: TextView? = null
|
||||
var tv_pop_cancel: TextView? = null
|
||||
var tv_connect_status:TextView? = null
|
||||
fun getShareDialog(context: Context?, mac: String, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
this.mMac = mac
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.8f)
|
||||
dialog!!.show()
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
callBack!!.doDismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun bindSuccess(){
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
// ll_setting_mode!!.visibility = View.VISIBLE
|
||||
tv_pop_relievebind!!.visibility = View.VISIBLE
|
||||
tv_pop_cancel!!.visibility = View.GONE
|
||||
tv_pop_sure!!.text = "下一步"
|
||||
}
|
||||
}
|
||||
|
||||
fun connectSuccess(){
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
tv_connect_status!!.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
fun connectFail(){
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
tv_connect_status!!.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
fun goSettingMode(){
|
||||
setDismiss()
|
||||
activity!!.startActivity(Intent(activity, SettingModeActivity::class.java))
|
||||
}
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork(roomName: String?, type: String?)
|
||||
fun doChangeWork(roomName: String?, type: String?)
|
||||
fun doUnBindWork()
|
||||
fun doConnectTj()
|
||||
fun doDismiss()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var li_close: LinearLayout? = null
|
||||
var li_new_place: LinearLayout? = null
|
||||
var li_new_use: LinearLayout? = null
|
||||
var li_equipment: LinearLayout? = null
|
||||
var tv_pop_title: TextView? = null
|
||||
var tv_new_name: TextView? = null
|
||||
var tv_place_custom: TextView? = null
|
||||
var tv_place_worm: TextView? = null
|
||||
var tv_use_custom: TextView? = null
|
||||
var tv_use_worm: TextView? = null
|
||||
var imv_pic: ImageView? = null
|
||||
var tv_new_place: EditText? = null
|
||||
var tv_new_use: EditText? = null
|
||||
var recycle_options: RecyclerView? = null
|
||||
var mAdapter: SlimAdapter? = null
|
||||
var mData = ArrayList<Any>()
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_findnew, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<LinearLayout>(R.id.li_close)
|
||||
li_new_place = inflate.findViewById<LinearLayout>(R.id.li_new_place)
|
||||
li_new_use = inflate.findViewById<LinearLayout>(R.id.li_new_use)
|
||||
tv_pop_title = inflate.findViewById<TextView>(R.id.tv_pop_title)
|
||||
tv_new_name = inflate.findViewById<TextView>(R.id.tv_new_name)
|
||||
imv_pic = inflate.findViewById<ImageView>(R.id.imv_pic)
|
||||
tv_new_place = inflate.findViewById<EditText>(R.id.tv_new_place)
|
||||
tv_place_custom = inflate.findViewById<TextView>(R.id.tv_place_custom)
|
||||
tv_place_worm = inflate.findViewById<TextView>(R.id.tv_place_worm)
|
||||
tv_new_use = inflate.findViewById<EditText>(R.id.tv_new_use)
|
||||
tv_use_custom = inflate.findViewById<TextView>(R.id.tv_use_custom)
|
||||
tv_use_worm = inflate.findViewById<TextView>(R.id.tv_use_worm)
|
||||
recycle_options = inflate.findViewById<RecyclerView>(R.id.recycle_options)
|
||||
li_equipment = inflate.findViewById<LinearLayout>(R.id.li_equipment)
|
||||
//按钮
|
||||
tv_pop_cancel = inflate.findViewById<TextView>(R.id.tv_pop_cancel)
|
||||
tv_pop_relievebind = inflate.findViewById<TextView>(R.id.tv_pop_relievebind)
|
||||
tv_pop_sure = inflate.findViewById<TextView>(R.id.tv_pop_sure)
|
||||
ll_setting_mode = inflate.findViewById<LinearLayout>(R.id.ll_setting_mode)
|
||||
tv_connect_status = inflate.findViewById<TextView>(R.id.tv_connect_status)
|
||||
//固定内容
|
||||
tv_new_name!!.text = "低功耗节点Low Power"
|
||||
/*进入默认不能输入*/
|
||||
setEdit(false, tv_new_place!!)
|
||||
setEdit(false, tv_new_use!!)
|
||||
aboutList()
|
||||
if (ToolUtil.isBind(activity!!, DataServer.mBindHistory, mMac)) {
|
||||
var model = ToolUtil.getBindBlueToothData(activity!!, DataServer.mBindHistory, mMac)
|
||||
tv_new_place!!.setText(model.name)
|
||||
tv_new_use!!.setText(model.type)
|
||||
}
|
||||
isBind()
|
||||
return inflate
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否绑定
|
||||
*/
|
||||
fun isBind() {
|
||||
if (ToolUtil.isBind(activity!!, DataServer.mBindHistory, mMac)) {
|
||||
tv_pop_relievebind!!.visibility = View.VISIBLE
|
||||
tv_pop_cancel!!.visibility = View.GONE
|
||||
tv_pop_sure!!.text = "确定"
|
||||
tv_pop_title!!.text = "已绑定设备"
|
||||
} else {
|
||||
tv_pop_relievebind!!.visibility = View.GONE
|
||||
tv_pop_cancel!!.visibility = View.VISIBLE
|
||||
tv_pop_sure!!.text = "立即绑定"
|
||||
tv_pop_title!!.text = "发现新设备"
|
||||
}
|
||||
}
|
||||
|
||||
/*设置是否可编辑*/
|
||||
fun setEdit(isCan: Boolean, edittext: EditText) {
|
||||
edittext.isCursorVisible = isCan
|
||||
edittext.isFocusable = isCan
|
||||
edittext.setTextIsSelectable(isCan)
|
||||
}
|
||||
|
||||
/*点击事件处理*/
|
||||
override fun setUiBeforShow() {
|
||||
//选择位置
|
||||
tv_new_place!!.setOnClickListener {
|
||||
mChooseType = 1
|
||||
getTypeList()
|
||||
showChooseList(true)
|
||||
}
|
||||
tv_new_place!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
count: Int,
|
||||
after: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
if (s!!.isNotEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle3(
|
||||
tv_new_place!!,
|
||||
li_new_place!!,
|
||||
tv_place_worm!!,
|
||||
""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
//自定义
|
||||
tv_place_custom!!.setOnClickListener {
|
||||
if (tv_place_custom!!.text.toString() == "自定义") {
|
||||
tv_place_custom!!.text = "选择"
|
||||
tv_new_place!!.hint = "请输入放置位置"
|
||||
setEdit(true, tv_new_place!!)
|
||||
} else {
|
||||
tv_place_custom!!.text = "自定义"
|
||||
setEdit(false, tv_new_place!!)
|
||||
tv_new_place!!.hint = "请选择放置位置"
|
||||
}
|
||||
}
|
||||
//选择用途
|
||||
tv_new_use!!.setOnClickListener {
|
||||
mChooseType = 2
|
||||
showChooseList(true)
|
||||
getLocationData(tv_new_place!!.text.toString())
|
||||
}
|
||||
tv_new_use!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
count: Int,
|
||||
after: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
if (s!!.isNotEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle3(
|
||||
tv_new_use!!,
|
||||
li_new_use!!,
|
||||
tv_use_worm!!,
|
||||
""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
//自定义
|
||||
tv_use_custom!!.setOnClickListener {
|
||||
if (tv_use_custom!!.text.toString() == "自定义") {
|
||||
tv_use_custom!!.text = "选择"
|
||||
setEdit(true, tv_new_use!!)
|
||||
tv_new_use!!.hint = "请输入设备用途"
|
||||
} else {
|
||||
tv_use_custom!!.text = "自定义"
|
||||
tv_new_use!!.isEnabled = false
|
||||
setEdit(false, tv_new_use!!)
|
||||
tv_new_use!!.hint = "请选择设备用途"
|
||||
}
|
||||
}
|
||||
//立即绑定+确定
|
||||
tv_pop_sure!!.setOnClickListener {
|
||||
if (tv_pop_sure!!.text == "立即绑定") {
|
||||
if (tv_new_place!!.text!!.isEmpty() || tv_new_use!!.text!!.isEmpty()) {
|
||||
if (tv_new_place!!.text!!.isEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle3(
|
||||
tv_new_place!!,
|
||||
li_new_place!!,
|
||||
tv_place_worm!!,
|
||||
"请选择放置位置"
|
||||
)
|
||||
}
|
||||
if (tv_new_use!!.text!!.isEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle3(
|
||||
tv_new_use!!,
|
||||
li_new_use!!,
|
||||
tv_use_worm!!,
|
||||
"请选择设备用途"
|
||||
)
|
||||
}
|
||||
return@setOnClickListener
|
||||
}
|
||||
callBack!!.doWork(tv_new_place!!.text.toString(), tv_new_use!!.text.toString())
|
||||
}else if(tv_pop_sure!!.text == "返回"){
|
||||
callBack!!.doDismiss()
|
||||
dismiss()
|
||||
}else if(tv_pop_sure!!.text == "下一步"){
|
||||
callBack!!.doConnectTj()
|
||||
} else {//确定 修改
|
||||
if (tv_new_place!!.text!!.isEmpty() || tv_new_use!!.text!!.isEmpty()) {
|
||||
if (tv_new_place!!.text!!.isEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle3(
|
||||
tv_new_place!!,
|
||||
li_new_place!!,
|
||||
tv_place_worm!!,
|
||||
"请选择放置位置"
|
||||
)
|
||||
}
|
||||
if (tv_new_use!!.text!!.isEmpty()) {
|
||||
InputLimitUtil.ShowEdittextStyle3(
|
||||
tv_new_use!!,
|
||||
li_new_use!!,
|
||||
tv_use_worm!!,
|
||||
"请选择设备用途"
|
||||
)
|
||||
}
|
||||
return@setOnClickListener
|
||||
}
|
||||
callBack!!.doChangeWork(tv_new_place!!.text.toString(), tv_new_use!!.text.toString())
|
||||
// dismiss()
|
||||
}
|
||||
}
|
||||
li_close!!.setOnClickListener {
|
||||
if (mChooseType != 0) {
|
||||
showChooseList(false)
|
||||
} else {
|
||||
callBack!!.doDismiss()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
//取消
|
||||
tv_pop_cancel!!.setOnClickListener {
|
||||
if (mChooseType != 0) {
|
||||
showChooseList(false)
|
||||
} else {
|
||||
callBack!!.doDismiss()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
//解除绑定
|
||||
tv_pop_relievebind!!.setOnClickListener {
|
||||
callBack!!.doUnBindWork()
|
||||
}
|
||||
//配置模式
|
||||
ll_setting_mode!!.setOnClickListener{
|
||||
callBack!!.doConnectTj()
|
||||
}
|
||||
}
|
||||
|
||||
/*选择位置+用途*/
|
||||
fun aboutList() {
|
||||
LoadUtils.setLinearLayoutManager(activity, recycle_options, false)
|
||||
mAdapter =
|
||||
SlimAdapter.create()
|
||||
//位置
|
||||
.register<CommonMLocation>(
|
||||
R.layout.item_text,
|
||||
object : SlimInjector<CommonMLocation> {
|
||||
override fun onInject(
|
||||
data: CommonMLocation,
|
||||
injector: IViewInjector<out IViewInjector<*>>
|
||||
) {
|
||||
injector.text(R.id.tv_text, data.name)
|
||||
injector.with<TextView>(R.id.tv_text) {
|
||||
//选中变色效果暂未实现
|
||||
if (data.check == 1) {
|
||||
it.setBackgroundColor(activity!!.resources.getColor(R.color.color_516AFC))
|
||||
it.setTextColor(activity!!.resources.getColor(R.color.white))
|
||||
} else {
|
||||
it.setBackgroundColor(activity!!.resources.getColor(R.color.white))
|
||||
it.setTextColor(activity!!.resources.getColor(R.color.color_999999))
|
||||
}
|
||||
}
|
||||
injector.clicked(R.id.li_text) {
|
||||
if (mChooseType == 1) {
|
||||
tv_new_place!!.setText(data.name)
|
||||
// tv_new_use!!.setText("")
|
||||
} else if (mChooseType == 2) {
|
||||
tv_new_use!!.setText(data.name)
|
||||
}
|
||||
showChooseList(false)
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
.attachTo(recycle_options)
|
||||
|
||||
}
|
||||
|
||||
//位置数据
|
||||
fun getTypeList() {
|
||||
mData.clear()
|
||||
DataServer.TJLocation.forEach {
|
||||
var bean = CommonMLocation(it, 0)
|
||||
mData.add(bean)
|
||||
}
|
||||
mAdapter!!.updateData(mData).notifyDataSetChanged()
|
||||
}
|
||||
|
||||
//用途数据
|
||||
fun getLocationData(type: String) {
|
||||
mData.clear()
|
||||
DataServer.TJUse.forEach {
|
||||
var bean = CommonMLocation(it, 0)
|
||||
mData.add(bean)
|
||||
}
|
||||
mAdapter!!.updateData(mData).notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun getData(list: Array<String>) {
|
||||
list.forEach {
|
||||
var bean = CommonMLocation(it, 0)
|
||||
mData.add(bean)
|
||||
}
|
||||
}
|
||||
|
||||
/*显示界面按断*/
|
||||
fun showChooseList(isShow: Boolean) {
|
||||
if (isShow) {
|
||||
//按钮
|
||||
tv_pop_cancel!!.visibility = View.VISIBLE
|
||||
tv_pop_sure!!.visibility = View.VISIBLE
|
||||
tv_pop_sure!!.text = "确定"
|
||||
tv_pop_relievebind!!.visibility = View.GONE
|
||||
//布局样式
|
||||
recycle_options!!.visibility = View.VISIBLE
|
||||
li_equipment!!.visibility = View.GONE
|
||||
} else {
|
||||
recycle_options!!.visibility = View.GONE
|
||||
li_equipment!!.visibility = View.VISIBLE
|
||||
//按钮--现在只考虑未绑定状态
|
||||
isBind()
|
||||
/* tv_pop_cancel!!.visibility = View.GONE
|
||||
tv_pop_sure!!.visibility = View.VISIBLE
|
||||
tv_pop_sure!!.text = "立即绑定"
|
||||
tv_pop_relievebind!!.visibility = View.GONE*/
|
||||
mChooseType = 0
|
||||
}
|
||||
when (mChooseType) {
|
||||
0 -> {
|
||||
tv_pop_title!!.text = "发现新设备"
|
||||
}
|
||||
1 -> {
|
||||
tv_pop_title!!.text = "选择位置"
|
||||
}
|
||||
2 -> {
|
||||
tv_pop_title!!.text = "选择用途"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: FindNewEquipmentDialog? = null
|
||||
|
||||
@get:Synchronized
|
||||
val instance: FindNewEquipmentDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = FindNewEquipmentDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.animation.SlideEnter.SlideTopEnter
|
||||
import com.flyco.animation.SlideExit.SlideTopExit
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.activity.InfoActivity
|
||||
import com.qidian.zhongkesmart.model.BindBlueToothData
|
||||
import com.qidian.zhongkesmart.model.DeviceInfo
|
||||
import com.qidian.zhongkesmart.utils.DataServer
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.utils.ObjectBoxUtils
|
||||
import com.qidian.zhongkesmart.utils.ToolUtil
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import com.zhy.view.flowlayout.FlowLayout
|
||||
import com.zhy.view.flowlayout.TagAdapter
|
||||
import com.zhy.view.flowlayout.TagFlowLayout
|
||||
import kotlinx.android.synthetic.main.layout_standby.*
|
||||
import java.util.*
|
||||
|
||||
/*取消绑定*/
|
||||
class HomeDeviceDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var flowlayoutAdapter: TagAdapter<DeviceInfo>? = null
|
||||
var mStansByList = ArrayList<DeviceInfo>()
|
||||
var id_flow_layout:TagFlowLayout? = null
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.8f)
|
||||
dialog!!.setCanceledOnTouchOutside(true)
|
||||
dialog!!.show()
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
// fun doCancel()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var li_standby_background: LinearLayout? = null
|
||||
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_home_devices, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_standby_background = inflate.findViewById<LinearLayout>(R.id.li_standby_background) as LinearLayout
|
||||
id_flow_layout = inflate.findViewById<View>(R.id.id_flow_layout) as TagFlowLayout
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
showAnim(SlideTopEnter())
|
||||
dismissAnim(SlideTopExit())
|
||||
showStandByPage()
|
||||
|
||||
id_flow_layout!!.setOnSelectListener(){
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: HomeDeviceDialog? = null
|
||||
|
||||
// @get:Synchronized
|
||||
val instance: HomeDeviceDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = HomeDeviceDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
|
||||
fun showStandByPage() {
|
||||
mStansByList.clear()
|
||||
mStansByList.addAll(ObjectBoxUtils.getAllData(DeviceInfo::class.java)!!)
|
||||
flowlayoutAdapter = object : TagAdapter<DeviceInfo>(mStansByList) {
|
||||
override fun getView(parent: FlowLayout?, position: Int, s: DeviceInfo): View? {
|
||||
val view: View = LayoutInflater.from(activity).inflate(
|
||||
R.layout.item_standby, null
|
||||
)
|
||||
var imv_stansby = view.findViewById<ImageView>(R.id.imv_stansby)
|
||||
var tv_stansby = view.findViewById<TextView>(R.id.tv_stansby)
|
||||
var tv_mark = view.findViewById<TextView>(R.id.tv_mark)
|
||||
tv_stansby.text = s.type
|
||||
imv_stansby!!.setImageResource(ToolUtil.getDJPageImage(s.type))
|
||||
if (s.isOnline) {
|
||||
tv_mark.setBackgroundResource(R.drawable.ed_yuan0fba61)
|
||||
} else {
|
||||
tv_mark.setBackgroundResource(R.drawable.ed_yuangray)
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
override fun setSelected(position: Int, s: DeviceInfo): Boolean {
|
||||
return s == s
|
||||
}
|
||||
}
|
||||
id_flow_layout!!.adapter = flowlayoutAdapter
|
||||
id_flow_layout!!.setOnTagClickListener { view, position, parent ->
|
||||
true
|
||||
}
|
||||
// if (mStansByList.isEmpty()) {
|
||||
// li_standby_background.visibility = View.GONE
|
||||
// } else {
|
||||
// li_standby_background.visibility = View.VISIBLE
|
||||
// }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,121 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.config.EventCode
|
||||
import com.qidian.zhongkesmart.utils.EventBusUtil
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.utils.WifiUtil
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import kotlinx.android.synthetic.main.activity_wi_fi.*
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
import java.util.*
|
||||
|
||||
/*输入昵称*/
|
||||
class InputNicknameDialog {
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var tv_pop_sure: TextView? = null
|
||||
var tv_woprn: TextView? = null
|
||||
var li_close: LinearLayout? = null
|
||||
var ced_pop: ClearEditText? = null
|
||||
fun getShareDialog(context: Context?, ssid:String/*,callBack: PopupYearWindowCallBack?*/) {
|
||||
activity = context
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.6f)
|
||||
dialog!!.show()
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
// EventBusUtil.register(activity)
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_input_nickname, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<View>(R.id.li_close) as LinearLayout
|
||||
ced_pop = inflate.findViewById<View>(R.id.ced_pop) as ClearEditText
|
||||
tv_woprn = inflate.findViewById<View>(R.id.tv_woprn) as TextView
|
||||
tv_pop_sure = inflate.findViewById<View>(R.id.tv_pop_sure) as TextView
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
ced_pop!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
count: Int,
|
||||
after: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
if(s!!.isNotEmpty()){
|
||||
ShowEdittextStyle(ced_pop!!, tv_woprn!!, "")
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
tv_pop_sure!!.setOnClickListener(View.OnClickListener { //请输入密码+Wi-Fi密码错误
|
||||
if (ced_pop!!.text.toString().isEmpty()) {
|
||||
ShowEdittextStyle(ced_pop!!, tv_woprn!!, "请输入密码")
|
||||
return@OnClickListener
|
||||
}
|
||||
// WifiUtil.connectWiFi(activity!!,mSsid,ced_pop!!.text.toString()!!)
|
||||
})
|
||||
li_close!!.setOnClickListener { dismiss() }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: InputNicknameDialog? = null
|
||||
|
||||
@get:Synchronized
|
||||
val instance: InputNicknameDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = InputNicknameDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
|
||||
/* @Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventBusCome(event: EventBusUtil.MessageEvent) {
|
||||
if (event != null) {
|
||||
when(event.code){
|
||||
EventCode.WIFI_CONFIRM_CONNECT -> {
|
||||
setDismiss()
|
||||
}
|
||||
EventCode.WIFI_CONFIRM_FAIL-> {
|
||||
ShowEdittextStyle(ced_pop!!, tv_woprn!!, "Wi-Fi密码错误")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.config.EventCode
|
||||
import com.qidian.zhongkesmart.utils.EventBusUtil
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.utils.WifiUtil
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import kotlinx.android.synthetic.main.activity_wi_fi.*
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
import java.util.*
|
||||
|
||||
/*输入昵称*/
|
||||
class InputThresholdDialog {
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var tv_pop_sure: TextView? = null
|
||||
var tv_woprn: TextView? = null
|
||||
var li_close: LinearLayout? = null
|
||||
var ced_pop: EditText? = null
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?) {
|
||||
activity = context
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.6f)
|
||||
dialog!!.show()
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
this.callBack = callBack
|
||||
// EventBusUtil.register(activity)
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork(roomName: String?)
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_input_threshold, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<View>(R.id.li_close) as LinearLayout
|
||||
ced_pop = inflate.findViewById<View>(R.id.ced_pop) as EditText
|
||||
tv_woprn = inflate.findViewById<View>(R.id.tv_woprn) as TextView
|
||||
tv_pop_sure = inflate.findViewById<View>(R.id.tv_pop_sure) as TextView
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
ced_pop!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
count: Int,
|
||||
after: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
if(s!!.isNotEmpty()){
|
||||
ShowEdittextStyle(ced_pop!!, tv_woprn!!, "请输入采样阈值,0-100")
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
tv_pop_sure!!.setOnClickListener(View.OnClickListener { //请输入密码+Wi-Fi密码错误
|
||||
if (ced_pop!!.text.toString().isEmpty()) {
|
||||
ShowEdittextStyle(ced_pop!!, tv_woprn!!, "请输入采样阈值,0-100")
|
||||
}else{
|
||||
callBack!!.doWork(ced_pop!!.text.toString())
|
||||
dismiss()
|
||||
}
|
||||
// WifiUtil.connectWiFi(activity!!,mSsid,ced_pop!!.text.toString()!!)
|
||||
})
|
||||
li_close!!.setOnClickListener { dismiss() }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: InputThresholdDialog? = null
|
||||
|
||||
@get:Synchronized
|
||||
val instance: InputThresholdDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = InputThresholdDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
package com.qidian.zhongkesmart.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.flyco.dialog.utils.CornerUtils
|
||||
import com.flyco.dialog.widget.base.BaseDialog
|
||||
import com.github.mikephil.charting.charts.LineChart
|
||||
import com.github.mikephil.charting.data.Entry
|
||||
import com.github.mikephil.charting.data.LineData
|
||||
import com.github.mikephil.charting.data.LineScatterCandleRadarDataSet
|
||||
import com.qidian.zhongkesmart.R
|
||||
import com.qidian.zhongkesmart.utils.ChartUtils
|
||||
import com.qidian.zhongkesmart.utils.InputLimitUtil.ShowEdittextStyle
|
||||
import com.qidian.zhongkesmart.views.ClearEditText
|
||||
import kotlinx.android.synthetic.main.layout_barchart.*
|
||||
import kotlinx.android.synthetic.main.pop_model_init_verify.*
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/*取消绑定*/
|
||||
class ModeInitVerifyDialog {
|
||||
private var callBack: PopupYearWindowCallBack? = null
|
||||
private var activity: Context? = null
|
||||
var dialog: CustomCommonDialog? = null
|
||||
var values:ArrayList<Entry>? = null
|
||||
var xValues: ArrayList<String>? = null
|
||||
// var index = 0
|
||||
var line_Chart:LineChart? = null
|
||||
fun getShareDialog(context: Context?, callBack: PopupYearWindowCallBack?,lineData: ArrayList<Entry>,xData:ArrayList<String>) {
|
||||
activity = context
|
||||
this.callBack = callBack
|
||||
values = lineData
|
||||
xValues = xData
|
||||
dialog = CustomCommonDialog(activity)
|
||||
dialog!!.widthScale(0.8f)
|
||||
dialog!!.setCanceledOnTouchOutside(false)
|
||||
dialog!!.show()
|
||||
// dialog.getWindow().setBackgroundDrawable( CornerUtils.cornerDrawable(Color.parseColor("#00000000"), dp2px(0)));
|
||||
}
|
||||
|
||||
fun setDismiss() {
|
||||
if (dialog != null && dialog!!.isShowing) {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun isShowing(): Boolean {
|
||||
return dialog != null && dialog!!.isShowing
|
||||
}
|
||||
|
||||
fun updateData(xData:ArrayList<String>,lineData: ArrayList<Entry>){
|
||||
if(isShowing()) {
|
||||
ChartUtils.initLineChart(
|
||||
line_Chart!!,
|
||||
xData!!,
|
||||
lineData!!,
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface PopupYearWindowCallBack {
|
||||
fun doWork()
|
||||
}
|
||||
|
||||
inner class CustomCommonDialog(context: Context?) : BaseDialog<CustomCommonDialog?>(context) {
|
||||
var li_close: LinearLayout? = null
|
||||
override fun onCreateView(): View {
|
||||
val inflate = View.inflate(mContext, R.layout.pop_model_init_verify, null)
|
||||
inflate.setBackgroundDrawable(
|
||||
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(10f).toFloat())
|
||||
)
|
||||
li_close = inflate.findViewById<LinearLayout>(R.id.li_close) as LinearLayout
|
||||
line_Chart = inflate.findViewById<LineChart>(R.id.linechart) as LineChart
|
||||
return inflate
|
||||
}
|
||||
|
||||
override fun setUiBeforShow() {
|
||||
li_close!!.setOnClickListener {
|
||||
callBack!!.doWork()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
ChartUtils.initLineChart(
|
||||
line_Chart!!,
|
||||
xValues!!,
|
||||
values!!,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var popupWindowPrivinceListUtils: ModeInitVerifyDialog? = null
|
||||
|
||||
// @get:Synchronized
|
||||
val instance: ModeInitVerifyDialog?
|
||||
get() {
|
||||
if (popupWindowPrivinceListUtils == null) {
|
||||
popupWindowPrivinceListUtils = ModeInitVerifyDialog()
|
||||
}
|
||||
return popupWindowPrivinceListUtils
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user