初始版本
This commit is contained in:
10
.dockerignore
Normal file
10
.dockerignore
Normal file
@ -0,0 +1,10 @@
|
||||
.devcontainer/
|
||||
.vscode/
|
||||
.idea/
|
||||
.git/
|
||||
.gitlab/
|
||||
|
||||
generated_*
|
||||
generated-*
|
||||
pb_gen/
|
||||
build/
|
||||
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@ -0,0 +1,13 @@
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{json,yml,yaml,tmpl}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.so filter=lfs diff=lfs merge=lfs -text
|
||||
237
.gitignore
vendored
237
.gitignore
vendored
@ -1,176 +1,97 @@
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
# Built application files
|
||||
*.apk
|
||||
*.aar
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
# Uncomment the following line in case you need and you don't have the release build type files in your app
|
||||
# release/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
# Log Files
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
# Android Studio Navigation editor temp files
|
||||
.navigation/
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
# Android Studio captures folder
|
||||
captures/
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
# IntelliJ
|
||||
*.iml
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/gradle.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/dictionaries
|
||||
.idea/libraries
|
||||
# Android Studio 3 in .gitignore file.
|
||||
.idea/caches
|
||||
.idea/modules.xml
|
||||
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
||||
.idea/navEditor.xml
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
# Keystore files
|
||||
# Uncomment the following lines if you do not want to check your keystore files in.
|
||||
#*.jks
|
||||
#*.keystore
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
# External native build folder generated in Android Studio 2.2 and later
|
||||
.externalNativeBuild
|
||||
.cxx/
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
# google-services.json
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
# Freeline
|
||||
freeline.py
|
||||
freeline/
|
||||
freeline_project_description.json
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
# fastlane
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
fastlane/test_output
|
||||
fastlane/readme.md
|
||||
|
||||
# UV
|
||||
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
#uv.lock
|
||||
# Version control
|
||||
vcs.xml
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
||||
.pdm.toml
|
||||
.pdm-python
|
||||
.pdm-build/
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
# Ruff stuff:
|
||||
.ruff_cache/
|
||||
|
||||
# PyPI configuration file
|
||||
.pypirc
|
||||
# lint
|
||||
lint/intermediates/
|
||||
lint/generated/
|
||||
lint/outputs/
|
||||
lint/tmp/
|
||||
# lint/reports/
|
||||
|
||||
# Android Profiling
|
||||
*.hprof
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
.idea
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
/local
|
||||
3
.gitlab-ci.yml
Normal file
3
.gitlab-ci.yml
Normal file
@ -0,0 +1,3 @@
|
||||
include:
|
||||
- project: "infra/gitlab-cicd"
|
||||
file: "/templates/global.yml"
|
||||
8
.gitlab/CODEOWNERS
Normal file
8
.gitlab/CODEOWNERS
Normal file
@ -0,0 +1,8 @@
|
||||
^[default] @group
|
||||
*
|
||||
|
||||
[CODEOWNERS][1] @org/codeowner-dev
|
||||
CODEOWNERS
|
||||
|
||||
[LICENSE][1] @org/legal-dev
|
||||
LICENSE
|
||||
28
.gitlab/LICENSE
Normal file
28
.gitlab/LICENSE
Normal file
@ -0,0 +1,28 @@
|
||||
# 闭源商业代码使用协议(非开源部分代码的引用和接口调用)
|
||||
|
||||
欢迎使用本闭源商业代码,为了确保您和我们共同遵守法律和条款,请在使用之前仔细阅读以下协议。如果您不同意本协议的任何内容,请勿使用该代码。
|
||||
|
||||
1. 版权所有
|
||||
本代码是由 中科海微 开发并拥有版权。未经许可,您无权复制、修改、分发或出售本代码的任何部分。
|
||||
|
||||
2. 授权范围
|
||||
在遵守本协议的前提下,中科海微 授予您对本代码的有限和非排他使用权限。您可以将本代码集成到您的商业产品中,并通过您的商业产品向最终用户提供服务。
|
||||
|
||||
3. 限制与禁止
|
||||
您被授权使用本代码,但是不得进行以下行为:
|
||||
- 对本代码进行逆向工程、反编译或尝试获取源代码;
|
||||
- 删除本代码中的任何版权声明、标记或其他明示或暗示的所有权信息;
|
||||
- 利用本代码直接或间接参与非法活动;
|
||||
- 将本代码用于政治目的、色情目的,或用于违反法律法规的任何目的。
|
||||
|
||||
4. 免责声明
|
||||
本代码按“原样”提供,没有任何明示或暗示的保证或条件。您对使用本代码所造成的风险自行承担。中科海微 不承担与本代码使用相关的任何责任。
|
||||
|
||||
5. 协议终止
|
||||
如您违反了本协议的任何规定,中科海微 有权随时终止您使用本代码的权限。在终止后,您必须立即停止使用本代码。
|
||||
|
||||
6. 法律适用和管辖
|
||||
本协议受中华人民共和国法律管辖,并在中华人民共和国境内解释执行。
|
||||
|
||||
7. 协议修改
|
||||
中科海微 有权根据需要随时修改本协议的内容。修改后的协议将在官方网站上公布,您应及时查阅最新版本。
|
||||
97
README.md
97
README.md
@ -1,5 +1,96 @@
|
||||
# TJ-android
|
||||
# Code Project Template
|
||||
|
||||
贴件仓库
|
||||
|
||||
我的
|
||||
|
||||
## Getting started
|
||||
|
||||
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||
|
||||
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||
|
||||
## Update CODEOWNERS
|
||||
- [ ] [Update the owner of default section to parent group](https://docs.gitlab.com/ee/user/project/codeowners/)
|
||||
|
||||
## Add your files
|
||||
|
||||
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
||||
|
||||
```
|
||||
cd existing_repo
|
||||
git remote add origin https://git.seawayos.com/template/code-project-template.git
|
||||
git branch -M main
|
||||
git push -uf origin main
|
||||
```
|
||||
|
||||
## Integrate with your tools
|
||||
|
||||
- [ ] [Set up project integrations](https://git.seawayos.com/template/code-project-template/-/settings/integrations)
|
||||
|
||||
## Collaborate with your team
|
||||
|
||||
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
||||
|
||||
## Test and Deploy
|
||||
|
||||
Use the built-in continuous integration in GitLab.
|
||||
|
||||
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
||||
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||
|
||||
***
|
||||
|
||||
# Editing this README
|
||||
|
||||
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||
|
||||
## Suggestions for a good README
|
||||
|
||||
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||
|
||||
## Name
|
||||
Choose a self-explaining name for your project.
|
||||
|
||||
## Description
|
||||
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||
|
||||
## Badges
|
||||
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||
|
||||
## Visuals
|
||||
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||
|
||||
## Installation
|
||||
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||
|
||||
## Usage
|
||||
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||
|
||||
## Support
|
||||
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
||||
|
||||
## Roadmap
|
||||
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||
|
||||
## Contributing
|
||||
State if you are open to contributions and what your requirements are for accepting them.
|
||||
|
||||
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||
|
||||
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||
|
||||
## Authors and acknowledgment
|
||||
Show your appreciation to those who have contributed to the project.
|
||||
|
||||
## License
|
||||
For open source projects, say how it is licensed.
|
||||
|
||||
## Project status
|
||||
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user