-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 4cbfae796640074ce2b503e0c889703e9b342a1f..0000000000000000000000000000000000000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460d8b38ac04e3a3224d7c79ef719b1991a9..0000000000000000000000000000000000000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7f4cb416c083d265558da75d457237d671..0000000000000000000000000000000000000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Bluetooth-LE-Library---Android.iml b/Bluetooth-LE-Library---Android.iml
deleted file mode 100644
index dcc509866aea4ca418caaaa53ecafd316a2c0422..0000000000000000000000000000000000000000
--- a/Bluetooth-LE-Library---Android.iml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index e03ed2f425f5fcff4fb057ef03b87bceceb851bb..ae607f42d0b7f6756d0fb4e81a3618018a61881a 100644
--- a/README.md
+++ b/README.md
@@ -1,173 +1,126 @@
-# Bluetooth LE Library for Android
-
-This library allows for easy access to a Bluetooth LE device's Advertisement Records.
-It also offers:
-
-* A simple running average RSSI reading keeping.
-* For iBeacons: Manufacturer data record parser.
-* For iBeacons: Distance indicators (Near, Far, Immediate, Unknown).
-* For iBeacons: A decently inaccurate (due to real world issues) distance approximation.
-* All the new object types are Parcelable.
-
-This will only work on devices with Android 4.3 (API Level 18) and above.
-
-
-
-
-
-## Including the Library in Your Project
-
-This project is available as an artifact for use with Gradle. To use that, add the following blocks to your build.gradle file:
-```groovy
- repositories {
- maven {
- url "https://dl.bintray.com/alt236/maven"
- }
- }
-
- dependencies {
- compile 'uk.co.alt236:bluetooth-le-library-android:1.0.0'
- }
+# Bluetooth_LE_Library
+
+**本项目基于开源项目Bluetooth_LE_Library 进行openharmony化的移植和开发,可以通过项目标签以及github地址( https://github.com/alt236/Bluetooth-LE-Library---Android )追踪到原项目版本**
+
+#### 项目介绍
+- 项目名称:该库可轻松访问Bluetooth LE设备的AdRecord和RSSI值。
+- 所属系列:openharmony的第三方组件适配移植
+- 功能:该库可轻松访问Bluetooth LE设备的AdRecord和RSSI值。它为iBeacons提供了其他功能。
+- 基线版本: Bluetooth_LE_Library Tags 1.1.1
+- 项目移植状态:主功能完成
+- 调用差异:无
+- 开发版本:sdk5,DevEco Studio2.1 beta4
+- 原项目Doc地址:https://github.com/alt236/Bluetooth-LE-Library---Android
+
+#### 效果演示
+
+
+
+
+
+
+#### 安装教程
+
+1.在项目根目录下的build.gradle文件中,
+ ```
+ allprojects {
+ repositories {
+ maven {
+ url 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
+ }
+ }
+ }
```
-If you *really* need a Jar file, fork the project and execute `./gradlew clean build generateRelease` at the root of the project.
-This will create a zip file under `/library/build/` the Jar can be found inside.
-
-## Using the Library
-In the `onLeScan()` method of your `BluetoothAdapter.LeScanCallback()` create a new BluetoothLeDevice with the given information.
-
-For example:
-
-```java
- private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
-
- @Override
- public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
-
- final BluetoothLeDevice deviceLe = new BluetoothLeDevice(device, rssi, scanRecord, System.currentTimeMillis());
-
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mDeviceStore.addDevice(deviceLe);
- mLeDeviceListAdapter.replaceData(mDeviceStore.getDeviceList());
- }
-
- });
- }
- };
+2.在entry模块的build.gradle文件中,
+ ```
+ dependencies {
+ implementation('com.gitee.chinasoft_ohos:Bluetooth_LE_Library:0.0.1-SNAPSHOT')
+ ......
+ }
```
-### Device Properties
+#### 使用说明
-Once you have created a device, you can access the following methods:
+1、您将需要以下权限来访问蓝牙硬件:
-* `getAddress()` : Gets the MAC Address of the device
-* `getAdRecordStore()`: Gives access to a device's Ad Records
-* `getDevice()`: Gives access to the standard BluetoothDevice object
-* `getFirstRssi()`: Retrieves the RSSI value which was used when the object was created
-* `getFirstTimestamp()` Retrieves the timestamp (in millis) which was used when the object was created
-* `getRssi()` Gets the current RSSI measurement (see note below).
-* `getScanRecord()` Retrieves the RAW scan record array
-* `getTimestamp()` Gets the timestamp of the last RSSI measurement
-* `getRunningAverageRssi()` Retrieves the internally calculated running average RSSI value (see note below).
+* `ohos.permission.USE_BLUETOOTH`
+* `ohos.permission.LOCATION`
+* `ohos.permission.DISCOVER_BLUETOOTH`
+2、在MainAbilitySlice中获取蓝牙本机管理对象,并设置回调监听。
+```
+// 获取蓝牙本机管理对象
+BluetoothHost bluetoothHost = BluetoothHost.getDefaultHost(this);
+bluetoothHost.enableBt();
+ScanCallback centralManagerCallback = new ScanCallback();
+BleCentralManager centralManager = new BleCentralManager(this, centralManagerCallback);
+```
+3、开始扫描蓝牙设备,并在回调里面获取扫描到蓝牙数据
+```
+List filters = new ArrayList<>();
+centralManager.startScan(filters);
+
+public class ScanCallback implements BleCentralManagerCallback {
+ List results = new ArrayList<>();
+
+ @Override
+ public void scanResultEvent(BleScanResult resultCode) {
+ // 对扫描结果进行处理
+ results.add(resultCode);
+ int rssi = resultCode.getRssi();
+ byte[] scanRecord = resultCode.getRawData();
+ BluetoothLeDevice deviceLe = new BluetoothLeDevice(resultCode,
+ rssi, scanRecord, System.currentTimeMillis());
+ getUITaskDispatcher().asyncDispatch(() -> {
+ for (int index = 0; index < listDevice.size(); index++) {
+ if (deviceLe.getAddress().equals(listDevice.get(index).getAddress())) {
+ BluetoothLeDevice item = listDevice.get(index);
+ item.updateRssiReading(System.currentTimeMillis(), rssi);
+ return;
+ }
+ }
+ });
+ }
+
+ @Override
+ public void scanFailedEvent(int resultCode) {
+ }
+
+ @Override
+ public void groupScanResultsEvent(List list) {
+ }
+ }
+```
-**Note:** The Running Average RSSI is not updated automatically (i.e. the library does not monitor on its own in the background). To add another measurement, you need to call `updateRssiReading(long timestamp, int rssiReading)`.
+支持功能:
+```
+* getAddress() : Gets the MAC Address of the device
+* getAdRecordStore(): Gives access to a device's Ad Records
+* getDevice(): Gives access to the standard BluetoothDevice object
+* getFirstRssi(): Retrieves the RSSI value which was used when the object was created
+* getFirstTimestamp() : Retrieves the timestamp (in millis) which was used when the object was created
+* getRssi() : Gets the current RSSI measurement (see note below).
+* getScanRecord() : Retrieves the RAW scan record array
+* getTimestamp() : Gets the timestamp of the last RSSI measurement
+* getRunningAverageRssi() : Retrieves the internally calculated running average RSSI value (see note below).
+```
+#### 测试信息
-### Accessing the Advertisement (Ad) Records
+CodeCheck代码测试无异常
-Once you've created a BluetoothLe device, you can access the AdRecord store via the `leDevice.getAdRecordStore()`. Once you have the AdRecordStore you can use the following methods:
+CloudTest代码测试无异常
-* `getRecord(int recordNo)`: Gets the AdRecord object corresponding to the recordNumber.
-* `getRecordDataAsString(int recordNo)` : Gets the AdRecord contents as a String (expect non printable characters in most cases).
-* `isRecordPresent(int recordNo)`: Checks to see if a record exists.
+火绒安全病毒安全检测通过
-**Note:** Record numbers are declared in the Bluetooth 4 spec which can be found [here](https://developer.bluetooth.org/TechnologyOverview/Pages/core-specification.aspx).
-They are also declared as constants in `AdRecord.java`.
+当前版本demo功能与原组件基本无差异
-### Fun with iBeacons
-You can check if a device is an iBeacon by using `BeaconUtils.getBeaconType(BluetootLeDevice device)`. Once you have confirmed that it is, you can create a new IBeaconDevice via the IBeaconDevice constructor.
+#### 版本迭代
-Example Flow:
-```java
- final BluetoothLeDevice device = ... // A generic BLE device
+- 0.0.1-SNAPSHOT
- if (BeaconUtils.getBeaconType(device) == BeaconType.IBEACON) {
- final IBeaconDevice iBeacon = new IBeaconDevice(device);
- // DO STUFF
- }
+#### 版权和许可信息
```
-
-An IBeaconDevice extends BluetoothLeDevice, so you still have access to the same methods as before. In addition you can do the following:
-
-* `getAccuracy()`: Gets the estimated Accuracy of the reading in meters based on a simple running average calculation
-* `getCalibratedTxPower()`: Gets the calibrated TX power of the iBeacon device as reported
-* `getCompanyIdentifier()`: Gets the iBeacon company identifier (this should always be 0x004C for Apple)
-* `getDistanceDescriptor()`: Gets the estimated Distance descriptor (an enum)
-* `getIBeaconData()`: Gets the raw IBeaconManufacturerData object.
-* `getUUID()`: Gets the device's UUID
-* `getMajor()`: Gets the device's Major value
-* `getMinor()`: Gets the device's Minor value
-
-
-### Lookup Functions
-You can also lookup values and convert them to human friendly strings:
-* `BluetoothClassResolver.resolveDeviceClass(int btClass)`: Will try to resolve a Blueotooth Device class
-* `CompanyIdentifierResolver.getCompanyName(int companyId, String fallback)`: Will try to resolve a Company identifier to the company name
-* `GattAttributeResolver.getAttributeName(String uuid, String fallback)`: Will try to convert a UUID to its name.
-
-**Note:** The data can be found as ODS (Open Office Spreadsheets) in the documents folder.
-
-## Library Changelog
-* v0.0.1
- * First public release
-* v0.0.2:
- * Attempting to create an iBeaconDevice from a device which is not an iBeacon will now throw an IllegalArgumentException exception.
- * Fixed a ConcurrentModificationException on getRunningAverageRssi()
- * Added some Estimote UUIDs
-* v1.0.0:
- * Migrated project to Android Studio/ gradle
- * Note that the API has slightly changed in this version.
- * We now use the more generic `BeaconUtils.getBeaconType()` method instead of `IBeaconUtils.isThisAnIBeacon()`
- * Fix for [issue 5](https://github.com/alt236/Bluetooth-LE-Library---Android/issues/5)
- * Fix for [issue 9](https://github.com/alt236/Bluetooth-LE-Library---Android/issues/9)
-
-## Sample Application Changelog
-* v0.0.1
- * First public release
-* v0.0.2:
- * Can now export scanned devices as a CSV file.
-* v0.0.3:
- * UI Refresh.
-* v1.0.0:
- * Migrated project to Android Studio/ gradle
- * Using version v1.0.0 of the library project
-* v1.1.0:
- * App refactor and materialisation.
- * Added runtime permissions.
-* v1.1.1:
- * Fix for [issue 23](https://github.com/alt236/Bluetooth-LE-Library---Android/issues/23)
-
-## Permission Explanation
-You will need the following permissions to access the Bluetooth Hardware
-
-* `android.permission.BLUETOOTH`
-* `android.permission.BLUETOOTH_ADMIN`
-
-In addition one of the following is needed from API 23 and above to scan for BT LE devices:
-* `android.permission.ACCESS_COARSE_LOCATION`
-* `android.permission.ACCESS_FINE_LOCATION `
-
-## TODO
-
-* Tidy up Javadoc. There is quite a lot of it that is template
-* Add parsers for common Ad Records.
-
-## Links
-* Github: [https://github.com/alt236/Bluetooth-LE-Library---Android]()
-
-## Credits
Author: [Alexandros Schillings](https://github.com/alt236).
* The Accuracy calculation algorithm was taken from: http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing
@@ -180,3 +133,4 @@ All logos are the property of their respective owners.
The code in this project is licensed under the Apache Software License 2.0.
Copyright (c) 2014-2017 Alexandros Schillings.
+```
\ No newline at end of file
diff --git a/apkdetails.sh b/apkdetails.sh
deleted file mode 100755
index 4645013fcc81f373999bb26767badec91f18a04d..0000000000000000000000000000000000000000
--- a/apkdetails.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-set -e
-set -o xtrace
-java -jar ./buildsystem/apkdetails/apkdetails-1.2.2.jar "$@"
-set +o xtrace
\ No newline at end of file
diff --git a/bluetooth-le-library.iml b/bluetooth-le-library.iml
deleted file mode 100644
index 1bf2c6ac737c0715231052ac01adad006bd6872e..0000000000000000000000000000000000000000
--- a/bluetooth-le-library.iml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index d571eb4c9b77766cd1ae8e7597113b592cac92d3..e83d0d6537187b1b6e318c86d0e7c3760f71c6e7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,43 +1,40 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
-buildscript {
- apply from: "${project.rootDir}/buildconstants/android-sdk-versions.gradle"
- apply from: "${project.rootDir}/buildconstants/dependency-versions.gradle"
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+buildscript {
repositories {
- google()
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
jcenter()
}
-
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.3'
- classpath 'com.novoda:bintray-release:0.9.2'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.huawei.ohos:hap:2.4.2.7'
+ classpath 'com.huawei.ohos:decctest:1.0.0.6'
}
}
allprojects {
repositories {
- google()
- mavenCentral()
- jcenter()
- }
-
- tasks.withType(Test) {
- testLogging {
- exceptionFormat "full"
- showCauses true
- showExceptions true
- showStackTraces true
- showStandardStreams true
- events = ["passed", "skipped", "failed"]
-
- // This line is left here to make test debugging easier
- // events = ["passed", "skipped", "failed", "standardError", "standardOut"]
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
}
+ maven {
+ url 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
+ }
+ jcenter()
}
-
- apply from: "${project.rootDir}/buildconstants/android-sdk-versions.gradle"
- apply from: "${project.rootDir}/buildconstants/dependency-versions.gradle"
- apply from: "${project.rootDir}/buildsystem/common-methods.gradle"
}
diff --git a/buildconstants/android-sdk-versions.gradle b/buildconstants/android-sdk-versions.gradle
deleted file mode 100644
index 7fcddc7f3141d01e29e02f67ad4cebabb2df9a6a..0000000000000000000000000000000000000000
--- a/buildconstants/android-sdk-versions.gradle
+++ /dev/null
@@ -1,7 +0,0 @@
-ext {
- min_sdk_version = 18
- target_sdk_version = 29
- compile_sdk_version = 29
- build_tools_version = "28.0.3"
- kotlin_version = '1.3.60'
-}
\ No newline at end of file
diff --git a/buildconstants/dependency-versions.gradle b/buildconstants/dependency-versions.gradle
deleted file mode 100644
index 30ec5e5bdbcc8124fc772c19073157890f2fca4b..0000000000000000000000000000000000000000
--- a/buildconstants/dependency-versions.gradle
+++ /dev/null
@@ -1,33 +0,0 @@
-ext {
- // androidx libraries
- androidx_appcompat_version = "1.1.0"
- androidx_annotation_version = "1.1.0"
- androidx_espresso_core_version = "3.1.0"
- androidx_legacy_v4 = "1.0.0"
- androidx_lifecycle_version = "2.1.0"
- androidx_room_version = "2.2.0"
- androidx_core_ktx = "1.1.0"
- androidx_preferences = "1.1.0"
-
- androidx_contraint_layout_version = "1.1.3"
- androidx_recyclerview = "1.1.0"
-
- androidx_test_core_version = "1.1.0"
- androidx_test_ext_junit_version = "1.0.0"
- androidx_test_runner_version = "1.1.1"
- androidx_test_rules_version = "1.1.1"
-
- // testing
- mockito_version = "2.13.0"
- mockito_kotlin_version = "2.1.0"
- junit_version = "4.12"
-
- // code quality
- jacoco_version = "0.8.5"
-
- // Other
- osmdroid_version = "6.1.2"
- material_intro_screen_version = "0.0.6"
- butterknife_version = "10.2.1"
- grant_permissions_version = "1.1.2"
-}
diff --git a/buildsystem/android-defaults.gradle b/buildsystem/android-defaults.gradle
deleted file mode 100644
index 2158b83619e287cb6a4a714bca46289107a05b6a..0000000000000000000000000000000000000000
--- a/buildsystem/android-defaults.gradle
+++ /dev/null
@@ -1,119 +0,0 @@
-// The versions are defined in "${project.rootDir}/buildconstants/android-sdk-versions.gradle"
-apply plugin: 'jacoco'
-
-jacoco {
- toolVersion = jacoco_version
-}
-
-android {
- compileSdkVersion compile_sdk_version
- buildToolsVersion build_tools_version
-
- defaultConfig {
- minSdkVersion min_sdk_version
- targetSdkVersion target_sdk_version
-
- multiDexEnabled false
- multiDexKeepProguard file("${project.rootDir}/buildsystem/multidex/multidex.pro")
-
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- consumerProguardFiles 'consumer-rules.pro'
- }
-
- buildTypes {
- release {
- minifyEnabled true
- testCoverageEnabled false
-
- // PROGUARD
- def proguardRuleFiles = collectCommonProguardRules()
- proguardRuleFiles.add(0, getDefaultProguardFile('proguard-android.txt'))
- proguardRuleFiles.add(1, 'proguard-rules.pro')
- logger.warn("Common proguard files: $proguardRuleFiles")
-
- proguardFiles proguardRuleFiles.toArray()
- }
-
- debug {
- minifyEnabled false
- testCoverageEnabled true
-
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-
- lintOptions {
- lintConfig file("${project.rootDir}/buildsystem/codequality/lint.xml")
- }
-
- testOptions {
- execution 'ANDROIDX_TEST_ORCHESTRATOR'
- animationsDisabled = true
-
- unitTests {
- //returnDefaultValues = true
- includeAndroidResources = true
- }
- }
-
- aaptOptions {
- noCompress 'zip'
- }
-}
-
-task jacocoTestReport2(type: JacocoReport) {
-
- reports {
- xml.enabled = true
- html.enabled = true
- }
-
- def fileFilter = ['jdk.internal.*',
- 'android/**/*.*',
- '**/R.class',
- '**/R$*.class',
- '**/BuildConfig.*',
- '**/Manifest*.*',
- '**/*Test*.*',
- '**/*$ViewInjector*.*',
- '**/*$ViewBinder*.*',
- // DAGGER 2
- '**/*_*Factory*.*',
- '**/*_MembersInjector*.*',
- '**/*_MembersInjector.class',
- '**/*Module*.*',
- '**/Dagger*Component$Builder.class',
- '**/Dagger*Component*.*']
-
- def mainSrc = "$project.projectDir/src/main/java"
-
- def javaClasses = fileTree(
- dir: "$buildDir/intermediates/classes/",
- excludes: fileFilter
- )
-
- def kotlinClasses = fileTree(
- dir: "$buildDir/tmp/kotlin-classes/",
- excludes: fileFilter
- )
-
- classDirectories = files([ javaClasses ], [ kotlinClasses ])
- sourceDirectories = files(mainSrc)
- executionData = fileTree(dir: "$buildDir",
- includes: ['jacoco/*.exec', 'connected/*.ec']
- )
-
- reports {
- xml.enabled = true
- html.enabled = true
- }
-}
-
-tasks.withType(Test) {
- jacoco.includeNoLocationClasses = false
-}
diff --git a/buildsystem/apkdetails/apkdetails-1.2.2.jar b/buildsystem/apkdetails/apkdetails-1.2.2.jar
deleted file mode 100644
index d8a2af5b7b1621380ff2f34731ad2abee556a6f7..0000000000000000000000000000000000000000
Binary files a/buildsystem/apkdetails/apkdetails-1.2.2.jar and /dev/null differ
diff --git a/buildsystem/codequality/lint.xml b/buildsystem/codequality/lint.xml
deleted file mode 100644
index ddbbe9219170895865dc137b1c865da77bad5205..0000000000000000000000000000000000000000
--- a/buildsystem/codequality/lint.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/buildsystem/common-methods.gradle b/buildsystem/common-methods.gradle
deleted file mode 100644
index 9d1ab3f4262fa92d8ccac1c170368de2e9d2dbb5..0000000000000000000000000000000000000000
--- a/buildsystem/common-methods.gradle
+++ /dev/null
@@ -1,93 +0,0 @@
-def execGitHashShort() {
- return cleanString('git rev-parse --short HEAD'.execute().text)
-}
-
-def execGitHash() {
- return cleanString('git rev-parse HEAD'.execute().text)
-}
-
-def execGitBranch() {
- return cleanString('git show -s --pretty=%d HEAD'.execute().text)
-}
-
-def execGitCommitDate() {
- final String cmd = "git show -s --format=%ci " + this.execGitHash()
- return cleanString(cmd.execute().text)
-}
-
-def execGitLog(int items) {
- final String cmd = "git log -n " + items + " --abbrev-commit --pretty=oneline"
- return cmd.execute().text
-}
-
-def getBuildNumber() {
- def buildNumberVariable = "CIRCLE_BUILD_NUM"
- def buildNumberValue = System.getenv(buildNumberVariable)
-
- if (buildNumberValue != null && !buildNumberValue.isEmpty()) {
- return buildNumberValue as Integer
- } else {
- return 1
- }
-}
-
-def isRunningOnCi() {
- def envVariable = "CI"
- return Boolean.parseBoolean(System.getenv(envVariable) ?: "false")
-}
-
-def cleanString(final String text) {
- return text.trim().replaceAll('/', '_').replaceAll('-', '_')
-}
-
-def quoteString(final String str) {
- final String quote = "\""
-
- if (str.length() > 0) {
- if (str.startsWith(quote) && str.endsWith(quote)) {
- return str
- } else {
- return quote + str + quote
- }
- } else {
- return quote + quote
- }
-}
-
-
-
-def getLastGitCommitMessage() {
- return 'git log -1 --pretty=%B'.execute().text.trim()
-}
-
-def collectCommonProguardRules() {
- def proguardFileDirectory = "${project.rootDir}/buildsystem/proguard-rules/"
-
- def proguardFileSet = fileTree(proguardFileDirectory).filter { it.isFile() }.files
- if(proguardFileSet.isEmpty()) {
- throw new IllegalStateException("No proguard rules found in $proguardFileDirectory")
- }
-
- return proguardFileSet.toList().sort()
-}
-
-
-def getPropertySafe(prop, fallback) {
- rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
-}
-
-ext {
- execGitHashShort = this.&execGitHashShort
- execGitHash = this.&execGitHash
- execGitBranch = this.&execGitBranch
- execGitCommitDate = this.&execGitCommitDate
- execGitLog = this.&execGitLog
- isRunningOnCi = this.&isRunningOnCi
- getLibVersions = this.&getLibVersions
- quoteString = this."eString
- getBuildNumber = this.&getBuildNumber
- getLastGitCommitMessage = this.&getLastGitCommitMessage
- shouldSkipFlakyRobolectricTests = this.&shouldSkipFlakyRobolectricTests
- collectCommonProguardRules = this.&collectCommonProguardRules
- getPropertySafe = this.&getPropertySafe
-}
\ No newline at end of file
diff --git a/buildsystem/generate_dependency_hashfile.sh b/buildsystem/generate_dependency_hashfile.sh
deleted file mode 100755
index 57f5db9079d6fbd1a222543c38e8ae7e2b61c8c5..0000000000000000000000000000000000000000
--- a/buildsystem/generate_dependency_hashfile.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-#
-# This script scans the directory passed as the first parameter and hashes all gradlefiles it finds/
-# It then outputs the hashes into the file passed as the second parameter
-#
-
-SOURCE_DIR=$1
-HASH_FILE=$2
-REGEX_PATTERN_GRADLE="*\.gradle"
-REGEX_PATTERN_ROBOLECTRIC="*robolectric.properties"
-
-find ${SOURCE_DIR} -type f \( -iname "$REGEX_PATTERN_GRADLE" -o -iname "$REGEX_PATTERN_ROBOLECTRIC" \) -exec md5sum {} \; | sort -k2 -b > ${HASH_FILE}
-
diff --git a/buildsystem/jacocoxml/jacocoxmlparser-1.0.0.jar b/buildsystem/jacocoxml/jacocoxmlparser-1.0.0.jar
deleted file mode 100644
index b553f20b3a19f5cb4acca7e0193695172b40ee36..0000000000000000000000000000000000000000
Binary files a/buildsystem/jacocoxml/jacocoxmlparser-1.0.0.jar and /dev/null differ
diff --git a/buildsystem/multidex/multidex.pro b/buildsystem/multidex/multidex.pro
deleted file mode 100644
index a6aa9480d616f3a972852293344c76607249f47c..0000000000000000000000000000000000000000
--- a/buildsystem/multidex/multidex.pro
+++ /dev/null
@@ -1,2 +0,0 @@
--keep class **Test { *; }
--keep class **Module { *; }
\ No newline at end of file
diff --git a/buildsystem/proguard-rules/dagger2-rules.pro b/buildsystem/proguard-rules/dagger2-rules.pro
deleted file mode 100644
index e5480eea7d2f75c424f61ed0258171dae7b5cdb6..0000000000000000000000000000000000000000
--- a/buildsystem/proguard-rules/dagger2-rules.pro
+++ /dev/null
@@ -1 +0,0 @@
--dontwarn com.google.errorprone.annotations.**
\ No newline at end of file
diff --git a/buildsystem/proguard-rules/gson-rules.pro b/buildsystem/proguard-rules/gson-rules.pro
deleted file mode 100644
index c50ceb0c606e8374862959da5fbcb158eb3205f6..0000000000000000000000000000000000000000
--- a/buildsystem/proguard-rules/gson-rules.pro
+++ /dev/null
@@ -1,24 +0,0 @@
-# Source: https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg
-
-##---------------Begin: proguard configuration for Gson ----------
-# Gson uses generic type information stored in a class file when working with fields. Proguard
-# removes such information by default, so configure it to keep all of it.
--keepattributes Signature
-
-# For using GSON @Expose annotation
--keepattributes *Annotation*
-
-# Gson specific classes
--dontwarn sun.misc.**
-#-keep class com.google.gson.stream.** { *; }
-
-# Application classes that will be serialized/deserialized over Gson
--keep class com.google.gson.examples.android.model.** { *; }
-
-# Prevent proguard from stripping interface information from TypeAdapterFactory,
-# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
--keep class * implements com.google.gson.TypeAdapterFactory
--keep class * implements com.google.gson.JsonSerializer
--keep class * implements com.google.gson.JsonDeserializer
-
-##---------------End: proguard configuration for Gson ----------
\ No newline at end of file
diff --git a/buildsystem/proguard-rules/kotlin-rules.pro b/buildsystem/proguard-rules/kotlin-rules.pro
deleted file mode 100644
index d595cdc4cf1042e03777e7e0abbcd1f1303901a1..0000000000000000000000000000000000000000
--- a/buildsystem/proguard-rules/kotlin-rules.pro
+++ /dev/null
@@ -1,2 +0,0 @@
--keep class kotlin.reflect.jvm.internal.** { *; }
--keep class kotlin.Metadata { *; }
\ No newline at end of file
diff --git a/buildsystem/signing_keys/debug.keystore b/buildsystem/signing_keys/debug.keystore
deleted file mode 100644
index 3a4172f54d5e27ebaa5490f7215d54b0b64d5d8c..0000000000000000000000000000000000000000
Binary files a/buildsystem/signing_keys/debug.keystore and /dev/null differ
diff --git a/circle.yml b/circle.yml
deleted file mode 100644
index 23d13c5452061fd73289a0856cb3fa0bf28ead1f..0000000000000000000000000000000000000000
--- a/circle.yml
+++ /dev/null
@@ -1,7 +0,0 @@
- test:
- override:
- - (echo "Running JUnit tests!")
- - ./gradlew test -PdisablePreDex
- post:
- - mkdir -p $CIRCLE_TEST_REPORTS/junit/
- - find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
diff --git a/dist/BluetoothLeLibrary-0.0.1-javadoc.jar b/dist/BluetoothLeLibrary-0.0.1-javadoc.jar
deleted file mode 100644
index e0e1a58af61a65749b46abb7740368f515ced890..0000000000000000000000000000000000000000
Binary files a/dist/BluetoothLeLibrary-0.0.1-javadoc.jar and /dev/null differ
diff --git a/dist/BluetoothLeLibrary-0.0.1.jar b/dist/BluetoothLeLibrary-0.0.1.jar
deleted file mode 100644
index d660473ddb33b87024d71547b3e57581a5ba3fcc..0000000000000000000000000000000000000000
Binary files a/dist/BluetoothLeLibrary-0.0.1.jar and /dev/null differ
diff --git a/documents/Bluetooth_UUIDs.ods b/documents/Bluetooth_UUIDs.ods
deleted file mode 100644
index 1ff67fa3564449ad83033d3ec0ccf9cf81738c25..0000000000000000000000000000000000000000
Binary files a/documents/Bluetooth_UUIDs.ods and /dev/null differ
diff --git a/documents/COMPANY_IDENTIFIERS.ods b/documents/COMPANY_IDENTIFIERS.ods
deleted file mode 100644
index ce7f86cdb294a51b28a636647863654ca02e190e..0000000000000000000000000000000000000000
Binary files a/documents/COMPANY_IDENTIFIERS.ods and /dev/null differ
diff --git a/sample_app/.gitignore b/entry/.gitignore
similarity index 100%
rename from sample_app/.gitignore
rename to entry/.gitignore
diff --git a/entry/build.gradle b/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5a04d972dc55df408b95c75947b3ebccf52f9ecf
--- /dev/null
+++ b/entry/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.huawei.ohos.hap'
+apply plugin: 'com.huawei.ohos.decctest'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testImplementation 'junit:junit:4.13'
+ ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100'
+ compile project(":library")
+}
+decc {
+ supportType = ['html','xml']
+}
diff --git a/entry/proguard-rules.pro b/entry/proguard-rules.pro
new file mode 100644
index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a
--- /dev/null
+++ b/entry/proguard-rules.pro
@@ -0,0 +1 @@
+# config module specific ProGuard rules here.
\ No newline at end of file
diff --git a/entry/src/main/config.json b/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..4a70fa9d2f1b2ae7270dba8d133564e8d175ff93
--- /dev/null
+++ b/entry/src/main/config.json
@@ -0,0 +1,109 @@
+{
+ "app": {
+ "bundleName": "me.jagar.chatvoiceplayerlibrary",
+ "vendor": "co",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "uk.co.alt236.btlescan",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.USE_BLUETOOTH",
+ "reason": "reason",
+ "usedScene": {
+ "ability": [
+ "uk.co.alt236.btlescan"
+ ],
+ "when": "always"
+ }
+ },
+ {
+ "name": "ohos.permission.LOCATION",
+ "reason": "reason",
+ "usedScene": {
+ "ability": [
+ "uk.co.alt236.btlescan"
+ ],
+ "when": "always"
+ }
+ },
+ {
+ "name": "ohos.permission.DISCOVER_BLUETOOTH",
+ "reason": "reason",
+ "usedScene": {
+ "ability": [
+ "uk.co.alt236.btlescan"
+ ],
+ "when": "always"
+ }
+ },
+ {
+ "name": "ohos.permission.COMMONEVENT_STICKY",
+ "reason": "reason",
+ "usedScene": {
+ "ability": [
+ "uk.co.alt236.btlescan"
+ ],
+ "when": "always"
+ }
+ },
+ {
+ "name": "ohos.abilitydemo.permission.PROVIDER",
+ "reason": "reason",
+ "usedScene": {
+ "ability": [
+ "uk.co.alt236.btlescan"
+ ],
+ "when": "always"
+ }
+ }
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "uk.co.alt236.btlescan.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "extra": "",
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar"
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/uk/co/alt236/btlescan/MainAbility.java b/entry/src/main/java/uk/co/alt236/btlescan/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..063ce966f8e9dd192291985dc5721ed702e7184c
--- /dev/null
+++ b/entry/src/main/java/uk/co/alt236/btlescan/MainAbility.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package uk.co.alt236.btlescan;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import uk.co.alt236.btlescan.slice.MainAbilitySlice;
+
+/**
+ * MainAbility
+ *
+ * @author ljx
+ * @since 2021-04-29
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+
+ requestPermissionsFromUser(new String[] {"ohos.permission.USE_BLUETOOTH",
+ "ohos.permission.LOCATION",
+ "ohos.permission.DISCOVER_BLUETOOTH" }, 1);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/uk/co/alt236/btlescan/MyApplication.java b/entry/src/main/java/uk/co/alt236/btlescan/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6b8a883c4bf9f72b721563ce78df8664a373431
--- /dev/null
+++ b/entry/src/main/java/uk/co/alt236/btlescan/MyApplication.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package uk.co.alt236.btlescan;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * MyApplication
+ *
+ * @author MyApplication
+ * @since 2021-04-29
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/entry/src/main/java/uk/co/alt236/btlescan/adapter/ConnectItemProvider.java b/entry/src/main/java/uk/co/alt236/btlescan/adapter/ConnectItemProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..1844755a7cfad669d26712f122e075047e36db78
--- /dev/null
+++ b/entry/src/main/java/uk/co/alt236/btlescan/adapter/ConnectItemProvider.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package uk.co.alt236.btlescan.adapter;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.agp.components.BaseItemProvider;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.Text;
+import ohos.bluetooth.ble.GattCharacteristic;
+import ohos.bluetooth.ble.GattService;
+import uk.co.alt236.bluetoothlelib.resolvers.GattAttributeResolver;
+import uk.co.alt236.btlescan.ResourceTable;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * ConnectItemProvider
+ *
+ * @author ljx
+ * @since 2021-04-29
+ */
+public class ConnectItemProvider extends BaseItemProvider {
+ private List list;
+ private AbilitySlice slice;
+
+ /**
+ * ConnectItemProvider
+ *
+ * @param list
+ * @param slice
+ */
+
+ public ConnectItemProvider(List list, AbilitySlice slice) {
+ this.list = list;
+ this.slice = slice;
+ }
+
+ /**
+ * setData
+ *
+ * @param listData
+ */
+ public void setData(List listData) {
+ this.list = listData;
+ notifyDataChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return list == null ? 0 : list.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ if (list != null && position >= 0 && position < list.size()) {
+ return list.get(position);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
+ final Component cpt;
+ if (convertComponent == null) {
+ cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_connect, null, false);
+ } else {
+ cpt = convertComponent;
+ }
+ GattService service = list.get(position);
+ Text name = (Text) cpt.findComponentById(ResourceTable.Id_tv_name);
+ Text mac = (Text) cpt.findComponentById(ResourceTable.Id_tv_uuid);
+ Image arrow = (Image) cpt.findComponentById(ResourceTable.Id_iv_arrow);
+ ListContainer listContainer = (ListContainer) cpt.findComponentById(ResourceTable.Id_item_list);
+
+ DirectionalLayout itemView = (DirectionalLayout) cpt.findComponentById(ResourceTable.Id_root_item_view);
+ itemView.setClickedListener(v -> {
+ if (listContainer.getVisibility() == Component.HIDE) {
+ listContainer.setVisibility(Component.VISIBLE);
+ arrow.setImageAndDecodeBounds(ResourceTable.Media_arrow2);
+ } else {
+ listContainer.setVisibility(Component.HIDE);
+ arrow.setImageAndDecodeBounds(ResourceTable.Media_arrow);
+ }
+ notifyDataChanged();
+ });
+ UUID uuid = service.getUuid();
+ String attributeName = GattAttributeResolver.getAttributeName(uuid.toString(), "Unknown Service");
+ name.setText(attributeName);
+ mac.setText(uuid.toString());
+
+ List characteristics = service.getCharacteristics();
+ ItemItemProvider itemProvider = new ItemItemProvider(characteristics);
+ listContainer.setItemProvider(itemProvider);
+ return cpt;
+ }
+
+ /**
+ * ItemItemProvider
+ *
+ * @author ljx
+ * @since 2021-04-14
+ */
+ public class ItemItemProvider extends BaseItemProvider {
+ private List list;
+
+ /**
+ * ItemItemProvider
+ *
+ * @param list
+ */
+ public ItemItemProvider(List list) {
+ this.list = list;
+ }
+
+ @Override
+ public int getCount() {
+ return list == null ? 0 : list.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ if (list != null && position >= 0 && position < list.size()) {
+ return list.get(position);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
+ final Component cpt;
+ if (convertComponent == null) {
+ cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_item_connect, null, false);
+ } else {
+ cpt = convertComponent;
+ }
+ GattCharacteristic service = list.get(position);
+
+ Text name = (Text) cpt.findComponentById(ResourceTable.Id_tv_name);
+ Text mac = (Text) cpt.findComponentById(ResourceTable.Id_tv_uuid);
+ UUID uuid = service.getUuid();
+ String attributeName = GattAttributeResolver.getAttributeName(uuid.toString(), "Unknown characteristic");
+ name.setText(attributeName);
+ mac.setText(uuid.toString());
+ return cpt;
+ }
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/uk/co/alt236/btlescan/adapter/DeviceItemProvider.java b/entry/src/main/java/uk/co/alt236/btlescan/adapter/DeviceItemProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..d3af5727936d9366649569e632b18b976e3d0fb9
--- /dev/null
+++ b/entry/src/main/java/uk/co/alt236/btlescan/adapter/DeviceItemProvider.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package uk.co.alt236.btlescan.adapter;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.agp.components.BaseItemProvider;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.Text;
+import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
+import uk.co.alt236.btlescan.ResourceTable;
+
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * ConnectItemProvider
+ *
+ * @author ljx
+ * @since 2021-04-29
+ */
+public class DeviceItemProvider extends BaseItemProvider {
+ private List list;
+ private AbilitySlice slice;
+
+ /**
+ * DeviceItemProvider
+ *
+ * @param listData
+ * @param abilitySlice
+ */
+ public DeviceItemProvider(List listData, AbilitySlice abilitySlice) {
+ this.list = listData;
+ this.slice = abilitySlice;
+ }
+
+ /**
+ * setData
+ *
+ * @param listData
+ */
+ public void setData(List listData) {
+ this.list = listData;
+ notifyDataChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return list == null ? 0 : list.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ if (list != null && position >= 0 && position < list.size()) {
+ return list.get(position);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
+ final Component cpt;
+ if (convertComponent == null) {
+ cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_sample, null, false);
+ } else {
+ cpt = convertComponent;
+ }
+ BluetoothLeDevice sampleItem = list.get(position);
+ Text name = (Text) cpt.findComponentById(ResourceTable.Id_item_name);
+ Text mac = (Text) cpt.findComponentById(ResourceTable.Id_mac);
+ Text date = (Text) cpt.findComponentById(ResourceTable.Id_date);
+ name.setText(sampleItem.getName());
+ mac.setText(sampleItem.getAddress());
+ Text rssi = (Text) cpt.findComponentById(ResourceTable.Id_rssi);
+ long timestamp = sampleItem.getTimestamp();
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String sd = sdf.format(timestamp);
+ date.setText(sd);
+ rssi.setText(sampleItem.getRssi() + "db / " + sampleItem.getFirstRssi() + "db");
+ return cpt;
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/uk/co/alt236/btlescan/slice/DeviceAbilitySlice.java b/entry/src/main/java/uk/co/alt236/btlescan/slice/DeviceAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..1cb0e2003faba8ca42a441e0ddc4960bf7f50838
--- /dev/null
+++ b/entry/src/main/java/uk/co/alt236/btlescan/slice/DeviceAbilitySlice.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package uk.co.alt236.btlescan.slice;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Text;
+import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
+import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
+import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
+import uk.co.alt236.bluetoothlelib.util.ByteUtils;
+import uk.co.alt236.btlescan.ResourceTable;
+
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+
+/**
+ * DeviceAbilitySlice
+ *
+ * @author ljx
+ * @since 2021-04-29
+ */
+public class DeviceAbilitySlice extends AbilitySlice {
+ private static final String DB = "db";
+ private BluetoothLeDevice device;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_device);
+ device = intent.getSequenceableParam("device");
+ initView();
+ initListener();
+ }
+
+ private void initView() {
+ Text titlebar = (Text) findComponentById(ResourceTable.Id_tv_title);
+ titlebar.setText(device.getName());
+ Text deviceName = (Text) findComponentById(ResourceTable.Id_device_name);
+ Text deviceAddress = (Text) findComponentById(ResourceTable.Id_device_address);
+ Text deviceClass = (Text) findComponentById(ResourceTable.Id_device_class);
+ deviceName.setText("Device Name:" + device.getName());
+ deviceAddress.setText("Device address:" + device.getAddress());
+ deviceClass.setText("Device Class:");
+ Text majorClass = (Text) findComponentById(ResourceTable.Id_device_major);
+ Text services = (Text) findComponentById(ResourceTable.Id_device_services);
+ Text state = (Text) findComponentById(ResourceTable.Id_device_state);
+ majorClass.setText("Major Class:");
+ services.setText("Services:");
+ state.setText("Bonding State:");
+ Text firstTime = (Text) findComponentById(ResourceTable.Id_rssi_first_time);
+ Text rssi = (Text) findComponentById(ResourceTable.Id_rssi_first);
+ Text lastTime = (Text) findComponentById(ResourceTable.Id_rssi_last_time);
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS zzz");
+ String sd = sdf.format(device.getFirstTimestamp());
+ firstTime.setText("First timestamp:" + sd);
+ rssi.setText("First RSSI:" + device.getFirstRssi() + DB);
+ String lastsd = sdf.format(device.getTimestamp());
+ lastTime.setText("Last timestamp:" + lastsd);
+ Text lastRssi = (Text) findComponentById(ResourceTable.Id_rssi_last);
+ lastRssi.setText("Last RSSI:" + device.getRssi() + DB);
+ Text average = (Text) findComponentById(ResourceTable.Id_rssi_average);
+ average.setText("Running Average RSSI:" + device.getRunningAverageRssi() + DB);
+ Text scanRecord = (Text) findComponentById(ResourceTable.Id_scan_record);
+ scanRecord.setText(ByteUtils.byteArrayToHexString(device.getScanRecord()));
+ Text adtitle = (Text) findComponentById(ResourceTable.Id_title);
+ Text asstring = (Text) findComponentById(ResourceTable.Id_as_string);
+ Text asarray = (Text) findComponentById(ResourceTable.Id_as_array);
+ Collection adRecords = device.getAdRecordStore().getRecordsAsCollection();
+ if (adRecords.size() > 0) {
+ for (AdRecord record : adRecords) {
+ if (record != null) {
+ String title = "#" + record.getType() + " " + record.getHumanReadableType();
+ adtitle.setText(title);
+ asstring.setText("As String:" + AdRecordUtils.getRecordDataAsString(record));
+ asarray.setText("As Array:" + ByteUtils.byteArrayToHexString(record.getData()));
+ }
+ }
+ }
+ }
+
+ private void initListener() {
+ Button connect = (Button) findComponentById(ResourceTable.Id_connect);
+ connect.setClickedListener(v -> {
+ Intent in = new Intent();
+ in.setParam("device", device);
+ present(new DeviceControlAbilitySlice(), in);
+ });
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/uk/co/alt236/btlescan/slice/DeviceControlAbilitySlice.java b/entry/src/main/java/uk/co/alt236/btlescan/slice/DeviceControlAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..b76c71646dca2af48e436aff838b6fbfe875f701
--- /dev/null
+++ b/entry/src/main/java/uk/co/alt236/btlescan/slice/DeviceControlAbilitySlice.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package uk.co.alt236.btlescan.slice;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.RoundProgressBar;
+import ohos.agp.components.Text;
+import ohos.bluetooth.ProfileBase;
+import ohos.bluetooth.ble.BlePeripheralCallback;
+import ohos.bluetooth.ble.BlePeripheralDevice;
+import ohos.bluetooth.ble.BleScanResult;
+import ohos.bluetooth.ble.GattCharacteristic;
+import ohos.bluetooth.ble.GattDescriptor;
+import ohos.bluetooth.ble.GattService;
+import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
+import uk.co.alt236.bluetoothlelib.resolvers.GattAttributeResolver;
+import uk.co.alt236.bluetoothlelib.util.ByteUtils;
+import uk.co.alt236.btlescan.ResourceTable;
+import uk.co.alt236.btlescan.adapter.ConnectItemProvider;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * DeviceAbilitySlice
+ *
+ * @author ljx
+ * @since 2021-04-29
+ */
+public class DeviceControlAbilitySlice extends AbilitySlice {
+ private static final String MDISCONNECTSTR = "DISCONNECT";
+ private static final String MCONNECTINGSTR = "connecting";
+ private static final String MCONNECTSTR = "CONNECT";
+ private static final String MUNKNOWNSTR = "unknown";
+ private static final String MUUIDSTR = "UUID:";
+ private static final String MDESCSTR = "Desc:";
+ private static final String ASSTRING = "As String:";
+ private static final String ASARRAY = "As Array:";
+ private static final int INCREASEROTATE = 20;
+ private static final int MAXROTATE = 360;
+ private static final int DELAYTIME = 100;
+ private boolean isFirst = true;
+ private BlePeripheralDevice peripheraDevice;
+ private Text mState;
+ private RoundProgressBar mProgressBar;
+ private Button mConnect;
+ private int rotate = 0;
+ private boolean isRotation = true;
+ private Text mUuid;
+ private Text mDesc;
+ private Text mStr;
+ private Text mArr;
+ private ListContainer listContainer;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_device_control);
+ initView();
+ BluetoothLeDevice device = intent.getSequenceableParam("device");
+ Text titlebar = (Text) findComponentById(ResourceTable.Id_tv_title);
+ titlebar.setText(device.getName());
+ Text address = (Text) findComponentById(ResourceTable.Id_address);
+ address.setText(device.getAddress());
+ BleScanResult bleDevice = device.getDevice();
+ peripheraDevice = bleDevice.getPeripheralDevice();
+
+ // 与外围设备建立连接,允许自动回连,连接会触发connectionStateChangedEvent回调
+ MyBlePeripheralCallback callback = new MyBlePeripheralCallback();
+ peripheraDevice.connect(true, callback);
+
+ // 连接后读取外围设备RSSI值,获取后触发readRemoteRssiEvent()回调
+ peripheraDevice.readRemoteRssiValue();
+ mState.setText(MCONNECTINGSTR);
+ mConnect.setText(MDISCONNECTSTR);
+ startRotate();
+ mConnect.setClickedListener(v -> {
+ String text = mConnect.getText();
+ if (MCONNECTSTR.equals(text)) {
+ startRotate();
+ mState.setText(MCONNECTINGSTR);
+ mConnect.setText(MDISCONNECTSTR);
+ peripheraDevice.connect(true, callback);
+ peripheraDevice.readRemoteRssiValue();
+ } else {
+ stopRotate();
+ peripheraDevice.disconnect();
+ mState.setText("disconnect");
+ mConnect.setText(MCONNECTSTR);
+ }
+ });
+ }
+
+ private void initView() {
+ mState = (Text) findComponentById(ResourceTable.Id_ble_state);
+ mProgressBar = (RoundProgressBar) findComponentById(ResourceTable.Id_round_progress_bar);
+ mConnect = (Button) findComponentById(ResourceTable.Id_disconnect);
+ listContainer = (ListContainer) findComponentById(ResourceTable.Id_listcontainer);
+ mUuid = (Text) findComponentById(ResourceTable.Id_uuid);
+ mDesc = (Text) findComponentById(ResourceTable.Id_desc);
+ mStr = (Text) findComponentById(ResourceTable.Id_as_string);
+ mArr = (Text) findComponentById(ResourceTable.Id_as_array);
+ }
+
+ /**
+ * 实现外围设备操作回调
+ *
+ * @author ljx
+ * @since 2021-04-29
+ */
+ private class MyBlePeripheralCallback extends BlePeripheralCallback {
+ @Override
+ public void connectionStateChangeEvent(int connectionState) {
+ super.connectionStateChangeEvent(connectionState);
+ if (connectionState == ProfileBase.STATE_CONNECTED) {
+ peripheraDevice.discoverServices(); // 连接成功获取外围设备的Service
+ getUITaskDispatcher().asyncDispatch(() -> {
+ mState.setText("connected");
+ mConnect.setText(MDISCONNECTSTR);
+ stopRotate();
+ listContainer.setVisibility(Component.VISIBLE);
+ });
+ }
+ if (connectionState == ProfileBase.STATE_CONNECTING) {
+ // 连接中
+ getUITaskDispatcher().asyncDispatch(() -> {
+ mState.setText(MCONNECTINGSTR);
+ mConnect.setText(MDISCONNECTSTR);
+ startRotate();
+ listContainer.setVisibility(Component.INVISIBLE);
+ });
+ }
+ if (connectionState == ProfileBase.STATE_DISCONNECTED) {
+ // 连接断开
+ getUITaskDispatcher().asyncDispatch(() -> {
+ mState.setText("disconnected");
+ mConnect.setText(MCONNECTSTR);
+ stopRotate();
+ listContainer.setVisibility(Component.INVISIBLE);
+ });
+ }
+ }
+
+ @Override
+ public void servicesDiscoveredEvent(int status) {
+ // 获取外围设备Service的回调
+ if (status == BlePeripheralDevice.OPERATION_SUCC) {
+ if (isFirst) {
+ // 获取Service成功后获服务列表
+ List services = peripheraDevice.getServices();
+ ConnectItemProvider provider = new ConnectItemProvider(services, DeviceControlAbilitySlice.this);
+ getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ isFirst = false;
+ listContainer.setItemProvider(provider);
+ }
+ });
+ }
+ }
+ }
+
+ @Override
+ public void characteristicChangedEvent(GattCharacteristic charecteristic) {
+ // 外围设备主动向中心设备发送特征值通知时触发回调
+ // 根据通知的charecteristic获取特征值携带的数据
+ UUID uuid = charecteristic.getUuid();
+ byte[] value = charecteristic.getValue();
+ String attribute = GattAttributeResolver.getAttributeName(uuid.toString(), MUNKNOWNSTR);
+ getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mUuid.setText(MUUIDSTR + uuid.toString());
+ mDesc.setText(MDESCSTR + attribute);
+ mStr.setText(ASSTRING + Arrays.toString(value));
+ mArr.setText(ASARRAY + ByteUtils.byteArrayToHexString(value));
+ }
+ });
+ }
+
+ @Override
+ public void characteristicWriteEvent(GattCharacteristic charecteristic, int ret) {
+ if (ret == BlePeripheralDevice.OPERATION_SUCC) {
+ // 向外围设备写特征值数据成功后的操作
+ UUID uuid = charecteristic.getUuid();
+ byte[] value = charecteristic.getValue();
+ String attribute = GattAttributeResolver.getAttributeName(uuid.toString(), MUNKNOWNSTR);
+ getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mUuid.setText(MUUIDSTR + uuid.toString());
+ mDesc.setText(MDESCSTR + attribute);
+ mStr.setText(ASSTRING + Arrays.toString(value));
+ mArr.setText(ASARRAY + ByteUtils.byteArrayToHexString(value));
+ }
+ });
+ }
+ }
+
+ @Override
+ public void characteristicReadEvent(GattCharacteristic charecteristic, int ret) {
+ if (ret == BlePeripheralDevice.OPERATION_SUCC) {
+ // 向外围设备写特征值数据成功后的操作
+ UUID uuid = charecteristic.getUuid();
+ byte[] value = charecteristic.getValue();
+ String attribute = GattAttributeResolver.getAttributeName(uuid.toString(), MUNKNOWNSTR);
+ getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mUuid.setText(MUUIDSTR + uuid.toString());
+ mDesc.setText(MDESCSTR + attribute);
+ mStr.setText(ASSTRING + Arrays.toString(value));
+ mArr.setText(ASARRAY + ByteUtils.byteArrayToHexString(value));
+ }
+ });
+ }
+ }
+
+ @Override
+ public void descriptorReadEvent(GattDescriptor descriptor, int ret) {
+ // 向外围设备读描述值数据成功后的操作
+ }
+
+ @Override
+ public void descriptorWriteEvent(GattDescriptor descriptor, int ret) {
+ // 向外围设备写描述值数据成功后的操作
+ }
+
+ @Override
+ public void readRemoteRssiEvent(int rssi, int ret) {
+ // 读取外围设备RSSI值成功后的操作,对端RSSI值为rssi
+ }
+ }
+
+ private void startRotate() {
+ isRotation = true;
+ mProgressBar.setVisibility(Component.VISIBLE);
+ getUITaskDispatcher().delayDispatch(() -> {
+ rotate = rotate + INCREASEROTATE;
+ if (rotate == MAXROTATE) {
+ rotate = 0;
+ }
+ if (isRotation && mProgressBar != null && mProgressBar.getVisibility() == Component.VISIBLE) {
+ mProgressBar.setRotation(rotate);
+ startRotate();
+ }
+ }, DELAYTIME);
+ }
+
+ private void stopRotate() {
+ isRotation = false;
+ mProgressBar.setVisibility(Component.INVISIBLE);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ stopRotate();
+ peripheraDevice.disconnect();
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/uk/co/alt236/btlescan/slice/MainAbilitySlice.java b/entry/src/main/java/uk/co/alt236/btlescan/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..a05c4870cca80553836f52fa3574eff73437cb54
--- /dev/null
+++ b/entry/src/main/java/uk/co/alt236/btlescan/slice/MainAbilitySlice.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package uk.co.alt236.btlescan.slice;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.aafwk.content.Operation;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.RoundProgressBar;
+import ohos.agp.components.Text;
+import ohos.agp.utils.LayoutAlignment;
+import ohos.agp.window.dialog.CommonDialog;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.Context;
+import ohos.bluetooth.BluetoothHost;
+import ohos.bluetooth.ble.BleCentralManager;
+import ohos.bluetooth.ble.BleCentralManagerCallback;
+import ohos.bluetooth.ble.BleScanFilter;
+import ohos.bluetooth.ble.BleScanResult;
+import ohos.utils.IntentConstants;
+import ohos.utils.net.Uri;
+import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
+import uk.co.alt236.btlescan.ResourceTable;
+import uk.co.alt236.btlescan.adapter.DeviceItemProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * DeviceAbilitySlice
+ *
+ * @author ljx
+ * @since 2021-04-29
+ */
+public class MainAbilitySlice extends AbilitySlice {
+ private static final int WIDTH = 340;
+ private static final int RADIUS = 15;
+ private BluetoothHost bluetoothHost;
+ private ScanCallback centralManagerCallback;
+ private BleCentralManager centralManager;
+ private ListContainer listContainer;
+ private RoundProgressBar mProgressBar;
+ private int rotate = 0;
+ private boolean isRotation = true;
+ private Button scan;
+ private DeviceItemProvider sampleItemProvider;
+ private List listDevice;
+ private Text itemNum;
+ private Text tvState;
+ private final int increaseRotate = 20;
+ private final int maxRotate = 360;
+ private final int delayTime = 100;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ // 获取蓝牙本机管理对象
+ bluetoothHost = BluetoothHost.getDefaultHost(this);
+ bluetoothHost.enableBt();
+ centralManagerCallback = new ScanCallback();
+ centralManager = new BleCentralManager(this, centralManagerCallback);
+ mProgressBar = (RoundProgressBar) findComponentById(ResourceTable.Id_round_progress_bar);
+ scan = (Button) findComponentById(ResourceTable.Id_scan);
+ listContainer = (ListContainer) findComponentById(ResourceTable.Id_listcontainer);
+ tvState = (Text) findComponentById(ResourceTable.Id_ble_state);
+ itemNum = (Text) findComponentById(ResourceTable.Id_item_num);
+ Text about = (Text) findComponentById(ResourceTable.Id_tv_about);
+ about.setClickedListener(v -> {
+ about();
+ });
+ init();
+ }
+
+ /**
+ * 初始化
+ */
+ public void init() {
+ scan.setClickedListener(v -> {
+ int state = bluetoothHost.getBtState();
+ if (state == BluetoothHost.STATE_ON) {
+ tvState.setText("on");
+ if ("scan".equals(scan.getText())) {
+ scan.setText("stop");
+ startRotate();
+ List filters = new ArrayList<>();
+ centralManager.startScan(filters);
+ } else {
+ scan.setText("scan");
+ stopRotate();
+ centralManager.stopScan();
+ }
+ } else {
+ bluetoothHost.enableBt();
+ }
+ });
+ if (bluetoothHost.getBtState() == BluetoothHost.STATE_ON) {
+ tvState.setText("on");
+ } else {
+ tvState.setText("off");
+ }
+
+ listDevice = new ArrayList<>();
+ sampleItemProvider = new DeviceItemProvider(listDevice, this);
+ listContainer.setItemProvider(sampleItemProvider);
+ listContainer.setItemClickedListener((container, component, position, id) -> {
+ BluetoothLeDevice deviceItem = (BluetoothLeDevice) listContainer.getItemProvider().getItem(position);
+
+ Intent intent = new Intent();
+ intent.setParam("device", deviceItem);
+ present(new DeviceAbilitySlice(), intent);
+ });
+ }
+
+ private void about() {
+ DirectionalLayout directionalLayout = (DirectionalLayout) LayoutScatter.getInstance(this)
+ .parse(ResourceTable.Layout_dialog_picker, null, false);
+ CommonDialog dialog = new CommonDialog(this);
+ dialog.setContentCustomComponent(directionalLayout);
+ dialog.setAutoClosable(true);
+ dialog.setSize(vp2px(this, WIDTH), DirectionalLayout.LayoutConfig.MATCH_CONTENT);
+ dialog.setAlignment(LayoutAlignment.CENTER);
+ dialog.setCornerRadius(vp2px(this, RADIUS));
+ dialog.show();
+ Text confirm = (Text) directionalLayout.findComponentById(ResourceTable.Id_tv_confirm);
+ confirm.setClickedListener(v -> {
+ dialog.destroy();
+ });
+ Text tvUrl = (Text) directionalLayout.findComponentById(ResourceTable.Id_tv_url);
+ tvUrl.setClickedListener(v -> {
+ initWeb();
+ dialog.destroy();
+ });
+ }
+
+ private void initWeb() {
+ Intent intents = new Intent();
+ Operation operation = new Intent.OperationBuilder()
+ .withUri(Uri.parse("https://github.com/alt236/Bluetooth-LE-Library---Android"))
+ .withAction(IntentConstants.ACTION_SEARCH)
+ .build();
+ intents.setOperation(operation);
+ startAbility(intents);
+ }
+
+ /**
+ * vp转像素
+ */
+ private int vp2px(Context context, float vp) {
+ DisplayAttributes attributes = DisplayManager.getInstance().getDefaultDisplay(context).get().getAttributes();
+ return (int) (attributes.densityPixels * vp);
+ }
+
+ private void startRotate() {
+ isRotation = true;
+ mProgressBar.setVisibility(Component.VISIBLE);
+ getUITaskDispatcher().delayDispatch(() -> {
+ rotate = rotate + increaseRotate;
+ if (rotate == maxRotate) {
+ rotate = 0;
+ }
+ if (isRotation && mProgressBar != null && mProgressBar.getVisibility() == Component.VISIBLE) {
+ mProgressBar.setRotation(rotate);
+ startRotate();
+ }
+ }, delayTime);
+ }
+
+ private void stopRotate() {
+ isRotation = false;
+ mProgressBar.setVisibility(Component.INVISIBLE);
+ }
+
+ /**
+ * ScanCallback
+ *
+ * @author ljx
+ * @since 2021-04-29
+ */
+ public class ScanCallback implements BleCentralManagerCallback {
+ List results = new ArrayList<>();
+
+ @Override
+ public void scanResultEvent(BleScanResult resultCode) {
+ // 对扫描结果进行处理
+ results.add(resultCode);
+ int rssi = resultCode.getRssi();
+ byte[] scanRecord = resultCode.getRawData();
+ BluetoothLeDevice deviceLe = new BluetoothLeDevice(resultCode,
+ rssi, scanRecord, System.currentTimeMillis());
+ getUITaskDispatcher().asyncDispatch(() -> {
+ for (int index = 0; index < listDevice.size(); index++) {
+ if (deviceLe.getAddress().equals(listDevice.get(index).getAddress())) {
+ BluetoothLeDevice item = listDevice.get(index);
+ item.updateRssiReading(System.currentTimeMillis(), rssi);
+ return;
+ }
+ }
+ listDevice.add(deviceLe);
+ sampleItemProvider.setData(listDevice);
+ itemNum.setText("Items:" + listDevice.size());
+ });
+ }
+
+ @Override
+ public void scanFailedEvent(int resultCode) {
+ }
+
+ @Override
+ public void groupScanResultsEvent(List list) {
+ }
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..743400fe0880475dd69f12f249d8b9a87fc53243
--- /dev/null
+++ b/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Bluetooth_LE_Library"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "HelloWorld",
+ "value": "Hello World"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_main.xml b/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_device.xml b/entry/src/main/resources/base/layout/ability_device.xml
new file mode 100644
index 0000000000000000000000000000000000000000..90a8a95f04252f13512593b03cd36927aa39fc82
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_device.xml
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_device_control.xml b/entry/src/main/resources/base/layout/ability_device_control.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cb5810142286d48e1a33c3763ed2bdb37a8570b5
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_device_control.xml
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/entry/src/main/resources/base/layout/ability_main.xml b/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..927b141996ddb725131c895a9a5fa9a0a7d618ef
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/dialog_picker.xml b/entry/src/main/resources/base/layout/dialog_picker.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e260b08953f934cebf094736e4d100a63d4da8fa
--- /dev/null
+++ b/entry/src/main/resources/base/layout/dialog_picker.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_connect.xml b/entry/src/main/resources/base/layout/item_connect.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5e71fffe93d12c33d9c186e599ebbfa888a00fb5
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_connect.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_item_connect.xml b/entry/src/main/resources/base/layout/item_item_connect.xml
new file mode 100644
index 0000000000000000000000000000000000000000..be27f202ebaf9ac128f9437b2d20fc72b6517424
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_item_connect.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_sample.xml b/entry/src/main/resources/base/layout/item_sample.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3a166dac11e90edb6c4a59214e3e14cc8e1cf62c
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_sample.xml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/media/arrow.png b/entry/src/main/resources/base/media/arrow.png
new file mode 100644
index 0000000000000000000000000000000000000000..570968230d55027004b410917a9eeee19d5a403e
Binary files /dev/null and b/entry/src/main/resources/base/media/arrow.png differ
diff --git a/entry/src/main/resources/base/media/arrow2.png b/entry/src/main/resources/base/media/arrow2.png
new file mode 100644
index 0000000000000000000000000000000000000000..68f76405db32ab4ffdb5a87821dfa46e581df798
Binary files /dev/null and b/entry/src/main/resources/base/media/arrow2.png differ
diff --git a/sample_app/src/main/res/drawable-xxhdpi/ic_bluetooth.png b/entry/src/main/resources/base/media/ic_bluetooth.png
similarity index 100%
rename from sample_app/src/main/res/drawable-xxhdpi/ic_bluetooth.png
rename to entry/src/main/resources/base/media/ic_bluetooth.png
diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/entry/src/main/resources/base/media/icon.png differ
diff --git a/entry/src/ohosTest/config.json b/entry/src/ohosTest/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..1d8e7417aff2667bb459cab0ddc18be2c2e81bd4
--- /dev/null
+++ b/entry/src/ohosTest/config.json
@@ -0,0 +1,41 @@
+{
+ "app": {
+ "bundleName": "uk.co.alt236.btlescan",
+ "vendor": "co",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "uk.co.alt236.btlescan",
+ "name": "testModule",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry_test",
+ "moduleType": "feature",
+ "installationFree": true
+ },
+ "abilities": [
+ {
+ "name": "decc.testkit.runner.EntryAbility",
+ "description": "Test Entry Ability",
+ "icon": "$media:icon",
+ "label": "$string:app_name",
+ "launchType": "standard",
+ "orientation": "landscape",
+ "visible": true,
+ "type": "page"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/entry/src/ohosTest/java/uk/co/alt236/btlescan/ExampleOhosTest.java b/entry/src/ohosTest/java/uk/co/alt236/btlescan/ExampleOhosTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..92c2f3bd0dc655d641925ebe9ae6b447c9b037f3
--- /dev/null
+++ b/entry/src/ohosTest/java/uk/co/alt236/btlescan/ExampleOhosTest.java
@@ -0,0 +1,14 @@
+package uk.co.alt236.btlescan;
+
+import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ExampleOhosTest {
+ @Test
+ public void testBundleName() {
+ final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName();
+ assertEquals("uk.co.alt236.btlescan", actualBundleName);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/test/java/uk/co/alt236/btlescan/ExampleTest.java b/entry/src/test/java/uk/co/alt236/btlescan/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4cacc2fc4ed4d2cd265ce06575aeb2494f499014
--- /dev/null
+++ b/entry/src/test/java/uk/co/alt236/btlescan/ExampleTest.java
@@ -0,0 +1,9 @@
+package uk.co.alt236.btlescan;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/gradle.properties b/gradle.properties
index 5465fec0ecadbf086fce0db92293c8f1d5f720ff..0daf1830fbdef07e50a44d74210c8c82f1b66278 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,10 @@
-android.enableJetifier=true
-android.useAndroidX=true
\ No newline at end of file
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 8c0fb64a8698b08ecc4158d828ca593c4928e9dd..490fda8577df6c95960ba7077c43220e5bb2c0d9 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index e12c3801d7c1b435f1cec937e70553fef5e71000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Wed Apr 22 10:28:09 BST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-all.zip
diff --git a/gradlew b/gradlew
index 91a7e269e19dfc62e27137a0b57ef3e430cee4fd..536f0272dd995f3afdb5e34e0f42bdf3d1986c22 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,20 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
##############################################################################
##
@@ -6,159 +22,162 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ]; do
+ ls=$(ls -ld "$PRG")
+ link=$(expr "$ls" : '.*-> \(.*\)$')
+ if expr "$link" : '/.*' >/dev/null; then
+ PRG="$link"
+ else
+ PRG=$(dirname "$PRG")"/$link"
+ fi
+done
+SAVED="$(pwd)"
+cd "$(dirname \"$PRG\")/" >/dev/null
+APP_HOME="$(pwd -P)"
+cd "$SAVED" >/dev/null
APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
+APP_BASE_NAME=$(basename "$0")
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
- echo "$*"
+warn() {
+ echo "$*"
}
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
+die() {
+ echo
+ echo "$*"
+ echo
+ exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
+nonstop=false
+case "$(uname)" in
+CYGWIN*)
+ cygwin=true
+ ;;
+Darwin*)
+ darwin=true
+ ;;
+MINGW*)
+ msys=true
+ ;;
+NONSTOP*)
+ nonstop=true
+ ;;
esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+if [ -n "$JAVA_HOME" ]; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ]; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
- fi
+ fi
else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then
+ MAX_FD_LIMIT=$(ulimit -H -n)
+ if [ $? -eq 0 ]; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
+ MAX_FD="$MAX_FD_LIMIT"
fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ]; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ]; then
+ APP_HOME=$(cygpath --path --mixed "$APP_HOME")
+ CLASSPATH=$(cygpath --path --mixed "$CLASSPATH")
+ JAVACMD=$(cygpath --unix "$JAVACMD")
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null)
+ SEP=""
+ for dir in $ROOTDIRSRAW; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ]; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@"; do
+ CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -)
+ CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition
+ eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg")
+ else
+ eval $(echo args$i)="\"$arg\""
fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
+ i=$(expr $i + 1)
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save() {
+ for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 8a0b282aa6885fb573c106b3551f7275c5f17e8e..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,3 +1,19 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -8,14 +24,17 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +65,9 @@ echo location of your Java installation.
goto fail
:init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +78,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
diff --git a/image_assets/feature_graphic.png b/image_assets/feature_graphic.png
deleted file mode 100644
index 7f0f65225ff8444dde688c81e650094415d97cce..0000000000000000000000000000000000000000
Binary files a/image_assets/feature_graphic.png and /dev/null differ
diff --git a/image_assets/screenshots/phone_screenshot_1.png b/image_assets/screenshots/phone_screenshot_1.png
deleted file mode 100644
index 3b30f13a774a41704d9a54c473d86890c3e066ad..0000000000000000000000000000000000000000
Binary files a/image_assets/screenshots/phone_screenshot_1.png and /dev/null differ
diff --git a/image_assets/screenshots/phone_screenshot_2.png b/image_assets/screenshots/phone_screenshot_2.png
deleted file mode 100644
index cff7f5b8cf7312e2593f2e9271ec633950ad574d..0000000000000000000000000000000000000000
Binary files a/image_assets/screenshots/phone_screenshot_2.png and /dev/null differ
diff --git a/image_assets/screenshots/phone_screenshot_3.png b/image_assets/screenshots/phone_screenshot_3.png
deleted file mode 100644
index 5686912a08c9210e4c201aaa7290fdde2412487a..0000000000000000000000000000000000000000
Binary files a/image_assets/screenshots/phone_screenshot_3.png and /dev/null differ
diff --git a/image_assets/screenshots/phone_screenshot_4.png b/image_assets/screenshots/phone_screenshot_4.png
deleted file mode 100644
index 72cab20a37624722a44e807260b877c732120a2e..0000000000000000000000000000000000000000
Binary files a/image_assets/screenshots/phone_screenshot_4.png and /dev/null differ
diff --git a/image_assets/web_hi_res_512.png b/image_assets/web_hi_res_512.png
deleted file mode 100644
index 439bcb0ac9a9e015a759f9e5e6a958cc94fff342..0000000000000000000000000000000000000000
Binary files a/image_assets/web_hi_res_512.png and /dev/null differ
diff --git a/img/bluetooth_1.png b/img/bluetooth_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..24c79552af787d6e4116887ff4fa7aaff754a9f3
Binary files /dev/null and b/img/bluetooth_1.png differ
diff --git a/img/bluetooth_2.jpg b/img/bluetooth_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..cd58ce723fb34b5d5bdbcb551e2dcbccfa69087d
Binary files /dev/null and b/img/bluetooth_2.jpg differ
diff --git a/img/bluetooth_3.jpg b/img/bluetooth_3.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..bcb4135de0f03b279aa4598c920877ac23646628
Binary files /dev/null and b/img/bluetooth_3.jpg differ
diff --git a/img/bluetooth_4.jpg b/img/bluetooth_4.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..68a445ff68f16123ef2242c3eb8f7d78582b7042
Binary files /dev/null and b/img/bluetooth_4.jpg differ
diff --git a/img/bluetooth_5.jpg b/img/bluetooth_5.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..aa5399ff9f21709d5a3dca3a2f09826ab277f4c0
Binary files /dev/null and b/img/bluetooth_5.jpg differ
diff --git a/library/build.gradle b/library/build.gradle
index d0dc2e7899b72a566988836e9bd95eb28d9c5bf1..25ddf0cf1daa8f1533639ebc05ce352f4019b8ff 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -1,57 +1,21 @@
-plugins {
- id 'com.android.library'
- id 'com.novoda.bintray-release'
-}
-
-apply from: "${project.rootDir}/buildsystem/android-defaults.gradle"
-
-final int versionMajor = 1
-final int versionMinor = 0
-final int versionPatch = 0
-final int androidVersionCode = 5
-
-final String semanticVersion = "${versionMajor}.${versionMinor}.${versionPatch}"
-
-repositories {
- google()
- mavenCentral()
-}
-
-dependencies {
- implementation "androidx.annotation:annotation:$androidx_annotation_version"
-
- testImplementation 'junit:junit:4.13'
- testImplementation "org.mockito:mockito-core:3.1.0"
-}
-
-publish {
- groupId = 'uk.co.alt236'
- artifactId = 'bluetooth-le-library-android'
- publishVersion = "${semanticVersion}"
- userOrg = ''
- desc = ''
- bintrayUser = getPropertySafe("alt236JCenterUser", "[NOT_CONFIGURED]")
- bintrayKey = getPropertySafe("alt236JCenterToken", "[NOT_CONFIGURED]")
- //website = 'https://github.com/novoda/bintray-release'
-}
-
-android {
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
defaultConfig {
- versionCode androidVersionCode
- versionName semanticVersion
+ compatibleSdkVersion 5
}
-
buildTypes {
release {
- minifyEnabled false
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
}
}
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
+
}
-// Script from https://github.com/novoda/bintray-release
-// execute: ./gradlew clean build bintrayUpload -PbintrayUser=BINTRAY_USERNAME -PbintrayKey=BINTRAY_KEY -PdryRun=false
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testImplementation 'junit:junit:4.13'
+}
diff --git a/library/ic_launcher-web.png b/library/ic_launcher-web.png
deleted file mode 100644
index baf0bd7edde2d759adf637f8f50c565d7d4139b6..0000000000000000000000000000000000000000
Binary files a/library/ic_launcher-web.png and /dev/null differ
diff --git a/library/library.iml b/library/library.iml
deleted file mode 100644
index 3aa64c6ba4bf1c650e4d6792a56fb43aa55bf110..0000000000000000000000000000000000000000
--- a/library/library.iml
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/proguard-rules.pro b/library/proguard-rules.pro
index f8c620ff696bac14c51b13eb8b3d1ba657a1dc2b..f7666e47561d514b2a76d5a7dfbb43ede86da92a 100644
--- a/library/proguard-rules.pro
+++ b/library/proguard-rules.pro
@@ -1,17 +1 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /home/alex/Dev/android-sdk-linux/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
+# config module specific ProGuard rules here.
\ No newline at end of file
diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml
deleted file mode 100644
index 0318a4529596b22ff7b6a453a5b63fde42e1642d..0000000000000000000000000000000000000000
--- a/library/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/src/main/config.json b/library/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..ee8015a329057176156deff36ce232f6a0a27cdd
--- /dev/null
+++ b/library/src/main/config.json
@@ -0,0 +1,28 @@
+{
+ "app": {
+ "bundleName": "uk.co.alt236.btlescan",
+ "vendor": "co",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {
+ },
+ "module": {
+ "package": "uk.co.alt236.bluetoothlelib",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "library",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothClass.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothClass.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cd3434c30ccf6ef3039605c4584a9bf101e89f7
--- /dev/null
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothClass.java
@@ -0,0 +1,379 @@
+package uk.co.alt236.bluetoothlelib.device;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+/**
+ * Represents a Bluetooth class, which describes general characteristics
+ * and capabilities of a device. For example, a Bluetooth class will
+ * specify the general device type such as a phone, a computer, or
+ * headset, and whether it's capable of services such as audio or telephony.
+ *
+ *
Every Bluetooth class is composed of zero or more service classes, and
+ * exactly one device class. The device class is further broken down into major
+ * and minor device class components.
+ *
+ *
+ */
+public final class BluetoothClass {
+ /**
+ * Legacy error value. Applications should use null instead.
+ *
+ * @hide
+ */
+ public static final int ERROR = 0xFF000000;
+
+ private final int mClass;
+
+ public BluetoothClass(int classInt) {
+ mClass = classInt;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof BluetoothClass) {
+ return mClass == ((BluetoothClass) o).mClass;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return mClass;
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toHexString(mClass);
+ }
+
+ /**
+ * Defines all service class constants.
+ *
Each {@link BluetoothClass} encodes zero or more service classes.
+ */
+ public static final class Service {
+ private static final int BITMASK = 0xFFE000;
+
+ public static final int LIMITED_DISCOVERABILITY = 0x002000;
+ public static final int POSITIONING = 0x010000;
+ public static final int NETWORKING = 0x020000;
+ public static final int RENDER = 0x040000;
+ public static final int CAPTURE = 0x080000;
+ public static final int OBJECT_TRANSFER = 0x100000;
+ public static final int AUDIO = 0x200000;
+ public static final int TELEPHONY = 0x400000;
+ public static final int INFORMATION = 0x800000;
+ }
+
+ /**
+ * Return true if the specified service class is supported by this
+ * {@link BluetoothClass}.
+ *
Valid service classes are the public constants in
+ * {@link Service}. For example, {@link
+ * Service#AUDIO}.
+ *
+ * @param service valid service class
+ * @return true if the service class is supported
+ */
+ public boolean hasService(int service) {
+ return ((mClass & Service.BITMASK & service) != 0);
+ }
+
+ /**
+ * Defines all device class constants.
+ *
Each {@link BluetoothClass} encodes exactly one device class, with
+ * major and minor components.
+ *
The constants in {@link
+ * Device} represent a combination of major and minor
+ * device components (the complete device class). The constants in {@link
+ * Major} represent only major device classes.
+ *
See {@link Service} for service class constants.
+ */
+ public static class Device {
+ private static final int BITMASK = 0x1FFC;
+
+ /**
+ * Defines all major device class constants.
+ *
See {@link Device} for minor classes.
+ */
+ public static class Major {
+ private static final int BITMASK = 0x1F00;
+
+ public static final int MISC = 0x0000;
+ public static final int COMPUTER = 0x0100;
+ public static final int PHONE = 0x0200;
+ public static final int NETWORKING = 0x0300;
+ public static final int AUDIO_VIDEO = 0x0400;
+ public static final int PERIPHERAL = 0x0500;
+ public static final int IMAGING = 0x0600;
+ public static final int WEARABLE = 0x0700;
+ public static final int TOY = 0x0800;
+ public static final int HEALTH = 0x0900;
+ public static final int UNCATEGORIZED = 0x1F00;
+ }
+
+ // Devices in the COMPUTER major class
+ public static final int COMPUTER_UNCATEGORIZED = 0x0100;
+ public static final int COMPUTER_DESKTOP = 0x0104;
+ public static final int COMPUTER_SERVER = 0x0108;
+ public static final int COMPUTER_LAPTOP = 0x010C;
+ public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110;
+ public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114;
+ public static final int COMPUTER_WEARABLE = 0x0118;
+
+ // Devices in the PHONE major class
+ public static final int PHONE_UNCATEGORIZED = 0x0200;
+ public static final int PHONE_CELLULAR = 0x0204;
+ public static final int PHONE_CORDLESS = 0x0208;
+ public static final int PHONE_SMART = 0x020C;
+ public static final int PHONE_MODEM_OR_GATEWAY = 0x0210;
+ public static final int PHONE_ISDN = 0x0214;
+
+ // Minor classes for the AUDIO_VIDEO major class
+ public static final int AUDIO_VIDEO_UNCATEGORIZED = 0x0400;
+ public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404;
+ public static final int AUDIO_VIDEO_HANDSFREE = 0x0408;
+ //public static final int AUDIO_VIDEO_RESERVED = 0x040C;
+ public static final int AUDIO_VIDEO_MICROPHONE = 0x0410;
+ public static final int AUDIO_VIDEO_LOUDSPEAKER = 0x0414;
+ public static final int AUDIO_VIDEO_HEADPHONES = 0x0418;
+ public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C;
+ public static final int AUDIO_VIDEO_CAR_AUDIO = 0x0420;
+ public static final int AUDIO_VIDEO_SET_TOP_BOX = 0x0424;
+ public static final int AUDIO_VIDEO_HIFI_AUDIO = 0x0428;
+ public static final int AUDIO_VIDEO_VCR = 0x042C;
+ public static final int AUDIO_VIDEO_VIDEO_CAMERA = 0x0430;
+ public static final int AUDIO_VIDEO_CAMCORDER = 0x0434;
+ public static final int AUDIO_VIDEO_VIDEO_MONITOR = 0x0438;
+ public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C;
+ public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440;
+ //public static final int AUDIO_VIDEO_RESERVED = 0x0444;
+ public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448;
+
+ // Devices in the WEARABLE major class
+ public static final int WEARABLE_UNCATEGORIZED = 0x0700;
+ public static final int WEARABLE_WRIST_WATCH = 0x0704;
+ public static final int WEARABLE_PAGER = 0x0708;
+ public static final int WEARABLE_JACKET = 0x070C;
+ public static final int WEARABLE_HELMET = 0x0710;
+ public static final int WEARABLE_GLASSES = 0x0714;
+
+ // Devices in the TOY major class
+ public static final int TOY_UNCATEGORIZED = 0x0800;
+ public static final int TOY_ROBOT = 0x0804;
+ public static final int TOY_VEHICLE = 0x0808;
+ public static final int TOY_DOLL_ACTION_FIGURE = 0x080C;
+ public static final int TOY_CONTROLLER = 0x0810;
+ public static final int TOY_GAME = 0x0814;
+
+ // Devices in the HEALTH major class
+ public static final int HEALTH_UNCATEGORIZED = 0x0900;
+ public static final int HEALTH_BLOOD_PRESSURE = 0x0904;
+ public static final int HEALTH_THERMOMETER = 0x0908;
+ public static final int HEALTH_WEIGHING = 0x090C;
+ public static final int HEALTH_GLUCOSE = 0x0910;
+ public static final int HEALTH_PULSE_OXIMETER = 0x0914;
+ public static final int HEALTH_PULSE_RATE = 0x0918;
+ public static final int HEALTH_DATA_DISPLAY = 0x091C;
+
+ // Devices in PERIPHERAL major class
+ /**
+ * @hide
+ */
+ public static final int PERIPHERAL_NON_KEYBOARD_NON_POINTING = 0x0500;
+ /**
+ * @hide
+ */
+ public static final int PERIPHERAL_KEYBOARD = 0x0540;
+ /**
+ * @hide
+ */
+ public static final int PERIPHERAL_POINTING = 0x0580;
+ /**
+ * @hide
+ */
+ public static final int PERIPHERAL_KEYBOARD_POINTING = 0x05C0;
+ }
+
+ /**
+ * Return the major device class component of this {@link BluetoothClass}.
+ *
Values returned from this function can be compared with the
+ * public constants in {@link Device.Major} to determine
+ * which major class is encoded in this Bluetooth class.
+ *
+ * @return major device class component
+ */
+ public int getMajorDeviceClass() {
+ return (mClass & Device.Major.BITMASK);
+ }
+
+ /**
+ * Return the (major and minor) device class component of this
+ * {@link BluetoothClass}.
+ *
Values returned from this function can be compared with the
+ * public constants in {@link Device} to determine which
+ * device class is encoded in this Bluetooth class.
+ *
+ * @return device class component
+ */
+ public int getDeviceClass() {
+ return (mClass & Device.BITMASK);
+ }
+
+ /**
+ * Return the Bluetooth Class of Device (CoD) value including the
+ * {@link Service}, {@link Device.Major} and
+ * minor device fields.
+ *
+ *
This value is an integer representation of Bluetooth CoD as in
+ * Bluetooth specification.
+ *
+ * @see https://www.bluetooth.com/specifications/assigned-numbers/baseband
+ *
+ * @hide
+ */
+ public int getClassOfDevice() {
+ return mClass;
+ }
+
+ /**
+ * Return the Bluetooth Class of Device (CoD) value including the
+ * {@link Service}, {@link Device.Major} and
+ * minor device fields.
+ *
+ *
This value is a byte array representation of Bluetooth CoD as in
+ * Bluetooth specification.
+ *
+ *
Bluetooth COD information is 3 bytes, but stored as an int. Hence the
+ * MSB is useless and needs to be thrown away. The lower 3 bytes are
+ * converted into a byte array MSB to LSB. Hence, using BIG_ENDIAN.
+ *
+ * @see https://www.bluetooth.com/specifications/assigned-numbers/baseband
+ *
+ * @hide
+ */
+ public byte[] getClassOfDeviceBytes() {
+ byte[] bytes = ByteBuffer.allocate(4)
+ .order(ByteOrder.BIG_ENDIAN)
+ .putInt(mClass)
+ .array();
+
+ // Discard the top byte
+ return Arrays.copyOfRange(bytes, 1, bytes.length);
+ }
+
+ /** @hide */
+ public static final int PROFILE_HEADSET = 0;
+ /** @hide */
+ public static final int PROFILE_A2DP = 1;
+ /** @hide */
+ public static final int PROFILE_OPP = 2;
+ /** @hide */
+ public static final int PROFILE_HID = 3;
+ /** @hide */
+ public static final int PROFILE_PANU = 4;
+ /** @hide */
+ public static final int PROFILE_NAP = 5;
+ /** @hide */
+ public static final int PROFILE_A2DP_SINK = 6;
+
+ /**
+ * Check class bits for possible bluetooth profile support.
+ * This is a simple heuristic that tries to guess if a device with the
+ * given class bits might support specified profile. It is not accurate for all
+ * devices. It tries to err on the side of false positives.
+ *
+ * @param profile The profile to be checked
+ * @return True if this device might support specified profile.
+ * @hide
+ */
+ public boolean doesClassMatch(int profile) {
+ if (profile == PROFILE_A2DP) {
+ if (hasService(Service.RENDER)) {
+ return true;
+ }
+ // By the A2DP spec, sinks must indicate the RENDER service.
+ // However we found some that do not (Chordette). So lets also
+ // match on some other class bits.
+ switch (getDeviceClass()) {
+ case Device.AUDIO_VIDEO_HIFI_AUDIO:
+ case Device.AUDIO_VIDEO_HEADPHONES:
+ case Device.AUDIO_VIDEO_LOUDSPEAKER:
+ case Device.AUDIO_VIDEO_CAR_AUDIO:
+ return true;
+ default:
+ return false;
+ }
+ } else if (profile == PROFILE_A2DP_SINK) {
+ if (hasService(Service.CAPTURE)) {
+ return true;
+ }
+ // By the A2DP spec, srcs must indicate the CAPTURE service.
+ // However if some device that do not, we try to
+ // match on some other class bits.
+ switch (getDeviceClass()) {
+ case Device.AUDIO_VIDEO_HIFI_AUDIO:
+ case Device.AUDIO_VIDEO_SET_TOP_BOX:
+ case Device.AUDIO_VIDEO_VCR:
+ return true;
+ default:
+ return false;
+ }
+ } else if (profile == PROFILE_HEADSET) {
+ // The render service class is required by the spec for HFP, so is a
+ // pretty good signal
+ if (hasService(Service.RENDER)) {
+ return true;
+ }
+ // Just in case they forgot the render service class
+ switch (getDeviceClass()) {
+ case Device.AUDIO_VIDEO_HANDSFREE:
+ case Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+ case Device.AUDIO_VIDEO_CAR_AUDIO:
+ return true;
+ default:
+ return false;
+ }
+ } else if (profile == PROFILE_OPP) {
+ if (hasService(Service.OBJECT_TRANSFER)) {
+ return true;
+ }
+
+ switch (getDeviceClass()) {
+ case Device.COMPUTER_UNCATEGORIZED:
+ case Device.COMPUTER_DESKTOP:
+ case Device.COMPUTER_SERVER:
+ case Device.COMPUTER_LAPTOP:
+ case Device.COMPUTER_HANDHELD_PC_PDA:
+ case Device.COMPUTER_PALM_SIZE_PC_PDA:
+ case Device.COMPUTER_WEARABLE:
+ case Device.PHONE_UNCATEGORIZED:
+ case Device.PHONE_CELLULAR:
+ case Device.PHONE_CORDLESS:
+ case Device.PHONE_SMART:
+ case Device.PHONE_MODEM_OR_GATEWAY:
+ case Device.PHONE_ISDN:
+ return true;
+ default:
+ return false;
+ }
+ } else if (profile == PROFILE_HID) {
+ return (getDeviceClass() & Device.Major.PERIPHERAL) == Device.Major.PERIPHERAL;
+ } else if (profile == PROFILE_PANU || profile == PROFILE_NAP) {
+ // No good way to distinguish between the two, based on class bits.
+ if (hasService(Service.NETWORKING)) {
+ return true;
+ }
+ return (getDeviceClass() & Device.Major.NETWORKING) == Device.Major.NETWORKING;
+ } else {
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java
index 0a89d03d1dd2121598eb78c7370d14220fec2ffa..ce4da8470b25c7a3eeca531be956f435cea932fc 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java
@@ -1,48 +1,43 @@
-package uk.co.alt236.bluetoothlelib.device;
-
-import android.Manifest;
-import android.bluetooth.BluetoothDevice;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+package uk.co.alt236.bluetoothlelib.device;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresPermission;
+import ohos.bluetooth.ble.BleScanResult;
+import ohos.utils.Parcel;
+import ohos.utils.Sequenceable;
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecordStore;
-import uk.co.alt236.bluetoothlelib.resolvers.BluetoothClassResolver;
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
import uk.co.alt236.bluetoothlelib.util.LimitedLinkHashMap;
-// TODO: Auto-generated Javadoc
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
/**
- * This is a wrapper around the default BluetoothDevice object
- * As BluetoothDevice is final it cannot be extended, so to get it you
+ * This is a wrapper around the default BleScanResult object
+ * As BleScanResult is final it cannot be extended, so to get it you
* need to call {@link #getDevice()} method.
*
* @author Alexandros Schillings
*/
-public class BluetoothLeDevice implements Parcelable {
- /**
- * The Constant CREATOR.
- */
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public BluetoothLeDevice createFromParcel(final Parcel in) {
- return new BluetoothLeDevice(in);
+public class BluetoothLeDevice implements Sequenceable {
+
+ //反序列化功能
+ public static final Producer PRODUCER = new Producer() {
+
+ public BluetoothLeDevice createFromParcel(Parcel in) {
+ // Initialize an instance first, then do customized unmarshlling.
+ BluetoothLeDevice adrecordstore = new BluetoothLeDevice();
+ adrecordstore.unmarshalling(in);
+ return adrecordstore;
}
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";
@@ -53,15 +48,14 @@ public class BluetoothLeDevice implements Parcelable {
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 mRssiLog;
- private final byte[] mScanRecord;
- private final int mFirstRssi;
- private final long mFirstTimestamp;
+ private AdRecordStore mRecordStore;
+ private BleScanResult mDevice;
+ private Map mRssiLog;
+ private byte[] mScanRecord;
+ private int mFirstRssi;
+ private long mFirstTimestamp;
private int mCurrentRssi;
private long mCurrentTimestamp;
- private transient Set mServiceSet;
/**
* Instantiates a new Bluetooth LE device.
@@ -71,18 +65,18 @@ public class BluetoothLeDevice implements Parcelable {
* @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) {
+ public BluetoothLeDevice(final BleScanResult device, final int rssi, final byte[] scanRecord, final long timestamp) {
mDevice = device;
mFirstRssi = rssi;
mFirstTimestamp = timestamp;
mRecordStore = new AdRecordStore(AdRecordUtils.parseScanRecordAsSparseArray(scanRecord));
- mScanRecord = scanRecord;
+ this.mScanRecord = scanRecord.clone();
mRssiLog = new LimitedLinkHashMap<>(MAX_RSSI_LOG_SIZE);
updateRssiReading(timestamp, rssi);
}
/**
- * Instantiates a new Bluetooth LE device.
+ * Instantiates a new Bluetooth LE device
*
* @param device the device
*/
@@ -98,23 +92,8 @@ public class BluetoothLeDevice implements Parcelable {
mScanRecord = device.getScanRecord();
}
- /**
- * Instantiates a new bluetooth le device.
- *
- * @param in the in
- */
- @SuppressWarnings("unchecked")
- 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) b.getSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG);
- mScanRecord = b.getByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD);
+ public BluetoothLeDevice() {
+
}
/**
@@ -135,14 +114,6 @@ public class BluetoothLeDevice implements Parcelable {
}
}
- /* (non-Javadoc)
- * @see android.os.Parcelable#describeContents()
- */
- @Override
- public int describeContents() {
- return 0;
- }
-
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@@ -198,7 +169,7 @@ public class BluetoothLeDevice implements Parcelable {
* @return the address
*/
public String getAddress() {
- return mDevice.getAddress();
+ return mDevice.getPeripheralDevice().getDeviceAddr();
}
/**
@@ -206,49 +177,8 @@ public class BluetoothLeDevice implements Parcelable {
*
* @return the bluetooth device bond state
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
public String getBluetoothDeviceBondState() {
- return resolveBondingState(mDevice.getBondState());
- }
-
- /**
- * Gets the bluetooth device class name.
- *
- * @return the bluetooth device class name
- */
- @RequiresPermission(Manifest.permission.BLUETOOTH)
- public String getBluetoothDeviceClassName() {
- return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
- }
-
- @RequiresPermission(Manifest.permission.BLUETOOTH)
- public Set getBluetoothDeviceKnownSupportedServices() {
- if (mServiceSet == null) {
- synchronized (this) {
- if (mServiceSet == null) {
- final Set serviceSet = new HashSet<>();
- for (final BluetoothService service : BluetoothService.values()) {
-
- if (mDevice.getBluetoothClass().hasService(service.getAndroidConstant())) {
- serviceSet.add(service);
- }
- }
- mServiceSet = Collections.unmodifiableSet(serviceSet);
- }
- }
- }
-
- return mServiceSet;
- }
-
- /**
- * Gets the bluetooth device major class name.
- *
- * @return the bluetooth device major class name
- */
- @RequiresPermission(Manifest.permission.BLUETOOTH)
- public String getBluetoothDeviceMajorClassName() {
- return BluetoothClassResolver.resolveMajorDeviceClass(mDevice.getBluetoothClass().getMajorDeviceClass());
+ return resolveBondingState(mDevice.getAdvertiseFlag());
}
/**
@@ -256,7 +186,7 @@ public class BluetoothLeDevice implements Parcelable {
*
* @return the device
*/
- public BluetoothDevice getDevice() {
+ public BleScanResult getDevice() {
return mDevice;
}
@@ -278,15 +208,12 @@ public class BluetoothLeDevice implements Parcelable {
return mFirstTimestamp;
}
- /**
- * Gets the name.
- *
- * @return the name
- */
- @RequiresPermission(Manifest.permission.BLUETOOTH)
- @Nullable
public String getName() {
- return mDevice.getName();
+ Optional deviceName = mDevice.getPeripheralDevice().getDeviceName();
+ if (deviceName.isPresent()) {
+ return deviceName.get();
+ }
+ return "Unknown device";
}
/**
@@ -303,7 +230,7 @@ public class BluetoothLeDevice implements Parcelable {
*
* @return the rssi log
*/
- protected Map getRssiLog() {
+ private Map getRssiLog() {
synchronized (mRssiLog) {
return mRssiLog;
}
@@ -317,21 +244,17 @@ public class BluetoothLeDevice implements Parcelable {
public double getRunningAverageRssi() {
int sum = 0;
int count = 0;
-
synchronized (mRssiLog) {
-
- for (final Long aLong : mRssiLog.keySet()) {
+ for (Map.Entry entry : mRssiLog.entrySet()) {
count++;
- sum += mRssiLog.get(aLong);
+ sum += mRssiLog.get(entry.getKey());
}
}
-
if (count > 0) {
- return sum / count;
+ return (float) sum / count;
} else {
return 0;
}
-
}
/**
@@ -340,7 +263,8 @@ public class BluetoothLeDevice implements Parcelable {
* @return the scan record
*/
public byte[] getScanRecord() {
- return mScanRecord;
+ byte[] clone = mScanRecord.clone();
+ return clone;
}
/**
@@ -374,9 +298,8 @@ public class BluetoothLeDevice implements Parcelable {
* @see java.lang.Object#toString()
*/
@Override
- @RequiresPermission(Manifest.permission.BLUETOOTH)
public String toString() {
- return "BluetoothLeDevice [mDevice=" + mDevice + ", mRssi=" + mFirstRssi + ", mScanRecord=" + ByteUtils.byteArrayToHexString(mScanRecord) + ", mRecordStore=" + mRecordStore + ", getBluetoothDeviceBondState()=" + getBluetoothDeviceBondState() + ", getBluetoothDeviceClassName()=" + getBluetoothDeviceClassName() + "]";
+ return "BluetoothLeDevice [mDevice=" + mDevice + ", mRssi=" + mFirstRssi + ", mScanRecord=" + ByteUtils.byteArrayToHexString(mScanRecord) + ", mRecordStore=" + mRecordStore + ", getBleScanResult BondState()=" + ", getBleScanResult ClassName()=" + "]";
}
/**
@@ -389,44 +312,42 @@ public class BluetoothLeDevice implements Parcelable {
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) {
+ private String resolveBondingState(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";
}
}
-}
+
+ @Override
+ public boolean marshalling(Parcel parcel) {
+ parcel.writeSequenceable(mRecordStore);
+ parcel.writeSequenceable(mDevice);
+ parcel.writeMap(mRssiLog);
+ parcel.writeByteArray(mScanRecord);
+ parcel.writeInt(mFirstRssi);
+ parcel.writeLong(mFirstTimestamp);
+ parcel.writeInt(mCurrentRssi);
+ parcel.writeLong(mCurrentTimestamp);
+ return true;
+ }
+
+ @Override
+ public boolean unmarshalling(Parcel parcel) {
+ mRecordStore = (AdRecordStore) parcel.readValue();
+ mDevice = (BleScanResult) parcel.readValue();
+ mRssiLog = (Map) parcel.readMap();
+ mScanRecord = parcel.readByteArray();
+ mFirstRssi = parcel.readInt();
+ mFirstTimestamp = parcel.readInt();
+ mCurrentRssi = parcel.readInt();
+ mCurrentTimestamp = parcel.readInt();
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothService.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothService.java
index c4ec277ba6b1881a1a8d9c176a849ec3b8d9c618..8b17c501ecf1d4559af037bf6bf2abb7a92d8312 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothService.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothService.java
@@ -1,11 +1,7 @@
package uk.co.alt236.bluetoothlelib.device;
-import android.bluetooth.BluetoothClass;
-
-/**
- *
- */
public enum BluetoothService {
+
AUDIO(BluetoothClass.Service.AUDIO),
CAPTURE(BluetoothClass.Service.CAPTURE),
INFORMATION(BluetoothClass.Service.INFORMATION),
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/adrecord/AdRecord.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/adrecord/AdRecord.java
index f4f45c414d50aa074d50176f46774d66960c9131..bea189b4a749b807207c1cf3ad1c638cfbdca3f4 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/adrecord/AdRecord.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/adrecord/AdRecord.java
@@ -1,52 +1,18 @@
package uk.co.alt236.bluetoothlelib.device.adrecord;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
+import ohos.utils.Parcel;
+import ohos.utils.Sequenceable;
import java.util.Arrays;
-import androidx.annotation.Nullable;
-
/**
* Created by Dave Smith
* Double Encore, Inc.
*
* Expanded by Alexandros Schillings
*/
-public final class AdRecord implements Parcelable {
- // 02 # Number of bytes that follow in first AD structure
- // 01 # Flags AD type
- // 1A # Flags value 0x1A = 000011010
- // bit 0 (OFF) LE Limited Discoverable Mode
- // bit 1 (ON) LE General Discoverable Mode
- // bit 2 (OFF) BR/EDR Not Supported
- // bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
- // bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
- // 1A # Number of bytes that follow in second (and last) AD structure
- // FF # Manufacturer specific data AD type
- // 4C 00 # Company identifier code (0x004C == Apple)
- // 02 # Byte 0 of iBeacon advertisement indicator
- // 15 # Byte 1 of iBeacon advertisement indicator
- // e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon proximity uuid
- // 00 00 # major
- // 00 00 # minor
- // c5 # The 2's complement of the calibrated Tx Power
-
-
- /**
- * General FLAGS
- *
- * Description: Flags
- *
- * Information:
- * Bit 0: LE Limited Discoverable Mode
- * Bit 1: LE General Discoverable Mode
- * Bit 2: BR/EDR Not Supported (i.e. bit 37 of LMP Extended Feature bits Page 0)
- * Bit 3: Simultaneous LE and BR/EDR to Same Device Capable (Controller) (i.e. bit 49 of LMP Extended Feature bits Page 0)
- * Bit 4: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
- * Bits 5-7 Reserved
- */
+public final class AdRecord implements Sequenceable {
+
public static final int TYPE_FLAGS = 0x01;
// SERVICE
public static final int TYPE_UUID16_INC = 0x02;
@@ -113,44 +79,41 @@ public final class AdRecord implements Parcelable {
* Information: The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data
*/
public static final int TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public AdRecord createFromParcel(final Parcel in) {
- return new AdRecord(in);
+
+ //反序列化功能
+ public static final Producer PRODUCER = new Producer() {
+
+ public AdRecord createFromParcel(Parcel in) {
+ // Initialize an instance first, then do customized unmarshlling.
+ AdRecord adrecordstore = new AdRecord();
+ adrecordstore.unmarshalling(in);
+ return adrecordstore;
}
- public AdRecord[] newArray(final int size) {
- return new AdRecord[size];
+ public AdRecordStore[] newArray(final int size) {
+ return new AdRecordStore[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;
+ private int mLength;
+ private int mType;
+ private byte[] mData;
+
+ public AdRecord() {
+ }
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;
+ if (data != null) {
+ this.mData = data.clone();
+ }
}
- @Nullable
public byte[] getData() {
- return mData;
+ byte[] temp = mData;
+ return temp;
}
public String getHumanReadableType() {
@@ -170,17 +133,6 @@ public final class AdRecord implements Parcelable {
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 TYPE_CONNECTION_INTERVAL_RANGE:
@@ -227,4 +179,20 @@ public final class AdRecord implements Parcelable {
return "Unknown AdRecord Structure: " + type;
}
}
+
+ @Override
+ public boolean marshalling(Parcel parcel) {
+ parcel.writeInt(mLength);
+ parcel.writeInt(mType);
+ parcel.writeByteArray(mData);
+ return true;
+ }
+
+ @Override
+ public boolean unmarshalling(Parcel parcel) {
+ mLength = parcel.readInt();
+ mType = parcel.readInt();
+ mData = parcel.readByteArray();
+ return true;
+ }
}
\ No newline at end of file
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/adrecord/AdRecordStore.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/adrecord/AdRecordStore.java
index a0993bdaa89e126087f2a3e37ee50d8bfb616602..7411a7a5a1188f4ea1a26fb6576a8d8722528bd2 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/adrecord/AdRecordStore.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/adrecord/AdRecordStore.java
@@ -1,63 +1,54 @@
package uk.co.alt236.bluetoothlelib.device.adrecord;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.SparseArray;
+import ohos.utils.Parcel;
+import ohos.utils.Sequenceable;
+import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-
-import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
+import java.util.HashMap;
/**
* The Class AdRecordStore.
*/
-public class AdRecordStore implements Parcelable {
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public AdRecordStore createFromParcel(final Parcel in) {
- return new AdRecordStore(in);
- }
+public class AdRecordStore implements Sequenceable {
- public AdRecordStore[] newArray(final int size) {
- return new AdRecordStore[size];
- }
- };
- private final SparseArray 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");
- }
+ private HashMap mAdRecords;
+ private String mLocalNameComplete;
+ private String mLocalNameShort;
+ public AdRecordStore(){
+
+ }
+
/**
* Instantiates a new Bluetooth LE device Ad Record Store.
*
* @param adRecords the ad records
*/
- public AdRecordStore(final SparseArray adRecords) {
+ public AdRecordStore(final HashMap adRecords) {
mAdRecords = adRecords;
-
- mLocalNameComplete = AdRecordUtils.getRecordDataAsString(
- mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_COMPLETE));
-
+ mLocalNameComplete = AdRecordUtils.getRecordDataAsString(mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_COMPLETE));
mLocalNameShort = AdRecordUtils.getRecordDataAsString(
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_SHORT));
}
- /* (non-Javadoc)
- * @see android.os.Parcelable#describeContents()
- */
- @Override
- public int describeContents() {
- return 0;
- }
+ //反序列化功能
+ public static final Producer PRODUCER = new Producer() {
+
+ public AdRecordStore createFromParcel(Parcel in) {
+ // Initialize an instance first, then do customized unmarshlling.
+ AdRecordStore adrecordstore = new AdRecordStore();
+ adrecordstore.unmarshalling(in);
+ return adrecordstore;
+ }
+
+ public AdRecordStore[] newArray(final int size) {
+ return new AdRecordStore[size];
+ }
+ };
/**
* Gets the short local device name.
@@ -114,7 +105,7 @@ public class AdRecordStore implements Parcelable {
* @return true, if is record present
*/
public boolean isRecordPresent(final int record) {
- return mAdRecords.indexOfKey(record) >= 0;
+ return mAdRecords.containsKey(record);
}
/* (non-Javadoc)
@@ -125,19 +116,6 @@ public class AdRecordStore implements Parcelable {
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.
*
@@ -145,14 +123,31 @@ public class AdRecordStore implements Parcelable {
* @param sparseArray the sparse array
* @return the collection
*/
- public static Collection asList(final SparseArray sparseArray) {
- if (sparseArray == null) return null;
+ public static Collection asList(final HashMap sparseArray) {
+ if (sparseArray == null){
+ return null;
+ }
final Collection arrayList = new ArrayList<>(sparseArray.size());
for (int i = 0; i < sparseArray.size(); i++) {
- arrayList.add(sparseArray.valueAt(i));
+ arrayList.add(sparseArray.get(i));
}
-
return arrayList;
}
+
+ @Override
+ public boolean marshalling(Parcel parcel) {
+ parcel.writeMap(mAdRecords);
+ parcel.writeString(mLocalNameComplete);
+ parcel.writeString(mLocalNameShort);
+ return true;
+ }
+
+ @Override
+ public boolean unmarshalling(Parcel parcel) {
+ mAdRecords = (HashMap) parcel.readMap();
+ mLocalNameComplete = parcel.readString();
+ mLocalNameShort = parcel.readString();
+ return true;
+ }
}
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconDevice.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconDevice.java
index f4d682c7be1517a7d656db7003e5c733ee0078c5..e47744cd2e2a8b392ffb612f09d13b324a507063 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconDevice.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconDevice.java
@@ -1,8 +1,5 @@
package uk.co.alt236.bluetoothlelib.device.beacon;
-/**
- *
- */
public interface BeaconDevice {
BeaconType getBeaconType();
}
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconManufacturerData.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconManufacturerData.java
index ebabbce92d5ec02c517e8dbb0b3e52e6fd7204ee..532750912180c07f6466dcd4711b0ac4d2321253 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconManufacturerData.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconManufacturerData.java
@@ -26,6 +26,7 @@ public abstract class BeaconManufacturerData {
}
public byte[] getData(){
- return mData;
+ byte[] clone = mData.clone();
+ return clone;
}
}
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java
index 294f906a843450095c042827357ccdfac3a56be4..feed5902d5fb5fc5535eeaf7e2dc3c9f61a3d717 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java
@@ -33,9 +33,9 @@ public final class BeaconUtils {
}
/**
- * Ascertains whether a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} is an iBeacon;
+ * Ascertains whether a {@link BluetoothLeDevice} is an iBeacon;
*
- * @param device a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} device.
+ * @param device a {@link BluetoothLeDevice} device.
* @return the {@link BeaconType}
*/
public static BeaconType getBeaconType(final BluetoothLeDevice device) {
@@ -48,8 +48,8 @@ public final class BeaconUtils {
if (!(manufacturerData.length >= 25)) {
return false;
}
-
- if (ByteUtils.doesArrayBeginWith(manufacturerData, IBeaconConstants.MANUFACTURER_DATA_IBEACON_PREFIX)) {
+ byte[] dataIbeaconPrefix = {0x4C, 0x00, 0x02, 0x15};
+ if (ByteUtils.doesArrayBeginWith(manufacturerData, dataIbeaconPrefix)) {
return true;
}
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconConstants.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconConstants.java
index 6c1914fda5bd8e5bf14453d594b0a60416a2c412..d3a68ab14e2fbfd6fb805d938102239f0087e148 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconConstants.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconConstants.java
@@ -1,9 +1,5 @@
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
-/**
- *
- */
public class IBeaconConstants {
public static final byte[] MANUFACTURER_DATA_IBEACON_PREFIX = {0x4C, 0x00, 0x02, 0x15};
-
}
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java
index 4b65b455e0c37a549c84be64ebb91e42a07bdc11..cd945203f74f9036cea6b0f1c6fbb923d6f0f1c6 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java
@@ -1,12 +1,10 @@
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
-import android.bluetooth.BluetoothDevice;
-import android.os.Parcel;
-
+import ohos.bluetooth.ble.BleScanResult;
+import ohos.utils.Parcel;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconDevice;
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
-import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils;
public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
@@ -23,7 +21,7 @@ public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
* @param scanRecord the scanRecord
* @throws IllegalArgumentException if the passed device is not an iBeacon
*/
- public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
+ public IBeaconDevice(final BleScanResult device, final int rssi, final byte[] scanRecord) {
super(device, rssi, scanRecord, 0);
mIBeaconData = new IBeaconManufacturerData(this);
}
@@ -37,7 +35,7 @@ public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
* @param timestamp the timestamp of the RSSI measurement
* @throws IllegalArgumentException if the passed device is not an iBeacon
*/
- public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
+ public IBeaconDevice(final BleScanResult device, final int rssi, final byte[] scanRecord, final long timestamp) {
super(device, rssi, scanRecord, timestamp);
mIBeaconData = new IBeaconManufacturerData(this);
}
@@ -55,7 +53,6 @@ public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
}
private IBeaconDevice(final Parcel in) {
- super(in);
mIBeaconData = new IBeaconManufacturerData(this);
}
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java
index 4c7d706063824be050791c86ee6af74a7b5196af..20352cd2a4123888af77cae325a2627118843971 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java
@@ -1,13 +1,13 @@
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
-import java.util.Arrays;
-
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
+import java.util.Arrays;
+
/**
* Parses the Manufactured Data field of an iBeacon
*
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/resolvers/BluetoothClassResolver.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/resolvers/BluetoothClassResolver.java
index 9697ee941128075741d48a0dcbb89c3ffeac4c98..d458391b92444f7835b1c9baede71a59861c98ee 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/resolvers/BluetoothClassResolver.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/resolvers/BluetoothClassResolver.java
@@ -1,6 +1,6 @@
package uk.co.alt236.bluetoothlelib.resolvers;
-import android.bluetooth.BluetoothClass;
+import uk.co.alt236.bluetoothlelib.device.BluetoothClass;
public class BluetoothClassResolver {
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/resolvers/CompanyIdentifierResolver.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/resolvers/CompanyIdentifierResolver.java
index 2a7271fa64cdb2da3d7cb2d00058bba3aa642425..3f12cb9a315ca2a8711ab0630fdbfeb66af4f18f 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/resolvers/CompanyIdentifierResolver.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/resolvers/CompanyIdentifierResolver.java
@@ -1,6 +1,6 @@
package uk.co.alt236.bluetoothlelib.resolvers;
-import android.util.SparseArray;
+import java.util.HashMap;
public class CompanyIdentifierResolver {
public static final int ERICSSON_TECHNOLOGY_LICENSING = 0x0000;
@@ -316,15 +316,15 @@ public class CompanyIdentifierResolver {
public static final int ETC_SP_ZOO = 0x0136;
public static final int PRESTIGIO_PLAZA_LTD = 0x0137;
- private static final SparseArray COMPANY_NAME_MAP = populateCompanyNameMap();
+ private static final HashMap 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 populateCompanyNameMap() {
- final SparseArray map = new SparseArray<>();
+ private static HashMap populateCompanyNameMap() {
+ final HashMap map = new HashMap<>();
map.put(ERICSSON_TECHNOLOGY_LICENSING, "Ericsson Technology Licensing");
map.put(NOKIA_MOBILE_PHONES, "Nokia Mobile Phones");
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtils.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtils.java
index 0dda9f2106851c078fb01e15aec3dafe1a296312..e61a79072552ed8d6073320743ffc7d879c7b2ac 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtils.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtils.java
@@ -1,26 +1,17 @@
package uk.co.alt236.bluetoothlelib.util;
-import android.annotation.SuppressLint;
-import android.util.SparseArray;
+import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import androidx.annotation.Nullable;
-import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
+import java.util.*;
public final class AdRecordUtils {
- private AdRecordUtils(){
+ private AdRecordUtils() {
// TO AVOID INSTANTIATION
}
- public static String getRecordDataAsString(@Nullable final AdRecord record) {
+ public static String getRecordDataAsString(final AdRecord record) {
if (record == null) {
return "";
}
@@ -28,8 +19,7 @@ public final class AdRecordUtils {
return toString(record.getData());
}
- @Nullable
- public static byte[] getServiceData(@Nullable final AdRecord record) {
+ public static byte[] getServiceData(final AdRecord record) {
if (record == null) {
return null;
}
@@ -43,7 +33,7 @@ public final class AdRecordUtils {
return Arrays.copyOfRange(raw, 2, raw.length);
}
- public static int getServiceDataUuid(@Nullable final AdRecord record) {
+ public static int getServiceDataUuid(final AdRecord record) {
if (record == null) {
return -1;
}
@@ -89,7 +79,6 @@ public final class AdRecordUtils {
return Collections.unmodifiableList(records);
}
- @SuppressLint("UseSparseArrays")
public static Map parseScanRecordAsMap(final byte[] scanRecord) {
final Map records = new HashMap<>();
@@ -115,8 +104,8 @@ public final class AdRecordUtils {
return Collections.unmodifiableMap(records);
}
- public static SparseArray parseScanRecordAsSparseArray(final byte[] scanRecord) {
- final SparseArray records = new SparseArray<>();
+ public static HashMap parseScanRecordAsSparseArray(final byte[] scanRecord) {
+ final HashMap records = new HashMap<>();
int index = 0;
while (index < scanRecord.length) {
@@ -140,7 +129,7 @@ public final class AdRecordUtils {
return records;
}
- private static String toString(@Nullable byte[] array) {
+ private static String toString(byte[] array) {
if (array == null) {
return "";
}
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/util/ByteUtils.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/util/ByteUtils.java
index 7cf3aedd62b0f2bb262219a0095aeb45b3b808c5..98b8ca165f7668a560c812615fa181e729018e1e 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/util/ByteUtils.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/util/ByteUtils.java
@@ -2,8 +2,6 @@ package uk.co.alt236.bluetoothlelib.util;
import java.nio.ByteBuffer;
-import androidx.annotation.Nullable;
-
public class ByteUtils {
/**
@@ -23,7 +21,7 @@ public class ByteUtils {
* @param array the array
* @return the string
*/
- public static String byteArrayToHexString(@Nullable final byte[] array) {
+ public static String byteArrayToHexString(final byte[] array) {
final byte[] safeArray = array == null ? new byte[0] : array;
final StringBuilder sb = new StringBuilder();
boolean firstEntry = true;
diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/util/LimitedLinkHashMap.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/util/LimitedLinkHashMap.java
index f7c41365c6e63a4c2d82c962fbe5fd1bcb873696..4eef43e5f82e70d7b35ed541366a8a9fd2928ff1 100644
--- a/library/src/main/java/uk/co/alt236/bluetoothlelib/util/LimitedLinkHashMap.java
+++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/util/LimitedLinkHashMap.java
@@ -1,9 +1,9 @@
package uk.co.alt236.bluetoothlelib.util;
import java.util.LinkedHashMap;
-import java.util.Map;
public class LimitedLinkHashMap extends LinkedHashMap {
+
private static final long serialVersionUID = -5375660288461724925L;
private final int mMaxSize;
@@ -13,8 +13,8 @@ public class LimitedLinkHashMap extends LinkedHashMap {
mMaxSize = maxSize;
}
- @Override
- protected boolean removeEldestEntry(final Map.Entry eldest) {
- return this.size() > mMaxSize;
- }
+// @Override
+// public boolean removeEldestEntry(final Entry eldest) {
+// return this.size() > mMaxSize;
+// }
}
diff --git a/library/src/main/resources/base/element/string.json b/library/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..1e2b219ccdd1183e23968586e5e2e404b41c38c9
--- /dev/null
+++ b/library/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "library"
+ }
+ ]
+}
diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/ExampleTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..46497d4a30624f7613d91bbf3bc2561ba939c068
--- /dev/null
+++ b/library/src/test/java/uk/co/alt236/bluetoothlelib/ExampleTest.java
@@ -0,0 +1,9 @@
+package uk.co.alt236.bluetoothlelib;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtilsTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtilsTest.java
deleted file mode 100644
index 1de810e2b8713044bda308869e85948ccd3cf6e5..0000000000000000000000000000000000000000
--- a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtilsTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package uk.co.alt236.bluetoothlelib.device.beacon;
-
-import junit.framework.TestCase;
-
-/**
- *
- */
-public class BeaconUtilsTest extends TestCase {
-
- public void testGetBeaconTypeIBeacon() throws Exception {
- assertEquals(BeaconType.IBEACON, BeaconUtils.getBeaconType(new byte[]{
- 0x4C, 0x00, 0x02, 0x15, 0x00, // <- Magic iBeacon header
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00
- }));
- }
-
- public void testGetBeaconTypeInvalid() throws Exception {
- assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType((byte[]) null));
- assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[0]));
- assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[25]));
- }
-}
\ No newline at end of file
diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerDataTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerDataTest.java
deleted file mode 100644
index cef150b0de765d779ce3fb9b0cab90e6cead53d7..0000000000000000000000000000000000000000
--- a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerDataTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
-
-import junit.framework.TestCase;
-
-import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
-
-/**
- *
- */
-public class IBeaconManufacturerDataTest extends TestCase {
- private static final byte[] NON_BEACON =
- {2, 1, 26, 11, -1, 76, 0, 9, 6, 3, -32, -64, -88,
- 1, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
- public void testNonIBeaconData() throws Exception{
- try {
- BeaconManufacturerData data = new IBeaconManufacturerData(NON_BEACON);
- fail("Should have thrown an exception");
- } catch (final IllegalArgumentException e){
- // EXPECTED
- }
-
- try {
- BeaconManufacturerData data = new IBeaconManufacturerData((byte[]) null);
- fail("Should have thrown an exception");
- } catch (final IllegalArgumentException e){
- // EXPECTED
- }
-
- try {
- BeaconManufacturerData data = new IBeaconManufacturerData(new byte[0]);
- fail("Should have thrown an exception");
- } catch (final IllegalArgumentException e){
- // EXPECTED
- }
- }
-}
\ No newline at end of file
diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconUtilsTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconUtilsTest.java
deleted file mode 100644
index 7399ed055c5a61976603ec2e29ccf7b75f569996..0000000000000000000000000000000000000000
--- a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconUtilsTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
-
-import junit.framework.TestCase;
-
-/**
- *
- */
-public class IBeaconUtilsTest extends TestCase {
-
- public void testCalculateUuidString() throws Exception {
- assertEquals("00", IBeaconUtils.calculateUuidString(new byte[]{0}));
- assertEquals("0a", IBeaconUtils.calculateUuidString(new byte[]{10}));
- assertEquals("0f", IBeaconUtils.calculateUuidString(new byte[]{15}));
- assertEquals("10", IBeaconUtils.calculateUuidString(new byte[]{16}));
- assertEquals("7f", IBeaconUtils.calculateUuidString(new byte[]{127}));
- assertEquals(
- "00000000-0000-0000-0000-00",
- IBeaconUtils.calculateUuidString(new byte[]{0,0,0,0,0,0,0,0,0,0,0}));
- }
-
- public void testGetDistanceDescriptor() throws Exception {
- assertEquals(IBeaconDistanceDescriptor.UNKNOWN, IBeaconUtils.getDistanceDescriptor(-1));
-
- assertEquals(IBeaconDistanceDescriptor.IMMEDIATE, IBeaconUtils.getDistanceDescriptor(0));
- assertEquals(IBeaconDistanceDescriptor.IMMEDIATE, IBeaconUtils.getDistanceDescriptor(0.4));
-
- assertEquals(IBeaconDistanceDescriptor.NEAR, IBeaconUtils.getDistanceDescriptor(0.5));
- assertEquals(IBeaconDistanceDescriptor.NEAR, IBeaconUtils.getDistanceDescriptor(2.9));
-
- assertEquals(IBeaconDistanceDescriptor.FAR, IBeaconUtils.getDistanceDescriptor(3));
- }
-}
\ No newline at end of file
diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/resolvers/GattAttributeResolverTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/resolvers/GattAttributeResolverTest.java
deleted file mode 100644
index 6b482c9e62783acd1f350237c0cc2278ee0bcf07..0000000000000000000000000000000000000000
--- a/library/src/test/java/uk/co/alt236/bluetoothlelib/resolvers/GattAttributeResolverTest.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package uk.co.alt236.bluetoothlelib.resolvers;
-
-import junit.framework.TestCase;
-
-/**
- *
- */
-public class GattAttributeResolverTest extends TestCase {
- private static final String UKNOWN = "unknown";
-
- public void testGetAttributeName() throws Exception {
- assertEquals(UKNOWN, GattAttributeResolver.getAttributeName("foo", UKNOWN));
- assertEquals("Estimote Advertising Vector", GattAttributeResolver.getAttributeName("b9402002-f5f8-466e-aff9-25556b57fe6d", UKNOWN));
- assertEquals("LINK_LOSS", GattAttributeResolver.getAttributeName("00001803-0000-1000-8000-00805f9b34fb", UKNOWN));
- assertEquals("Base GUID", GattAttributeResolver.getAttributeName("00000000-0000-1000-8000-00805f9b34fb", UKNOWN));
- assertEquals("PNPID", GattAttributeResolver.getAttributeName("00002a50-0000-1000-8000-00805f9b34fb", UKNOWN));
- assertEquals("HTTP", GattAttributeResolver.getAttributeName("0000000c-0000-1000-8000-00805f9b34fb", UKNOWN));
-
- }
-}
\ No newline at end of file
diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtilsTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtilsTest.java
deleted file mode 100644
index d528dd8e95dd4f9ad6796370890fbdadc6dde459..0000000000000000000000000000000000000000
--- a/library/src/test/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtilsTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package uk.co.alt236.bluetoothlelib.util;
-
-import junit.framework.TestCase;
-
-import java.util.List;
-import java.util.Map;
-
-import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
-
-/**
- *
- */
-public class AdRecordUtilsTest extends TestCase {
- private static final byte[] NON_IBEACON =
- {2, 1, 26, 11, -1, 76, 0, 9, 6, 3, -32, -64, -88,
- 1, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
- public void testParseScanRecordAsList() throws Exception {
- final List adRecords = AdRecordUtils.parseScanRecordAsList(NON_IBEACON);
- assertNotNull(adRecords);
- assertEquals(2, adRecords.size());
-
- int type = AdRecord.TYPE_FLAGS;
- assertEquals(type, adRecords.get(0).getType());
- assertEquals(2, adRecords.get(0).getLength());
-
- type = AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA;
- assertEquals(type, adRecords.get(1).getType());
- assertEquals(11, adRecords.get(1).getLength());
- }
-
- public void testParseScanRecordAsMap() throws Exception {
- final Map adRecords = AdRecordUtils.parseScanRecordAsMap(NON_IBEACON);
- assertNotNull(adRecords);
- assertEquals(2, adRecords.size());
-
- int type = AdRecord.TYPE_FLAGS;
- assertEquals(type, adRecords.get(type).getType());
- assertEquals(2, adRecords.get(type).getLength());
-
- type = AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA;
- assertEquals(type, adRecords.get(type).getType());
- assertEquals(11, adRecords.get(type).getLength());
- }
-
- public void testParseScanRecordAsSparseArray() throws Exception {
- //
- // Cannot be tested here as it relies on Android code...
- //
- // final SparseArray adRecords = AdRecordUtils.parseScanRecordAsSparseArray(NON_IBEACON);
- // assertNotNull(adRecords);
- // assertEquals(2, adRecords.size());
- // assertEquals(AdRecord.TYPE_FLAGS, adRecords.get(AdRecord.TYPE_FLAGS).getType());
- // assertEquals(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA, adRecords.get(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getType());
- }
-}
\ No newline at end of file
diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/util/ByteUtilsTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/util/ByteUtilsTest.java
deleted file mode 100644
index 0d563582dc5518420af551bf524f3500d85076d6..0000000000000000000000000000000000000000
--- a/library/src/test/java/uk/co/alt236/bluetoothlelib/util/ByteUtilsTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package uk.co.alt236.bluetoothlelib.util;
-
-import junit.framework.TestCase;
-
-/**
- *
- */
-public class ByteUtilsTest extends TestCase {
-
- public void testByteArrayToHexString() throws Exception {
- assertEquals("[]", ByteUtils.byteArrayToHexString(new byte[0]));
-
- assertEquals("[]", ByteUtils.byteArrayToHexString(null));
-
- final byte[] one = {1, 10, 15, 127};
- assertEquals("[01, 0A, 0F, 7F]", ByteUtils.byteArrayToHexString(one));
- }
-
- public void testDoesArrayBeginWith() throws Exception {
-
- // If the prefix is longer than the array,
- // we automatically fail
- byte[] array = new byte[10];
- byte[] prefix = new byte[array.length * 2];
- assertFalse(ByteUtils.doesArrayBeginWith(array, prefix));
-
- array = new byte[]{1, 2, 3};
- prefix = new byte[]{1, 3};
- assertFalse(ByteUtils.doesArrayBeginWith(array, prefix));
-
- array = new byte[10];
- prefix = new byte[array.length];
- assertTrue(ByteUtils.doesArrayBeginWith(array, prefix));
-
- array = new byte[]{1, 2, 3};
- prefix = new byte[]{1, 2};
- assertTrue(ByteUtils.doesArrayBeginWith(array, prefix));
- }
-
- public void testGetIntFromByte() throws Exception {
- byte bite = 127;
- int integer = ByteUtils.getIntFromByte(bite);
- assertEquals(127, integer);
-
- bite = -1;
- integer = ByteUtils.getIntFromByte(bite);
- assertEquals(255, integer);
- }
-
- public void testInvertArray() throws Exception {
- final byte[] original = {1, 2 ,3 ,4};
- final byte[] out = new byte[original.length];
-
- System.arraycopy( original, 0, out, 0, original.length);
- ByteUtils.invertArray(out);
-
- assertEquals(original[0], out[3]);
- assertEquals(original[1], out[2]);
- assertEquals(original[2], out[1]);
- assertEquals(original[3], out[0]);
- }
-}
\ No newline at end of file
diff --git a/print_codecov.sh b/print_codecov.sh
deleted file mode 100755
index b53e6cd80ebf6d670ce7440fde624be3221923f1..0000000000000000000000000000000000000000
--- a/print_codecov.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-PATTERN='jacoco*.xml'
-JAR_FILE='./buildsystem/jacocoxml/jacocoxmlparser-1.0.0.jar'
-COLOR_FLAG=''
-
-if which tput > /dev/null 2>&1 && [[ $(tput -T${TERM} colors) -ge 8 ]]; then
- COLOR_FLAG='--color'
-fi
-
-find -iname ${PATTERN} -print0 \
- | sort -z \
- | xargs -0 -I '{}' java -jar ${JAR_FILE} ${COLOR_FLAG} --global-stats -i '{}'
-
diff --git a/sample_app/apk_v1.1.1.apk b/sample_app/apk_v1.1.1.apk
deleted file mode 100644
index 892cf25865fdd9bcd7ca0807f0b74bfd70c440ed..0000000000000000000000000000000000000000
Binary files a/sample_app/apk_v1.1.1.apk and /dev/null differ
diff --git a/sample_app/app_v1.1.0.apk b/sample_app/app_v1.1.0.apk
deleted file mode 100644
index 0ca9dcb29c5cf6022cd319ca4a66dd7c66cb9e8e..0000000000000000000000000000000000000000
Binary files a/sample_app/app_v1.1.0.apk and /dev/null differ
diff --git a/sample_app/build.gradle b/sample_app/build.gradle
deleted file mode 100644
index 7cb1d3a67a7380abea2fefbc009bc84534a26067..0000000000000000000000000000000000000000
--- a/sample_app/build.gradle
+++ /dev/null
@@ -1,108 +0,0 @@
-plugins {
- id 'com.android.application'
- id 'kotlin-android'
- id 'kotlin-android-extensions'
- id 'kotlin-kapt'
- id 'com.github.triplet.play' version '2.5.0'
-}
-
-apply from: "${project.rootDir}/buildsystem/android-defaults.gradle"
-
-final int versionMajor = 1
-final int versionMinor = 1
-final int versionPatch = getBuildNumber()
-final int androidVersionCode = getBuildNumber()
-
-final String semanticVersion = "${versionMajor}.${versionMinor}.${versionPatch}"
-
-repositories {
- google()
- mavenCentral()
- maven { url "https://repo.commonsware.com.s3.amazonaws.com" }
- maven { url "https://s3.amazonaws.com/repo.commonsware.com" }
- maven { url "https://dl.bintray.com/alt236/maven" }
-}
-
-android {
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
-
- signingConfigs {
- release {
- storeFile file(System.getenv("ANDROID_KEYSTORE") ?: "[KEY_NOT_DEFINED]")
- storePassword System.getenv("KEYSTORE_PASSWORD")
- keyAlias System.getenv("KEY_ALIAS")
- keyPassword System.getenv("KEY_PASSWORD")
- }
-
- debug {
- storeFile file("${project.rootDir}/buildsystem/signing_keys/debug.keystore")
- keyAlias 'androiddebugkey'
- keyPassword 'android'
- storePassword 'android'
- }
- }
-
- defaultConfig {
- versionCode androidVersionCode
- versionName semanticVersion
- }
-
- buildTypes {
- release {
- minifyEnabled false
- resValue "string", "app_name", "Bluetooth LE Scanner"
- if(isRunningOnCi()) {
- signingConfig signingConfigs.release
- }
- }
-
- debug {
- minifyEnabled false
- applicationIdSuffix ".debug"
- resValue "string", "app_name", "Debug Bluetooth LE Scanner"
- signingConfig signingConfigs.debug
- }
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-}
-
-dependencies {
- implementation project(':library')
-
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-
- implementation "androidx.appcompat:appcompat:$androidx_appcompat_version"
- implementation "androidx.recyclerview:recyclerview:$androidx_recyclerview"
- implementation "com.anthonycr.grant:permissions:$grant_permissions_version"
- implementation 'uk.co.alt236:easycursor-android:1.0.0'
-
- testImplementation 'junit:junit:4.13'
- testImplementation 'org.mockito:mockito-all:1.10.19'
-}
-
-play {
- def credentialsPath = System.getenv("GPLAY_DEPLOY_KEY") ?: "[KEY_NOT_DEFINED]"
- def lastCommitMessage = getLastGitCommitMessage().take(50)
-
- logger.warn("GPP Config: $credentialsPath")
- logger.warn("Release Name: '$lastCommitMessage'")
-
- if(isRunningOnCi()) {
- enabled = true
- track = "internal"
- //userFraction = 1.0
- releaseStatus = "completed"
- serviceAccountCredentials = file(credentialsPath)
- releaseName = lastCommitMessage
- artifactDir = file("${project.rootDir}/sample_app/build/outputs/apk/release/")
- } else {
- enabled = false
- }
-}
\ No newline at end of file
diff --git a/sample_app/proguard-rules.pro b/sample_app/proguard-rules.pro
deleted file mode 100644
index f8c620ff696bac14c51b13eb8b3d1ba657a1dc2b..0000000000000000000000000000000000000000
--- a/sample_app/proguard-rules.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /home/alex/Dev/android-sdk-linux/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/sample_app/sample_app.iml b/sample_app/sample_app.iml
deleted file mode 100644
index 8a89f912f78bb040f6c313a030ecd155a9a243b5..0000000000000000000000000000000000000000
--- a/sample_app/sample_app.iml
+++ /dev/null
@@ -1,188 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample_app/src/main/AndroidManifest.xml b/sample_app/src/main/AndroidManifest.xml
deleted file mode 100644
index f98ff973976fd9d4f6fc79e3d14dbcc8e74a6d5c..0000000000000000000000000000000000000000
--- a/sample_app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.kt
deleted file mode 100644
index 690b72bec522e970cebb594c0e0fc12b350bb760..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/containers/BluetoothLeDeviceStore.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package uk.co.alt236.btlescan.containers
-
-import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice
-import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor
-import java.util.*
-
-class BluetoothLeDeviceStore {
- private val mDeviceMap = HashMap()
-
- fun addDevice(device: BluetoothLeDevice) {
- if (mDeviceMap.containsKey(device.address)) {
- mDeviceMap[device.address]!!.updateRssiReading(device.timestamp, device.rssi)
- } else {
- mDeviceMap[device.address] = device
- }
- }
-
- fun clear() {
- mDeviceMap.clear()
- }
-
- val size: Int
- get() = mDeviceMap.size
-
- val deviceCursor: EasyObjectCursor
- get() = getDeviceCursor(DEFAULT_COMPARATOR)
-
- fun getDeviceCursor(comparator: Comparator): EasyObjectCursor {
- return EasyObjectCursor(
- BluetoothLeDevice::class.java,
- getDeviceList(comparator),
- "address")
- }
-
- val deviceList: List
- get() = getDeviceList(DEFAULT_COMPARATOR)
-
- fun getDeviceList(comparator: Comparator): List {
- val methodResult: List = ArrayList(mDeviceMap.values)
- Collections.sort(methodResult, comparator)
- return methodResult
- }
-
- private class BluetoothLeDeviceComparator : Comparator {
- override fun compare(arg0: BluetoothLeDevice, arg1: BluetoothLeDevice): Int {
- return arg0.address.compareTo(arg1.address)
- }
- }
-
- companion object {
- private val DEFAULT_COMPARATOR = BluetoothLeDeviceComparator()
- }
-}
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/kt/ByteArrayExt.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/kt/ByteArrayExt.kt
deleted file mode 100644
index 980f6ca7e2dc2da62a0ef0fce31af8caafbc0d23..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/kt/ByteArrayExt.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package uk.co.alt236.btlescan.kt
-
-object ByteArrayExt {
-
- fun ByteArray.toCharString(): String {
- val chars = ArrayList(this.size)
-
- for (byte in this) {
- if (byte in 0..31) {
- val unicode = (0x2400 + byte).toChar()
- chars.add(unicode)
- } else {
- chars.add(byte.toChar())
- }
- }
- return String(chars.toCharArray());
- }
-
-}
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/services/BluetoothLeService.java b/sample_app/src/main/java/uk/co/alt236/btlescan/services/BluetoothLeService.java
deleted file mode 100644
index 3319311d6ab989b7a560fcbf752cf42a11c0d4fa..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/services/BluetoothLeService.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package uk.co.alt236.btlescan.services;
-
-import android.app.Service;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallback;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattService;
-import android.bluetooth.BluetoothManager;
-import android.bluetooth.BluetoothProfile;
-import android.content.Context;
-import android.content.Intent;
-import android.os.IBinder;
-import android.util.Log;
-
-import java.util.List;
-
-/**
- * Service for managing connection and data communication with a GATT server hosted on a
- * given Bluetooth LE device.
- */
-public class BluetoothLeService extends Service {
- public final static String ACTION_GATT_CONNECTED = BluetoothLeService.class.getName() + ".ACTION_GATT_CONNECTED";
- public final static String ACTION_GATT_CONNECTING = BluetoothLeService.class.getName() + ".ACTION_GATT_CONNECTING";
- public final static String ACTION_GATT_DISCONNECTED = BluetoothLeService.class.getName() + ".ACTION_GATT_DISCONNECTED";
- public final static String ACTION_GATT_SERVICES_DISCOVERED = BluetoothLeService.class.getName() + ".ACTION_GATT_SERVICES_DISCOVERED";
- public final static String ACTION_DATA_AVAILABLE = BluetoothLeService.class.getName() + ".ACTION_DATA_AVAILABLE";
- public final static String EXTRA_DATA_RAW = BluetoothLeService.class.getName() + ".EXTRA_DATA_RAW";
- public final static String EXTRA_UUID_CHAR = BluetoothLeService.class.getName() + ".EXTRA_UUID_CHAR";
-
- private final static String TAG = BluetoothLeService.class.getSimpleName();
- private final IBinder mBinder = new LocalBinder(this);
- private BluetoothManager mBluetoothManager;
- private BluetoothAdapter mBluetoothAdapter;
- private String mBluetoothDeviceAddress;
- private BluetoothGatt mBluetoothGatt;
- private State mConnectionState = State.DISCONNECTED;
-
- // Implements callback methods for GATT events that the app cares about. For example,
- // connection change and services discovered.
- private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
- @Override
- public void onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
- broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
- }
-
- @Override
- public void onCharacteristicRead(final BluetoothGatt gatt,
- final BluetoothGattCharacteristic characteristic,
- final int status) {
-
- if (status == BluetoothGatt.GATT_SUCCESS) {
- broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
- }
- }
-
- @Override
- public void onConnectionStateChange(final BluetoothGatt gatt,
- final int status,
- final int newState) {
-
- Log.d(TAG, "onConnectionStateChange: status=" + status + ", newState=" + newState);
-
- if (newState == BluetoothProfile.STATE_CONNECTED) {
- setConnectionState(State.CONNECTED, true);
- Log.i(TAG, "Connected to GATT server.");
- // Attempts to discover services after successful connection.
- Log.i(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices());
-
- } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
- // Make sure we tidy up. On certain devices reusing a Gatt after a disconnection
- // can cause problems.
- disconnect();
-
- setConnectionState(State.DISCONNECTED, true);
- Log.i(TAG, "Disconnected from GATT server.");
- }
- }
-
- @Override
- public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {
- if (status == BluetoothGatt.GATT_SUCCESS) {
- broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
- } else {
- Log.w(TAG, "onServicesDiscovered received: " + status);
- }
- }
- };
-
- private void broadcastUpdate(final String action) {
- final Intent intent = new Intent(action);
- sendBroadcast(intent);
- }
-
- private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) {
- final Intent intent = new Intent(action);
- intent.putExtra(EXTRA_UUID_CHAR, characteristic.getUuid().toString());
-
- // Always try to add the RAW value
- final byte[] data = characteristic.getValue();
- if (data != null && data.length > 0) {
- intent.putExtra(EXTRA_DATA_RAW, data);
- }
-
- sendBroadcast(intent);
- }
-
- /**
- * After using a given BLE device, the app must call this method to ensure resources are
- * released properly.
- */
- public void close() {
- if (mBluetoothGatt == null) {
- return;
- }
- mBluetoothGatt.close();
- mBluetoothGatt = null;
- }
-
- /**
- * Connects to the GATT server hosted on the Bluetooth LE device.
- *
- * @param address The device address of the destination device.
- * @return Return true if the connection is initiated successfully. The connection result
- * is reported asynchronously through the
- * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
- * callback.
- */
- public boolean connect(final String address) {
-
- final boolean retVal;
- if (mBluetoothAdapter == null || address == null) {
- Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
- retVal = false;
-
- // Previously connected device. Try to reconnect.
- } else if (mBluetoothDeviceAddress != null
- && address.equals(mBluetoothDeviceAddress)
- && mBluetoothGatt != null) {
-
- Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
- if (mBluetoothGatt.connect()) {
- Log.d(TAG, "Connection attempt OK.");
- setConnectionState(State.CONNECTING, true);
- retVal = true;
- } else {
- Log.w(TAG, "Connection attempt failed.");
- setConnectionState(State.DISCONNECTED, true);
- retVal = false;
- }
- } else {
-
- final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
- if (device == null) {
- Log.w(TAG, "Device not found. Unable to connect.");
- retVal = false;
- } else {
- // We want to directly connect to the device, so we are setting the autoConnect
- // parameter to false.
-
- Log.d(TAG, "Trying to create a new connection.");
- mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
- mBluetoothDeviceAddress = address;
- setConnectionState(State.CONNECTING, true);
- retVal = true;
- }
- }
-
- return retVal;
- }
-
- private synchronized void setConnectionState(final State newState, final boolean broadCast) {
- Log.i(TAG, "Setting internal state to " + newState);
- mConnectionState = newState;
-
- final String broadcastAction;
-
- switch (newState) {
- case CONNECTED:
- broadcastAction = ACTION_GATT_CONNECTED;
- break;
- case CONNECTING:
- broadcastAction = ACTION_GATT_CONNECTING;
- break;
- case DISCONNECTED:
- broadcastAction = ACTION_GATT_DISCONNECTED;
- break;
- default:
- throw new IllegalArgumentException("Unknown state: " + newState);
- }
-
- if (broadCast) {
- Log.i(TAG, "Broadcasting " + broadcastAction);
- broadcastUpdate(broadcastAction);
- }
-
- }
-
- /**
- * Disconnects an existing connection or cancel a pending connection. The disconnection result
- * is reported asynchronously through the
- * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
- * callback.
- */
- public void disconnect() {
- if (mBluetoothAdapter == null || mBluetoothGatt == null) {
- Log.w(TAG, "BluetoothAdapter not initialized");
- return;
- }
- mBluetoothGatt.disconnect();
-
- // Reusing a Gatt after disconnecting can cause problems
- mBluetoothGatt = null;
- }
-
- /**
- * Retrieves a list of supported GATT services on the connected device. This should be
- * invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.
- *
- * @return A {@code List} of supported services.
- */
- public List getSupportedGattServices() {
- if (mBluetoothGatt == null) return null;
-
- return mBluetoothGatt.getServices();
- }
-
- /**
- * Initializes a reference to the local Bluetooth adapter.
- *
- * @return Return true if the initialization is successful.
- */
- public boolean initialize() {
- // For API level 18 and above, get a reference to BluetoothAdapter through
- // BluetoothManager.
- if (mBluetoothManager == null) {
- mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
- if (mBluetoothManager == null) {
- Log.e(TAG, "Unable to initialize BluetoothManager.");
- return false;
- }
- }
-
- mBluetoothAdapter = mBluetoothManager.getAdapter();
- if (mBluetoothAdapter == null) {
- Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
- return false;
- }
-
- return true;
- }
-
- @Override
- public IBinder onBind(final Intent intent) {
- return mBinder;
- }
-
- @Override
- public boolean onUnbind(final Intent intent) {
- // After using a given device, you should make sure that BluetoothGatt.close() is called
- // such that resources are cleaned up properly. In this particular example, close() is
- // invoked when the UI is disconnected from the Service.
- close();
- return super.onUnbind(intent);
- }
-
- /**
- * Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported
- * asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
- * callback.
- *
- * @param characteristic The characteristic to read from.
- */
- public void readCharacteristic(final BluetoothGattCharacteristic characteristic) {
- if (mBluetoothAdapter == null || mBluetoothGatt == null) {
- Log.w(TAG, "BluetoothAdapter not initialized");
- return;
- }
- mBluetoothGatt.readCharacteristic(characteristic);
- }
-
- /**
- * Enables or disables notification on a give characteristic.
- *
- * @param characteristic Characteristic to act on.
- * @param enabled If true, enable notification. False otherwise.
- */
- public void setCharacteristicNotification(final BluetoothGattCharacteristic characteristic, final boolean enabled) {
- if (mBluetoothAdapter == null || mBluetoothGatt == null) {
- Log.w(TAG, "BluetoothAdapter not initialized");
- return;
- }
- mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
- }
-
-}
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/services/LocalBinder.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/services/LocalBinder.kt
deleted file mode 100644
index 9689478c6e9059742935c9f2300a02124b87213f..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/services/LocalBinder.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package uk.co.alt236.btlescan.services
-
-import android.os.Binder
-
-class LocalBinder(val service: BluetoothLeService) : Binder()
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/services/State.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/services/State.kt
deleted file mode 100644
index 1174b26c64331e29ec0d4730dc62f5dec45df1ec..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/services/State.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package uk.co.alt236.btlescan.services
-
-internal enum class State {
- DISCONNECTED, CONNECTING, CONNECTED
-}
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/Navigation.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/Navigation.kt
deleted file mode 100644
index 3ac4376323c3cbabee83cce19ee690db3d0e10b9..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/Navigation.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package uk.co.alt236.btlescan.ui.common
-
-import android.app.Activity
-import android.content.Intent
-import android.net.Uri
-import androidx.core.app.ActivityCompat
-import androidx.core.app.ShareCompat
-import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice
-import uk.co.alt236.btlescan.R
-import uk.co.alt236.btlescan.ui.control.DeviceControlActivity
-import uk.co.alt236.btlescan.ui.details.DeviceDetailsActivity
-
-class Navigation(private val activity: Activity) {
-
- fun openDetailsActivity(device: BluetoothLeDevice?) {
- val intent = DeviceDetailsActivity.createIntent(activity, device)
- startActivity(intent)
- }
-
- fun startControlActivity(device: BluetoothLeDevice?) {
- val intent = DeviceControlActivity.createIntent(activity, device)
- startActivity(intent)
- }
-
- fun shareFileViaEmail(uri: Uri, recipient: Array?, subject: String?, message: String?) {
- val intent = ShareCompat.IntentBuilder.from(activity)
- .setChooserTitle(R.string.exporter_email_device_list_picker_text)
- .setStream(uri)
- .setEmailTo(recipient ?: emptyArray())
- .setSubject(subject ?: "")
- .setText(message ?: "")
- .setType("text/text")
- .intent
- .setAction(Intent.ACTION_SEND)
- .setDataAndType(uri, "plain/text")
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
-
- startActivity(intent)
- }
-
- private fun startActivity(intent: Intent) {
- ActivityCompat.startActivity(activity, intent, null)
- }
-
-}
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseRecyclerViewAdapter.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseRecyclerViewAdapter.kt
deleted file mode 100644
index ea2a9608443338ab5cbf585eebe45c0b2445128d..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseRecyclerViewAdapter.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package uk.co.alt236.btlescan.ui.common.recyclerview
-
-import android.view.ViewGroup
-import androidx.recyclerview.widget.RecyclerView
-
-abstract class BaseRecyclerViewAdapter @JvmOverloads constructor(private val core: RecyclerViewBinderCore,
- items: List = ArrayList()) : RecyclerView.Adapter>() {
-
- private val list = ArrayList()
-
- init {
- list.addAll(items)
- }
-
- override fun onCreateViewHolder(parent: ViewGroup,
- viewType: Int): BaseViewHolder {
- return core.create(parent, viewType)
- }
-
- override fun onBindViewHolder(holder: BaseViewHolder,
- position: Int) {
- val viewType = getItemViewType(position)
- val binder = core.getBinder(viewType)
-
- bind(binder, holder, getItem(position))
- }
-
- override fun getItemCount(): Int {
- return list.size
- }
-
- override fun getItemViewType(position: Int): Int {
- return core.getViewType(getItem(position))
- }
-
- fun getItem(position: Int): RecyclerViewItem? {
- return list[position]
- }
-
- fun setData(data: Collection) {
- list.clear()
- list.addAll(data)
- notifyDataSetChanged()
- }
-
- companion object {
- private fun bind(binder: BaseViewBinder,
- holder: BaseViewHolder<*>,
- item: RecyclerViewItem?) {
- @Suppress("UNCHECKED_CAST")
- binder.bind((holder as BaseViewHolder), item as T)
- }
- }
-}
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseViewBinder.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseViewBinder.kt
deleted file mode 100644
index c92a23539c1fffdbbf137f5ed74f13b27b7b1188..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseViewBinder.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package uk.co.alt236.btlescan.ui.common.recyclerview
-
-import android.content.Context
-import androidx.annotation.StringRes
-import uk.co.alt236.btlescan.R
-
-abstract class BaseViewBinder(protected val context: Context) {
- abstract fun bind(holder: BaseViewHolder, item: T)
- abstract fun canBind(item: RecyclerViewItem): Boolean
-
- protected fun getString(@StringRes id: Int): String {
- return context.getString(id)
- }
-
- protected fun getString(@StringRes resId: Int, vararg formatArgs: Any?): String {
- return context.getString(resId, *formatArgs)
- }
-
- protected fun getQuotedString(vararg formatArgs: Any?): String {
- return getString(R.string.formatter_single_quoted_string, *formatArgs)
- }
-}
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseViewHolder.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseViewHolder.kt
deleted file mode 100644
index fdbe35df2bc958b4897a6b2afb9a46805b149a3b..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/BaseViewHolder.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package uk.co.alt236.btlescan.ui.common.recyclerview
-
-import android.view.View
-import androidx.recyclerview.widget.RecyclerView.ViewHolder
-
-abstract class BaseViewHolder(val view: View) : ViewHolder(view)
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewBinderCore.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewBinderCore.java
deleted file mode 100644
index a9888f13fd4329459c0d215128d3297e2b29e191..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewBinderCore.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package uk.co.alt236.btlescan.ui.common.recyclerview;
-
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class RecyclerViewBinderCore {
- public static final int INVALID_VIEWTYPE = -1;
-
- private static final String TAG = RecyclerViewBinderCore.class.getSimpleName();
- private final List>> mViewHolderClasses;
- private final List> mViewBinders;
- private final List mLayoutIds;
-
- public RecyclerViewBinderCore() {
- mViewBinders = new ArrayList<>();
- mViewHolderClasses = new ArrayList<>();
- mLayoutIds = new ArrayList<>();
- }
-
- public void clear() {
- mViewBinders.clear();
- mViewHolderClasses.clear();
- mLayoutIds.clear();
- }
-
- public void add(
- final BaseViewBinder binder,
- final Class extends BaseViewHolder> viewHolder,
- final int layoutId) {
-
- mViewBinders.add(binder);
- mViewHolderClasses.add(viewHolder);
- mLayoutIds.add(layoutId);
- }
-
- public BaseViewHolder extends RecyclerViewItem> create(ViewGroup parent, final int viewType) {
- if (viewType == INVALID_VIEWTYPE) {
- throw new IllegalArgumentException("Invalid viewType: " + viewType);
- }
-
- final Class> clazz = mViewHolderClasses.get(viewType);
- final int layoutId = mLayoutIds.get(viewType);
- final View itemView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
-
- return (BaseViewHolder extends RecyclerViewItem>) instantiate(clazz, itemView);
- }
-
- public int getViewType(final T item) {
- int result = INVALID_VIEWTYPE;
- int count = 0;
-
- for (final BaseViewBinder extends RecyclerViewItem> binder : mViewBinders) {
-
- if (binder.canBind(item)) {
- result = count;
- break;
- }
-
- count++;
- }
-
- if (result == INVALID_VIEWTYPE) {
- Log.w(TAG, "Could not get viewType for " + item);
- }
-
- return result;
- }
-
- public BaseViewBinder extends RecyclerViewItem> getBinder(int viewType) {
- if (viewType == INVALID_VIEWTYPE) {
- throw new IllegalArgumentException("Invalid viewType: " + viewType);
- }
-
- return mViewBinders.get(viewType);
- }
-
- @SuppressWarnings("TryWithIdenticalCatches")
- private static Object instantiate(
- final Class> clazz, View parentView) {
- try {
- final Constructor> constructor = clazz.getDeclaredConstructors()[0];
- return constructor.newInstance(parentView);
- } catch (InstantiationException e) {
- throw new IllegalStateException(e);
- } catch (IllegalAccessException e) {
- throw new IllegalStateException(e);
- } catch (InvocationTargetException e) {
- throw new IllegalStateException(e);
- }
- }
-}
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewItem.kt b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewItem.kt
deleted file mode 100644
index d3361ff1ddfbbf1416411c3256caeb04aa9362d9..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/common/recyclerview/RecyclerViewItem.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package uk.co.alt236.btlescan.ui.common.recyclerview
-
-interface RecyclerViewItem
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java
deleted file mode 100644
index 92bbe756f7a5b5829244c6fb1767a16adfc9b251..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/DeviceControlActivity.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package uk.co.alt236.btlescan.ui.control;
-
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattService;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.ExpandableListView;
-import android.widget.TextView;
-
-import java.util.List;
-
-import androidx.appcompat.app.AppCompatActivity;
-import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
-import uk.co.alt236.btlescan.R;
-import uk.co.alt236.btlescan.services.BluetoothLeService;
-import uk.co.alt236.btlescan.services.LocalBinder;
-
-/**
- * For a given BLE device, this Activity provides the user interface to connect, display data,
- * and display GATT services and characteristics supported by the device. The Activity
- * communicates with {@code BluetoothLeService}, which in turn interacts with the
- * Bluetooth LE API.
- */
-public class DeviceControlActivity extends AppCompatActivity {
- private static final String EXTRA_DEVICE = DeviceControlActivity.class.getName() + ".EXTRA_DEVICE";
- private final static String TAG = DeviceControlActivity.class.getSimpleName();
- private Exporter mExporter;
- private BluetoothGattCharacteristic mNotifyCharacteristic;
- private BluetoothLeService mBluetoothLeService;
- // If a given GATT characteristic is selected, check for supported features. This sample
- // demonstrates 'Read' and 'Notify' features. See
- // http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete
- // list of supported characteristic features.
- private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() {
- @Override
- public boolean onChildClick(final ExpandableListView parent, final android.view.View v, final int groupPosition, final int childPosition, final long id) {
- final GattDataAdapterFactory.GattDataAdapter adapter =
- (GattDataAdapterFactory.GattDataAdapter) parent.getExpandableListAdapter();
-
- final BluetoothGattCharacteristic characteristic =
- adapter.getBluetoothGattCharacteristic(groupPosition, childPosition);
-
- final int charaProp = characteristic.getProperties();
- if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
- // If there is an active notification on a characteristic, clear
- // it first so it doesn't update the data field on the user interface.
- if (mNotifyCharacteristic != null) {
- mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
- mNotifyCharacteristic = null;
- }
- mBluetoothLeService.readCharacteristic(characteristic);
- }
- if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
- mNotifyCharacteristic = characteristic;
- mBluetoothLeService.setCharacteristicNotification(characteristic, true);
- }
- return true;
- }
- };
- private View view;
-
- // Code to manage Service lifecycle.
- private final ServiceConnection mServiceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(final ComponentName componentName, final IBinder service) {
- mBluetoothLeService = ((LocalBinder) service).getService();
- if (!mBluetoothLeService.initialize()) {
- Log.e(TAG, "Unable to initialize Bluetooth");
- finish();
- }
- // Automatically connects to the device upon successful start-up initialization.
- mBluetoothLeService.connect(mDevice.getAddress());
- }
-
- @Override
- public void onServiceDisconnected(final ComponentName componentName) {
- mBluetoothLeService = null;
- }
- };
- private BluetoothLeDevice mDevice;
- private State mCurrentState = State.DISCONNECTED;
-
- private String mExportString;
- // Handles various events fired by the Service.
- // ACTION_GATT_CONNECTED: connected to a GATT server.
- // ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
- // ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
- // ACTION_DATA_AVAILABLE: received data from the device.
- // this can be a result of read or notification operations.
- private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(final Context context, final Intent intent) {
- final String action = intent.getAction();
- if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
- updateConnectionState(State.CONNECTED);
- invalidateOptionsMenu();
- } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
- clearUI();
- updateConnectionState(State.DISCONNECTED);
- invalidateOptionsMenu();
- } else if (BluetoothLeService.ACTION_GATT_CONNECTING.equals(action)) {
- clearUI();
- updateConnectionState(State.CONNECTING);
- invalidateOptionsMenu();
- } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
- // Show all the supported services and characteristics on the user interface.
- displayGattServices(mBluetoothLeService.getSupportedGattServices());
- } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
- final String uuid = intent.getStringExtra(BluetoothLeService.EXTRA_UUID_CHAR);
- final byte[] dataArr = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA_RAW);
-
- view.setGattUuid(uuid);
- view.setData(dataArr);
- }
- }
- };
-
- private void clearUI() {
- mExportString = null;
- view.clearUi();
- }
-
- // Demonstrates how to iterate through the supported GATT Services/Characteristics.
- // In this sample, we populate the data structure that is bound to the ExpandableListView
- // on the UI.
- private void displayGattServices(final List gattServices) {
- if (gattServices == null) return;
- mExportString = mExporter.generateExportString(
- mDevice.getName(),
- mDevice.getAddress(),
- gattServices);
-
- final GattDataAdapterFactory.GattDataAdapter adapter = GattDataAdapterFactory.createAdapter(this, gattServices);
- view.setListAdapter(adapter);
- invalidateOptionsMenu();
- }
-
- @Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_gatt_services);
-
- final Intent intent = getIntent();
- mDevice = intent.getParcelableExtra(EXTRA_DEVICE);
- view = new View(this);
-
- // Sets up UI references.
- ((TextView) findViewById(R.id.device_address)).setText(mDevice.getAddress());
- view.setListClickListener(servicesListClickListner);
-
- getSupportActionBar().setTitle(mDevice.getName());
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
- mExporter = new Exporter(this);
-
- final Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
- bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.gatt_services, menu);
-
- switch (mCurrentState) {
-
- case DISCONNECTED:
- menu.findItem(R.id.menu_connect).setVisible(true);
- menu.findItem(R.id.menu_disconnect).setVisible(false);
- menu.findItem(R.id.menu_refresh).setActionView(null);
- break;
- case CONNECTING:
- menu.findItem(R.id.menu_connect).setVisible(false);
- menu.findItem(R.id.menu_disconnect).setVisible(false);
- menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate);
- break;
- case CONNECTED:
- menu.findItem(R.id.menu_connect).setVisible(false);
- menu.findItem(R.id.menu_disconnect).setVisible(true);
- menu.findItem(R.id.menu_refresh).setActionView(null);
- break;
- default:
- throw new IllegalStateException("Don't know how to handle: " + mCurrentState);
- }
-
- if (mExportString == null) {
- menu.findItem(R.id.menu_share).setVisible(false);
- } else {
- menu.findItem(R.id.menu_share).setVisible(true);
- }
-
- return true;
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- unbindService(mServiceConnection);
- mBluetoothLeService = null;
- }
-
- @Override
- public boolean onOptionsItemSelected(final MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_connect:
- mBluetoothLeService.connect(mDevice.getAddress());
- return true;
- case R.id.menu_disconnect:
- mBluetoothLeService.disconnect();
- return true;
- case android.R.id.home:
- onBackPressed();
- return true;
- case R.id.menu_share:
- final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
- final String subject = getString(
- R.string.exporter_email_device_services_subject,
- mDevice.getName(),
- mDevice.getAddress());
-
- intent.setType("text/plain");
- intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
- intent.putExtra(android.content.Intent.EXTRA_TEXT, mExportString);
-
- startActivity(Intent.createChooser(
- intent,
- getString(R.string.exporter_email_device_list_picker_text)));
-
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- unregisterReceiver(mGattUpdateReceiver);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
- if (mBluetoothLeService != null) {
- final boolean result = mBluetoothLeService.connect(mDevice.getAddress());
- Log.d(TAG, "Connect request result=" + result);
- }
- }
-
- private void updateConnectionState(final State state) {
- mCurrentState = state;
- runOnUiThread(() -> view.setConnectionState(state));
- }
-
- private static IntentFilter makeGattUpdateIntentFilter() {
- final IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
- intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
- intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
- intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
- intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTING);
- return intentFilter;
- }
-
- private static String tryString(final String string, final String fallback) {
- if (string == null) {
- return fallback;
- } else {
- return string;
- }
- }
-
- public static Intent createIntent(final Context context, final BluetoothLeDevice device) {
- final Intent intent = new Intent(context, DeviceControlActivity.class);
- intent.putExtra(DeviceControlActivity.EXTRA_DEVICE, device);
- return intent;
- }
-}
\ No newline at end of file
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/Exporter.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/Exporter.java
deleted file mode 100644
index 7a8fb8ffc135713d527d150e33c91d1e3fc5afaa..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/Exporter.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package uk.co.alt236.btlescan.ui.control;
-
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattService;
-import android.content.Context;
-
-import java.util.List;
-
-import uk.co.alt236.bluetoothlelib.resolvers.GattAttributeResolver;
-import uk.co.alt236.btlescan.R;
-
-/*package*/ class Exporter {
- private final Context mContext;
-
- public Exporter(final Context context) {
- mContext = context.getApplicationContext();
- }
-
- public String generateExportString(final String deviceName,
- final String deviceAddress,
- final List gattServices) {
-
- final String unknownServiceString = mContext.getString(R.string.unknown_service);
- final String unknownCharaString = mContext.getString(R.string.unknown_characteristic);
- final StringBuilder exportBuilder = new StringBuilder();
-
- exportBuilder.append("Device Name: ");
- exportBuilder.append(deviceName);
- exportBuilder.append('\n');
- exportBuilder.append("Device Address: ");
- exportBuilder.append(deviceAddress);
- exportBuilder.append('\n');
- exportBuilder.append('\n');
-
- exportBuilder.append("Services:");
- exportBuilder.append("--------------------------");
- exportBuilder.append('\n');
-
- String uuid = null;
- for (final BluetoothGattService gattService : gattServices) {
- uuid = gattService.getUuid().toString();
-
- exportBuilder.append(GattAttributeResolver.getAttributeName(uuid, unknownServiceString));
- exportBuilder.append(" (");
- exportBuilder.append(uuid);
- exportBuilder.append(')');
- exportBuilder.append('\n');
-
- final List gattCharacteristics = gattService.getCharacteristics();
- for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
- uuid = gattCharacteristic.getUuid().toString();
-
- exportBuilder.append('\t');
- exportBuilder.append(GattAttributeResolver.getAttributeName(uuid, unknownCharaString));
- exportBuilder.append(" (");
- exportBuilder.append(uuid);
- exportBuilder.append(')');
- exportBuilder.append('\n');
- }
-
- exportBuilder.append('\n');
- exportBuilder.append('\n');
- }
-
- exportBuilder.append("--------------------------");
- exportBuilder.append('\n');
-
- return exportBuilder.toString();
- }
-}
diff --git a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/GattDataAdapterFactory.java b/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/GattDataAdapterFactory.java
deleted file mode 100644
index f9c71b1d86a320999ddb65265241feae45584c98..0000000000000000000000000000000000000000
--- a/sample_app/src/main/java/uk/co/alt236/btlescan/ui/control/GattDataAdapterFactory.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package uk.co.alt236.btlescan.ui.control;
-
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattService;
-import android.content.Context;
-import android.widget.SimpleExpandableListAdapter;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import uk.co.alt236.bluetoothlelib.resolvers.GattAttributeResolver;
-import uk.co.alt236.btlescan.R;
-
-/*package*/ class GattDataAdapterFactory {
- private static final String LIST_NAME = "NAME";
- private static final String LIST_UUID = "UUID";
-
- public static GattDataAdapter createAdapter(final Context context,
- final List gattServices) {
-
-
- final String unknownServiceString = context.getString(R.string.unknown_service);
- final String unknownCharaString = context.getString(R.string.unknown_characteristic);
- final List