├── DebugApp
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values
│ │ │ ├── strings.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ └── styles.xml
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ ├── values-v21
│ │ │ └── styles.xml
│ │ └── layout
│ │ │ └── activity_debug.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── cl
│ │ └── felipebarriga
│ │ └── android
│ │ └── sony
│ │ └── smartband
│ │ └── api
│ │ └── demo
│ │ └── DebugActivity.java
├── proguard-rules.pro
├── build.gradle
└── DebugApp.iml
├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── vcs.xml
├── runConfigurations.xml
├── modules.xml
├── compiler.xml
├── gradle.xml
└── misc.xml
├── RawBandLogger
├── .gitignore
├── src
│ └── main
│ │ ├── ic_log-web.png
│ │ ├── ic_lauasd-web.png
│ │ ├── ic_record-web.png
│ │ ├── ic_steps-web.png
│ │ ├── ic_battery-web.png
│ │ ├── ic_bluetooth-web.png
│ │ ├── ic_stopwatch-web.png
│ │ ├── res
│ │ ├── mipmap-hdpi
│ │ │ ├── ic_log.png
│ │ │ ├── ic_record.png
│ │ │ ├── ic_steps.png
│ │ │ ├── ic_battery.png
│ │ │ ├── ic_bluetooth.png
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_stopwatch.png
│ │ ├── mipmap-mdpi
│ │ │ ├── ic_log.png
│ │ │ ├── ic_record.png
│ │ │ ├── ic_steps.png
│ │ │ ├── ic_battery.png
│ │ │ ├── ic_bluetooth.png
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_stopwatch.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_log.png
│ │ │ ├── ic_steps.png
│ │ │ ├── ic_battery.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_record.png
│ │ │ ├── ic_bluetooth.png
│ │ │ └── ic_stopwatch.png
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_log.png
│ │ │ ├── ic_battery.png
│ │ │ ├── ic_record.png
│ │ │ ├── ic_steps.png
│ │ │ ├── ic_bluetooth.png
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_stopwatch.png
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_log.png
│ │ │ ├── ic_record.png
│ │ │ ├── ic_steps.png
│ │ │ ├── ic_battery.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_bluetooth.png
│ │ │ └── ic_stopwatch.png
│ │ ├── values
│ │ │ ├── strings.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ └── styles.xml
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ ├── values-v21
│ │ │ └── styles.xml
│ │ └── layout
│ │ │ └── activity_rawband.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── cl
│ │ └── felipebarriga
│ │ └── android
│ │ └── sony
│ │ └── smartband
│ │ └── api
│ │ └── rawband
│ │ └── RawBandActivity.java
├── proguard-rules.pro
├── build.gradle
└── RawBandLogger.iml
├── SonySmartBandOpenAPI
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── cl
│ │ └── felipebarriga
│ │ └── android
│ │ └── sony
│ │ └── smartband
│ │ └── api
│ │ └── bluetooth
│ │ ├── CharacteristicInfo.java
│ │ ├── profiles
│ │ ├── BaseProfile.java
│ │ ├── GenericAccessProfile.java
│ │ ├── BleConstants.java
│ │ ├── BatteryProfile.java
│ │ ├── DeviceInformationProfile.java
│ │ ├── AADeviceServiceProfile.java
│ │ └── AHServiceProfile.java
│ │ ├── DescriptorInfo.java
│ │ ├── BtBridgeListener.java
│ │ ├── BtBandListener.java
│ │ ├── Profiles.java
│ │ ├── BandMode.java
│ │ ├── BtBandEvent.java
│ │ ├── BtAction.java
│ │ ├── BtBridge.java
│ │ └── BtBand.java
├── build.gradle
├── proguard-rules.pro
└── SonySmartBandOpenAPI.iml
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── README.md
├── .gitignore
├── gradle.properties
├── sony-smartband-open-api.iml
├── LICENSE
├── gradlew.bat
└── gradlew
/DebugApp/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | sony-smartband-open-api
--------------------------------------------------------------------------------
/RawBandLogger/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':SonySmartBandOpenAPI'
2 | include ':DebugApp'
3 | include ':RawBandLogger'
4 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/RawBandLogger/src/main/ic_log-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/ic_log-web.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # sony-smartband-open-api
2 | Open API of Sony SmartBand SWR-10
3 |
4 | # build instructions
5 |
6 | ```
7 | ./gradlew build
8 | ```
9 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/ic_lauasd-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/ic_lauasd-web.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/ic_record-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/ic_record-web.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/ic_steps-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/ic_steps-web.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/ic_battery-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/ic_battery-web.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/ic_bluetooth-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/ic_bluetooth-web.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/ic_stopwatch-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/ic_stopwatch-web.png
--------------------------------------------------------------------------------
/DebugApp/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/DebugApp/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/DebugApp/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/DebugApp/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/DebugApp/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/DebugApp/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-hdpi/ic_log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-hdpi/ic_log.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-mdpi/ic_log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-mdpi/ic_log.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xhdpi/ic_log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xhdpi/ic_log.png
--------------------------------------------------------------------------------
/DebugApp/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/DebugApp/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/DebugApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/DebugApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-hdpi/ic_record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-hdpi/ic_record.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-hdpi/ic_steps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-hdpi/ic_steps.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-mdpi/ic_record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-mdpi/ic_record.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-mdpi/ic_steps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-mdpi/ic_steps.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xhdpi/ic_steps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xhdpi/ic_steps.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_log.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_log.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-hdpi/ic_battery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-hdpi/ic_battery.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-hdpi/ic_bluetooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-hdpi/ic_bluetooth.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-hdpi/ic_stopwatch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-hdpi/ic_stopwatch.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-mdpi/ic_battery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-mdpi/ic_battery.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-mdpi/ic_bluetooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-mdpi/ic_bluetooth.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-mdpi/ic_stopwatch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-mdpi/ic_stopwatch.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xhdpi/ic_battery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xhdpi/ic_battery.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xhdpi/ic_record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xhdpi/ic_record.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_battery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_battery.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_record.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_steps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_steps.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_record.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_steps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_steps.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xhdpi/ic_bluetooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xhdpi/ic_bluetooth.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xhdpi/ic_stopwatch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xhdpi/ic_stopwatch.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_bluetooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_bluetooth.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_stopwatch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxhdpi/ic_stopwatch.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_battery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_battery.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_bluetooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_bluetooth.png
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_stopwatch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fbarriga/sony-smartband-open-api/HEAD/RawBandLogger/src/main/res/mipmap-xxxhdpi/ic_stopwatch.png
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/DebugApp/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Sony SmartBand API Demo
3 | Settings
4 |
5 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Sony SmartBand API Demo
3 | Settings
4 |
5 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/DebugApp/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 21 11:34:03 PDT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
7 |
--------------------------------------------------------------------------------
/DebugApp/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/workspace.xml
2 | /.idea/libraries
3 | /.idea/tasks.xml
4 |
5 | /local.properties
6 | .DS_Store
7 | /build
8 | .gradle
9 |
10 | # Ignore Gradle GUI config
11 | gradle-app.setting
12 |
13 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
14 | !gradle-wrapper.jar
15 |
16 | # Cache of project
17 | .gradletasknamecache
18 |
--------------------------------------------------------------------------------
/DebugApp/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/DebugApp/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | buildscript {
3 | repositories {
4 | // maven { url 'http://repo1.maven.org/maven2' }
5 | }
6 | dependencies {
7 | // classpath 'com.android.tools.build:gradle:0.4'
8 | }
9 | }
10 | */
11 |
12 | apply plugin: 'android-library'
13 |
14 | dependencies {
15 | compile files('libs/android-support-v4.jar')
16 | }
17 |
18 | android {
19 | compileSdkVersion 23
20 | buildToolsVersion "23.0.2"
21 |
22 | defaultConfig {
23 | minSdkVersion 18
24 | targetSdkVersion 23
25 | }
26 |
27 | lintOptions {
28 | abortOnError false
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/CharacteristicInfo.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | /**
4 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
5 | */
6 | public class CharacteristicInfo {
7 | final String mServiceName;
8 | final String mCharacteristicName;
9 |
10 | CharacteristicInfo( String serviceName, String characteristicName ) {
11 | mServiceName = serviceName;
12 | mCharacteristicName = characteristicName;
13 | }
14 |
15 | public String toString() {
16 | return "service=" + mServiceName + " name=" + mCharacteristicName;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/DebugApp/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/fbarriga/software/AndroidSDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/RawBandLogger/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/fbarriga/software/AndroidSDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/DebugApp/src/main/res/layout/activity_debug.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/fbarriga/software/AndroidSDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/profiles/BaseProfile.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles;
2 |
3 | import java.util.HashMap;
4 | import java.util.UUID;
5 |
6 | /**
7 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
8 | */
9 | public abstract class BaseProfile {
10 | protected final static HashMap sUUIDNameMap;
11 |
12 | static {
13 | sUUIDNameMap = new HashMap<>( );
14 | }
15 |
16 | public final HashMap getsUUIDNameMap() {
17 | return sUUIDNameMap;
18 | }
19 |
20 | public final String getUuidName( UUID uuid ) {
21 | return sUUIDNameMap.get( uuid );
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/DescriptorInfo.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | /**
4 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
5 | */
6 | public class DescriptorInfo {
7 | final String mServiceName;
8 | final String mCharacteristicName;
9 | final String mDescriptorName;
10 |
11 | DescriptorInfo( String serviceName, String characteristicName, String descriptorName ) {
12 | mServiceName = serviceName;
13 | mCharacteristicName = characteristicName;
14 | mDescriptorName = descriptorName;
15 | }
16 |
17 | public String toString() {
18 | return "service=" + mServiceName + " name=" + mCharacteristicName + " descriptor=" + mDescriptorName;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/DebugApp/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion '23.0.2'
6 | defaultConfig {
7 | applicationId 'cl.felipebarriga.android.sony.smartband.api.demo'
8 | minSdkVersion 18
9 | targetSdkVersion 23
10 | versionCode 1001
11 | versionName '1.0.0'
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | productFlavors {
20 | }
21 | }
22 |
23 | dependencies {
24 | compile fileTree(include: ['*.jar'], dir: 'libs')
25 | testCompile 'junit:junit:4.12'
26 | compile 'com.android.support:appcompat-v7:23.1.1'
27 | compile 'com.android.support:design:23.1.1'
28 | compile project(':SonySmartBandOpenAPI')
29 | }
30 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/profiles/GenericAccessProfile.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles;
2 |
3 | import java.util.UUID;
4 |
5 | /**
6 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
7 | */
8 | public class GenericAccessProfile extends BaseProfile {
9 | public static final String CLASS = "GenericAccessProfile";
10 |
11 | public static final UUID SERVICE_UUID;
12 | public static final UUID DEVICE_NAME_UUID;
13 |
14 | static {
15 | SERVICE_UUID = UUID.fromString( "00001800-0000-1000-8000-00805F9B34FB" );
16 | DEVICE_NAME_UUID = UUID.fromString( "00002A00-0000-1000-8000-00805F9B34FB" );
17 |
18 | sUUIDNameMap.put( SERVICE_UUID, CLASS );
19 | sUUIDNameMap.put( DEVICE_NAME_UUID, "DEVICE_NAME_UUID" );
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/profiles/BleConstants.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles;
2 |
3 | import java.util.HashMap;
4 | import java.util.UUID;
5 |
6 | /**
7 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
8 | */
9 | public class BleConstants {
10 | public static final UUID CLIENT_CHARACTERISTIC_CONFIGURATION;
11 |
12 | private static HashMap sUUIDNameMap;
13 |
14 | static {
15 | CLIENT_CHARACTERISTIC_CONFIGURATION = UUID.fromString( "00002902-0000-1000-8000-00805F9B34FB" );
16 |
17 | sUUIDNameMap = new HashMap();
18 | sUUIDNameMap.put( CLIENT_CHARACTERISTIC_CONFIGURATION, "CLIENT_CHARACTERISTIC_CONFIGURATION" );
19 | }
20 |
21 | public static String getUuidName( UUID uuid ) {
22 | return sUUIDNameMap.get( uuid );
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/RawBandLogger/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion '23.0.2'
6 | defaultConfig {
7 | applicationId 'cl.felipebarriga.android.sony.smartband.api.rawband'
8 | minSdkVersion 18
9 | targetSdkVersion 23
10 | versionCode 1001
11 | versionName '1.0.0'
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | productFlavors {
20 | }
21 | }
22 |
23 | dependencies {
24 | compile fileTree(include: ['*.jar'], dir: 'libs')
25 | testCompile 'junit:junit:4.12'
26 | compile 'com.android.support:appcompat-v7:23.1.1'
27 | compile 'com.android.support:design:23.1.1'
28 | compile 'com.androidplot:androidplot-core:0.6.1'
29 | compile project(':SonySmartBandOpenAPI')
30 | }
31 |
--------------------------------------------------------------------------------
/sony-smartband-open-api.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/DebugApp/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
14 |
15 |
16 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
14 |
15 |
16 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/BtBridgeListener.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | import android.bluetooth.BluetoothGattCharacteristic;
4 | import android.bluetooth.BluetoothGattDescriptor;
5 | import android.bluetooth.BluetoothGattService;
6 |
7 | import java.util.List;
8 |
9 |
10 | /**
11 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
12 | */
13 | public interface BtBridgeListener {
14 | void onCharacteristicRead( BluetoothGattCharacteristic characteristic );
15 | void onConnectionStateChange( BtBridge.Status status );
16 | void onCharacteristicChanged( BluetoothGattCharacteristic characteristic );
17 | void onCharacteristicWrite( BluetoothGattCharacteristic characteristic );
18 | void onDescriptorRead( BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor );
19 | void onDescriptorWrite( BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor );
20 | void onServicesDiscovered( List services );
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/profiles/BatteryProfile.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles;
2 |
3 | import android.bluetooth.BluetoothGattCharacteristic;
4 | import java.util.UUID;
5 |
6 | /**
7 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
8 | */
9 | public class BatteryProfile extends BaseProfile {
10 | public static final String CLASS = "BatteryProfile";
11 |
12 | public static final UUID SERVICE_UUID;
13 | public static final UUID BATTERY_LEVEL_UUID;
14 |
15 | static {
16 | SERVICE_UUID = UUID.fromString( "0000180F-0000-1000-8000-00805F9B34FB" );
17 | BATTERY_LEVEL_UUID = UUID.fromString( "00002A19-0000-1000-8000-00805F9B34FB" );
18 |
19 | sUUIDNameMap.put( SERVICE_UUID, CLASS );
20 | sUUIDNameMap.put( BATTERY_LEVEL_UUID, "BATTERY_LEVEL_UUID" );
21 | }
22 |
23 | public static int readBatteryLevel( BluetoothGattCharacteristic characteristic ) {
24 | return characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT8, 0 );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Felipe Barriga Richards
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/DebugApp/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | 1.8
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/BtBandListener.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | import java.util.Date;
4 |
5 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.AHServiceProfile;
6 |
7 | /**
8 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
9 | */
10 | public interface BtBandListener {
11 |
12 | void onAHServiceReadAccData( int[] data );
13 | void onAHServiceReadCurrentTime( int bandSeconds, Date deviceDate, long deltaMs );
14 | void onAHServiceReadData( );
15 | void onAHServiceReadEvent( BtBandEvent event );
16 | void onAHServiceReadMode( BandMode.AccessoryMode mode );
17 | void onAHServiceReadProtocolVersion( int version );
18 | void onAHServiceReadUptime( int uptime, Date started );
19 |
20 | void onBatteryLevel( int level );
21 |
22 | void onFirmwareRevision( String rev );
23 | void onSoftwareRevision( String rev );
24 | void onHardwareRevision( String rev );
25 | void onManufacturerName( String name );
26 |
27 | void onAASDeviceVersion( int version );
28 | void onAASDeviceSmartLink( int version );
29 | void onAASDeviceProductId( String productId );
30 | void onAASDeviceData( String data );
31 |
32 | void onGADeviceName( String data );
33 |
34 | void onConnectionStateChange( BtBridge.Status status );
35 | void onServicesDiscovered();
36 | }
37 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/profiles/DeviceInformationProfile.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles;
2 |
3 | import java.util.UUID;
4 |
5 | /**
6 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
7 | */
8 | public class DeviceInformationProfile extends BaseProfile {
9 | public static final String CLASS = "DeviceInformationProfile";
10 |
11 | public static final UUID SERVICE_UUID;
12 | public static final UUID FIRMWARE_REVISION_UUID;
13 | public static final UUID HARDWARE_REVISION_UUID;
14 | public static final UUID SOFTWARE_REVISION_UUID;
15 | public static final UUID MANUFACTURER_NAME_UUID;
16 |
17 | static {
18 | SERVICE_UUID = UUID.fromString( "0000180A-0000-1000-8000-00805F9B34FB" );
19 | FIRMWARE_REVISION_UUID = UUID.fromString( "00002A26-0000-1000-8000-00805F9B34FB" );
20 | HARDWARE_REVISION_UUID = UUID.fromString( "00002A27-0000-1000-8000-00805F9B34FB" );
21 | SOFTWARE_REVISION_UUID = UUID.fromString( "00002A28-0000-1000-8000-00805F9B34FB" );
22 | MANUFACTURER_NAME_UUID = UUID.fromString( "00002A29-0000-1000-8000-00805F9B34FB" );
23 |
24 | sUUIDNameMap.put( SERVICE_UUID , CLASS );
25 | sUUIDNameMap.put( FIRMWARE_REVISION_UUID, "FIRMWARE_REVISION_UUID" );
26 | sUUIDNameMap.put( HARDWARE_REVISION_UUID, "HARDWARE_REVISION_UUID" );
27 | sUUIDNameMap.put( SOFTWARE_REVISION_UUID, "SOFTWARE_REVISION_UUID" );
28 | sUUIDNameMap.put( MANUFACTURER_NAME_UUID, "MANUFACTURER_NAME_UUID" );
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/Profiles.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | import android.util.Log;
4 |
5 | import java.util.HashMap;
6 | import java.util.UUID;
7 |
8 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.AADeviceServiceProfile;
9 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.AHServiceProfile;
10 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.BaseProfile;
11 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.BatteryProfile;
12 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.DeviceInformationProfile;
13 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.GenericAccessProfile;
14 |
15 | /**
16 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
17 | */
18 | public class Profiles {
19 | private static final String CLASS = "Profiles";
20 | private static HashMap sUUIDProfileMap;
21 |
22 | static {
23 | sUUIDProfileMap = new HashMap();
24 | sUUIDProfileMap.put( BatteryProfile.SERVICE_UUID , new BatteryProfile() );
25 | sUUIDProfileMap.put( AHServiceProfile.SERVICE_UUID , new AHServiceProfile() );
26 | sUUIDProfileMap.put( AADeviceServiceProfile.SERVICE_UUID , new AADeviceServiceProfile() );
27 | sUUIDProfileMap.put( DeviceInformationProfile.SERVICE_UUID, new DeviceInformationProfile() );
28 | sUUIDProfileMap.put( GenericAccessProfile.SERVICE_UUID , new GenericAccessProfile() );
29 | }
30 |
31 | public static BaseProfile getService( UUID uuid ) {
32 | Log.v( CLASS, "getService: uuid=" + uuid.toString() );
33 | Object profile = sUUIDProfileMap.get( uuid );
34 | if( profile == null ) {
35 | Log.w( CLASS, "getService: Profile not found for uuid=" + uuid.toString() );
36 | return null;
37 | }
38 |
39 | return ( BaseProfile ) profile;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/profiles/AADeviceServiceProfile.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles;
2 |
3 | import android.bluetooth.BluetoothGattCharacteristic;
4 | import java.util.UUID;
5 |
6 | /**
7 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
8 | */
9 | public class AADeviceServiceProfile extends BaseProfile {
10 | public static final String CLASS = "AADeviceServiceProfile";
11 |
12 | public static final UUID SERVICE_UUID;
13 | public static final UUID VERSION_UUID;
14 | public static final UUID DATA_UUID;
15 | public static final UUID PRODUCT_ID_UUID;
16 | public static final UUID SMART_LINK_SERVICE_UUID;
17 |
18 | static {
19 | SERVICE_UUID = UUID.fromString( "00000101-37cb-11e3-8682-0002a5d5c51b" );
20 | VERSION_UUID = UUID.fromString( "00000110-37cb-11e3-8682-0002a5d5c51b" );
21 | SMART_LINK_SERVICE_UUID = UUID.fromString( "00000111-37cb-11e3-8682-0002a5d5c51b" );
22 | PRODUCT_ID_UUID = UUID.fromString( "00000112-37cb-11e3-8682-0002a5d5c51b" );
23 | DATA_UUID = UUID.fromString( "00000113-37cb-11e3-8682-0002a5d5c51b" );
24 |
25 | sUUIDNameMap.put( SERVICE_UUID , CLASS );
26 | sUUIDNameMap.put( VERSION_UUID , "VERSION_UUID" );
27 | sUUIDNameMap.put( SMART_LINK_SERVICE_UUID, "SMART_LINK_SERVICE_UUID" );
28 | sUUIDNameMap.put( PRODUCT_ID_UUID , "PRODUCT_ID_UUID" );
29 | sUUIDNameMap.put( DATA_UUID , "DATA_UUID" );
30 | }
31 |
32 | public static int readDeviceAASVersion( BluetoothGattCharacteristic characteristic ) {
33 | return characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT16, 0 );
34 | }
35 |
36 | public static int readDeviceSmartLinkService( BluetoothGattCharacteristic characteristic ) {
37 | return characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT8, 0 );
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/BandMode.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
7 | */
8 | public class BandMode {
9 | public final static String CLASS = "BandMode";
10 |
11 | public enum AccessoryMode {
12 | DAY,
13 | NIGHT,
14 | MEDIA,
15 | FIRMWARE_UPDATE,
16 | UNKNOWN
17 | }
18 |
19 | private interface ACCESSORY_MODE {
20 | int DAY = 0;
21 | int NIGHT = 1;
22 | int MEDIA = 2;
23 | int FIRMWARE_UPDATE = 3;
24 | }
25 |
26 | private final AccessoryMode mMode;
27 | public BandMode( int mode ) {
28 | mMode = getMode( mode );
29 | }
30 |
31 | public static AccessoryMode getMode( int _mode ) {
32 | AccessoryMode mode;
33 | if( _mode == ACCESSORY_MODE.DAY ) {
34 | mode = AccessoryMode.DAY;
35 | } else if( _mode == ACCESSORY_MODE.NIGHT ) {
36 | mode = AccessoryMode.NIGHT;
37 | } else if( _mode == ACCESSORY_MODE.MEDIA ) {
38 | mode = AccessoryMode.MEDIA;
39 | } else if ( _mode == ACCESSORY_MODE.FIRMWARE_UPDATE ) {
40 | mode = AccessoryMode.FIRMWARE_UPDATE;
41 | } else {
42 | mode = AccessoryMode.UNKNOWN;
43 | Log.e( CLASS, "getMode: unknown mode: mode=" + _mode );
44 | }
45 | return mode;
46 | }
47 |
48 | public AccessoryMode getMode() {
49 | return mMode;
50 | }
51 |
52 | static public int getInt( AccessoryMode mode ) {
53 | if( AccessoryMode.DAY.equals( mode ) ) {
54 | return ACCESSORY_MODE.DAY;
55 | } else if( AccessoryMode.NIGHT.equals( mode ) ) {
56 | return ACCESSORY_MODE.NIGHT;
57 | } else if( AccessoryMode.MEDIA.equals( mode ) ) {
58 | return ACCESSORY_MODE.MEDIA;
59 | } else if( AccessoryMode.FIRMWARE_UPDATE.equals( mode ) ) {
60 | return ACCESSORY_MODE.FIRMWARE_UPDATE;
61 | }
62 |
63 | Log.e( CLASS, "getInt: unknown mode: mode=" + mode );
64 | return -1;
65 | }
66 |
67 | public int getInt() {
68 | return getInt( mMode );
69 | }
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/BtBandEvent.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | import android.util.Log;
4 |
5 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.AHServiceProfile;
6 |
7 | /**
8 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
9 | */
10 |
11 | public class BtBandEvent {
12 | public static final String CLASS = "BtBandEvent";
13 |
14 | private interface EVENT_TYPE_CODE {
15 | int TAP = 0;
16 | int BUTTON = 1;
17 | int LIFE_BOOKMARK = 2;
18 | int MODE_SWITCH = 3;
19 | int HARDWARE_EVENT = 4;
20 | int UPDATE_TIME = 5;
21 | }
22 |
23 | enum EventType {
24 | UNKNOWN,
25 | TAP,
26 | BUTTON,
27 | LIFE_BOOKMARK,
28 | MODE_SWITCH,
29 | HARDWARE_EVENT,
30 | UPDATE_TIME
31 | }
32 |
33 | enum Event {
34 | UNKNOWN,
35 | LOW_MEMORY,
36 | LOW_BATTERY,
37 | TAP_SINGLE,
38 | TAP_DOUBLE,
39 | TAP_TRIPLE,
40 | BUTTON,
41 | LIFE_BOOKMARK,
42 | MODE_SWITCH_DAY,
43 | MODE_SWITCH_NIGHT,
44 | MODE_SWITCH_MEDIA,
45 | MODE_SWITCH_FIRMWARE,
46 | UPDATE_TIME
47 | }
48 |
49 | private final EventType mType;
50 | private final Event mEvent;
51 | private final long mTimestamp;
52 |
53 | public EventType getType() {
54 | return mType;
55 | }
56 |
57 | public Event getEvent() {
58 | return mEvent;
59 | }
60 |
61 | public long getTimestamp() {
62 | return mTimestamp;
63 | }
64 |
65 | public BtBandEvent( int code, int value, int payload ) {
66 |
67 | if( code == EVENT_TYPE_CODE.LIFE_BOOKMARK ) {
68 | mType = EventType.LIFE_BOOKMARK;
69 | mEvent = Event.LIFE_BOOKMARK;
70 | mTimestamp = AHServiceProfile.convertBandSecondsToTimestamp( payload );
71 | return;
72 | }
73 |
74 | mTimestamp = 0;
75 |
76 | // Button + TAP will enable media mode
77 | // On media mode taps are detected without problems
78 | if( code == EVENT_TYPE_CODE.TAP ) {
79 | mType = EventType.TAP;
80 | if( value == AHServiceProfile.TAP_EVENT_TYPE.SINGLE ) {
81 | mEvent = Event.TAP_SINGLE;
82 | } else if( value == AHServiceProfile.TAP_EVENT_TYPE.DOUBLE ) {
83 | mEvent = Event.TAP_DOUBLE;
84 | } else if( value == AHServiceProfile.TAP_EVENT_TYPE.TRIPLE ) {
85 | mEvent = Event.TAP_TRIPLE;
86 | } else {
87 | mEvent = Event.UNKNOWN;
88 | Log.e( CLASS, "BtBandEvent: Unknown kind of TAP. value: " + value );
89 | }
90 |
91 | return;
92 | }
93 |
94 | if( code == EVENT_TYPE_CODE.BUTTON ) {
95 | mType = EventType.BUTTON;
96 | mEvent = Event.BUTTON;
97 | return;
98 | }
99 |
100 | if( code == EVENT_TYPE_CODE.MODE_SWITCH ) {
101 | mType = EventType.MODE_SWITCH;
102 | BandMode.AccessoryMode mode = new BandMode( value ).getMode();
103 | switch( mode ) {
104 | case DAY:
105 | mEvent = Event.MODE_SWITCH_DAY;
106 | break;
107 |
108 | case NIGHT:
109 | mEvent = Event.MODE_SWITCH_NIGHT;
110 | break;
111 |
112 | case MEDIA:
113 | mEvent = Event.MODE_SWITCH_MEDIA;
114 | break;
115 |
116 | case FIRMWARE_UPDATE:
117 | mEvent = Event.MODE_SWITCH_FIRMWARE;
118 | break;
119 |
120 | case UNKNOWN:
121 | default:
122 | Log.e( CLASS, "BtBandEvent: Switched to unknown mode: " + value );
123 | mEvent = Event.UNKNOWN;
124 | break;
125 | }
126 | return;
127 | }
128 |
129 | byte LOW_MEMORY_MASK = 0b00000001;
130 | byte LOW_BATTERY_MASK = 0b00000010;
131 | if( code == EVENT_TYPE_CODE.HARDWARE_EVENT ) {
132 | mType = EventType.HARDWARE_EVENT;
133 | if( ( value & LOW_BATTERY_MASK ) > 0 ) {
134 | mEvent = Event.LOW_BATTERY;
135 | } else if( ( value & LOW_MEMORY_MASK ) <= 0 ) {
136 | mEvent = Event.LOW_MEMORY;
137 | } else {
138 | mEvent = Event.UNKNOWN;
139 | Log.e( CLASS, "BtBandEvent: Unknown hardware event: " + value );
140 | }
141 | return;
142 | }
143 |
144 | if( code == EVENT_TYPE_CODE.UPDATE_TIME ) {
145 | mType = EventType.UPDATE_TIME;
146 | mEvent = Event.UPDATE_TIME;
147 | Log.d( CLASS, "readEvent: The device is requesting that we send a time update" );
148 | return;
149 | }
150 |
151 | mType = EventType.UNKNOWN;
152 | mEvent = Event.UNKNOWN;
153 |
154 | Log.e( CLASS, "BtBandEvent: Unknown mode: " + code );
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/java/cl/felipebarriga/android/sony/smartband/api/rawband/RawBandActivity.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.rawband;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.util.Log;
7 |
8 | import java.util.Date;
9 |
10 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BandMode;
11 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBand;
12 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBandEvent;
13 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBandListener;
14 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBridge;
15 |
16 | /**
17 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
18 | */
19 | public class RawBandActivity extends Activity implements BtBandListener {
20 | private final String CLASS = getClass().getSimpleName();
21 |
22 | @Override
23 | public void onAHServiceReadAccData( int[] data ) {
24 | Log.d( CLASS, "onAHServiceReadAccData: data=[" + data[0] + "," + data[1] + "," + data[2] + "]" );
25 | }
26 |
27 | @Override
28 | public void onAHServiceReadEvent( BtBandEvent event ) {
29 | Log.d( CLASS, "onAHServiceReadEvent: event=" + event );
30 | }
31 |
32 | @Override
33 | public void onAHServiceReadCurrentTime( int bandSeconds, Date deviceDate, long deltaMs ) {
34 | Log.d( CLASS, "onAHServiceReadCurrentTime: bandSeconds=" + bandSeconds
35 | +" deviceDate=" + deviceDate + " deltaMs=" + deltaMs );
36 |
37 | // SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
38 | // updateUILabel( RowId.CURRENT_TIME, sdf.format( deviceDate ) );
39 | }
40 |
41 | @Override
42 | public void onAHServiceReadProtocolVersion( int version ) {
43 | Log.d( CLASS, "onAHServiceReadProtocolVersion: version=" + version );
44 | // updateUILabel( RowId.PROTOCOL_VERSION, String.valueOf( version ) );
45 | }
46 |
47 | @Override
48 | public void onAHServiceReadData( ) {
49 | Log.d( CLASS, "onAHServiceReadData: called." );
50 | }
51 |
52 | @Override
53 | public void onAHServiceReadMode( BandMode.AccessoryMode mode ) {
54 | Log.d( CLASS, "onAHServiceReadMode: mode=" + mode.name() );
55 | // updateUILabel( RowId.CURRENT_MODE, mode.name() );
56 | }
57 |
58 | @Override
59 | public void onAHServiceReadUptime( int uptime, Date started ) {
60 | Log.d( CLASS, "onAHServiceReadUptime: started=" + started + " uptime=" + uptime );
61 | // updateUILabel( RowId.UPTIME, String.valueOf( uptime ) );
62 | }
63 |
64 | @Override
65 | public void onBatteryLevel( int level ) {
66 | Log.d( CLASS, "onBatteryLevel: level=" + level );
67 | // updateUILabel( RowId.BATTERY_LEVEL, String.valueOf( level ) );
68 | }
69 |
70 | @Override
71 | public void onFirmwareRevision( String rev ) {
72 | // updateUILabel( RowId.FIRMWARE_REVISION, rev );
73 | }
74 |
75 | @Override
76 | public void onSoftwareRevision( String rev ) {
77 | // updateUILabel( RowId.SOFTWARE_REVISION, rev );
78 | }
79 |
80 | @Override
81 | public void onHardwareRevision( String rev ) {
82 | // updateUILabel( RowId.HARDWARE_REVISION, rev );
83 | }
84 |
85 | @Override
86 | public void onManufacturerName( String name ) {
87 | // updateUILabel( RowId.MANUFACTURER_NAME, name );
88 | }
89 |
90 | @Override
91 | public void onAASDeviceVersion( int version ) {
92 | // updateUILabel( RowId.AAS_VERSION, String.valueOf( version ) );
93 | }
94 |
95 | @Override
96 | public void onAASDeviceSmartLink( int smartLink ) {
97 | // updateUILabel( RowId.AAS_SMART_LINK, String.valueOf( smartLink ) );
98 | }
99 |
100 | @Override
101 | public void onAASDeviceProductId( String productId ) {
102 | // updateUILabel( RowId.AAS_PRODUCT_ID, productId );
103 | }
104 |
105 | @Override
106 | public void onAASDeviceData( String data ) {
107 | // updateUILabel( RowId.AAS_DATA, data );
108 | }
109 |
110 | @Override
111 | public void onGADeviceName( String name ) {
112 | // updateUILabel( RowId.GA_DEVICE_NAME, name );
113 | }
114 |
115 | @Override
116 | public void onConnectionStateChange( final BtBridge.Status status ) {
117 | Log.i( CLASS, "onConnectionStateChange: status=" + status.name() );
118 | if( status == BtBridge.Status.CONNECTED ) {
119 | // updateUIButton( RowId.STATUS, true, "Disconnect" );
120 | } else if( status == BtBridge.Status.DISCONNECTED ) {
121 | // updateUIButton( RowId.STATUS, true, "Connect" );
122 | } else {
123 | // updateUIButton( RowId.STATUS, false, "Disconnect" );
124 | }
125 | }
126 |
127 | @Override
128 | public void onServicesDiscovered() {
129 | Log.i( CLASS, "onServicesDiscovered: called" );
130 | }
131 |
132 | private BtBand mBtBand;
133 | private Handler mHandler;
134 |
135 | @Override
136 | protected void onCreate( Bundle savedInstanceState ) {
137 | super.onCreate( savedInstanceState );
138 | Log.v( CLASS, "onCreate: called." );
139 |
140 | // mHandler = new Handler( );
141 | // mBtBand = new BtBand( this );
142 | // mBtBand.addListener( this );
143 | setContentView( R.layout.activity_rawband );
144 | }
145 |
146 | @Override
147 | protected void onStart() {
148 | super.onStart();
149 | Log.v( CLASS, "onStart: called." );
150 | }
151 |
152 | @Override
153 | protected void onResume() {
154 | super.onResume();
155 | Log.v( CLASS, "onResume: called." );
156 | }
157 |
158 | @Override
159 | protected void onPause() {
160 | super.onPause();
161 | Log.v( CLASS, "onPause: called." );
162 | }
163 |
164 | @Override
165 | protected void onRestart() {
166 | super.onRestart();
167 | Log.v( CLASS, "onRestart: called." );
168 | }
169 |
170 | @Override
171 | protected void onStop() {
172 | super.onStop();
173 | Log.v( CLASS, "onStop: called." );
174 | }
175 |
176 | @Override
177 | protected void onDestroy() {
178 | super.onDestroy();
179 | Log.v( CLASS, "onDestroy: called." );
180 | mBtBand.disconnect();
181 | }
182 |
183 |
184 | }
185 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/SonySmartBandOpenAPI.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/profiles/AHServiceProfile.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles;
2 |
3 | import android.bluetooth.BluetoothGattCharacteristic;
4 | import android.util.Log;
5 |
6 | import java.util.Calendar;
7 | import java.util.Date;
8 | import java.util.UUID;
9 |
10 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BandMode;
11 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBandEvent;
12 |
13 | /**
14 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
15 | */
16 | public class AHServiceProfile extends BaseProfile {
17 | public static final String CLASS = "AHServiceProfile";
18 |
19 | public static final UUID SERVICE_UUID;
20 | public static final UUID ACCEL_DATA_UUID;
21 | public static final UUID AUTO_NIGHT_MODE_UUID;
22 | public static final UUID CONTROL_POINT_UUID;
23 | public static final UUID ALARM_UUID;
24 | public static final UUID CURRENT_TIME_UUID;
25 | public static final UUID DATA_UUID;
26 | public static final UUID DEBUG_UUID;
27 | public static final UUID MODE_UUID;
28 | public static final UUID EVENT_UUID;
29 | public static final UUID NOTIFICATION_UUID;
30 | public static final UUID PROTOCOL_VERSION_UUID;
31 | public static final UUID USER_TARGET_UUID;
32 |
33 | public static final long TIMESTAMP_OF_2013 = 1356998400000L;
34 |
35 | public interface TAP_EVENT_TYPE {
36 | int SINGLE = 0;
37 | int DOUBLE = 1;
38 | int TRIPLE = 2;
39 | }
40 |
41 | static {
42 | SERVICE_UUID = UUID.fromString( "00000200-37cb-11e3-8682-0002a5d5c51b" );
43 | PROTOCOL_VERSION_UUID = UUID.fromString( "00000201-37cb-11e3-8682-0002a5d5c51b" );
44 | MODE_UUID = UUID.fromString( "00000202-37cb-11e3-8682-0002a5d5c51b" );
45 | DATA_UUID = UUID.fromString( "00000203-37cb-11e3-8682-0002a5d5c51b" );
46 | NOTIFICATION_UUID = UUID.fromString( "00000204-37cb-11e3-8682-0002a5d5c51b" );
47 | USER_TARGET_UUID = UUID.fromString( "00000205-37cb-11e3-8682-0002a5d5c51b" );
48 | ALARM_UUID = UUID.fromString( "00000206-37cb-11e3-8682-0002a5d5c51b" );
49 | ACCEL_DATA_UUID = UUID.fromString( "00000207-37cb-11e3-8682-0002a5d5c51b" );
50 | CURRENT_TIME_UUID = UUID.fromString( "00000208-37cb-11e3-8682-0002a5d5c51b" );
51 | EVENT_UUID = UUID.fromString( "00000209-37cb-11e3-8682-0002a5d5c51b" );
52 | CONTROL_POINT_UUID = UUID.fromString( "00000210-37cb-11e3-8682-0002a5d5c51b" );
53 | DEBUG_UUID = UUID.fromString( "00000211-37cb-11e3-8682-0002a5d5c51b" );
54 | AUTO_NIGHT_MODE_UUID = UUID.fromString( "00000212-37cb-11e3-8682-0002a5d5c51b" );
55 |
56 | sUUIDNameMap.put( SERVICE_UUID , CLASS );
57 | sUUIDNameMap.put( PROTOCOL_VERSION_UUID, "PROTOCOL_VERSION_UUID" );
58 | sUUIDNameMap.put( MODE_UUID , "MODE_UUID" );
59 | sUUIDNameMap.put( DATA_UUID , "DATA_UUID" );
60 | sUUIDNameMap.put( NOTIFICATION_UUID , "NOTIFICATION_UUID" );
61 | sUUIDNameMap.put( USER_TARGET_UUID , "USER_TARGET_UUID" );
62 | sUUIDNameMap.put( ALARM_UUID , "ALARM_UUID" );
63 | sUUIDNameMap.put( ACCEL_DATA_UUID , "ACCEL_DATA_UUID" );
64 | sUUIDNameMap.put( CURRENT_TIME_UUID , "CURRENT_TIME_UUID" );
65 | sUUIDNameMap.put( EVENT_UUID , "EVENT_UUID" );
66 | sUUIDNameMap.put( CONTROL_POINT_UUID , "CONTROL_POINT_UUID" );
67 | sUUIDNameMap.put( DEBUG_UUID , "DEBUG_UUID" );
68 | sUUIDNameMap.put( AUTO_NIGHT_MODE_UUID , "AUTO_NIGHT_MODE_UUID" );
69 | }
70 |
71 | public static int readProtocolVersion( BluetoothGattCharacteristic characteristic ) {
72 | return characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT8, 0 );
73 | }
74 |
75 | // return uptime in seconds
76 | public static int readUptime( BluetoothGattCharacteristic characteristic ) {
77 | return characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT32, 0 );
78 | }
79 |
80 |
81 |
82 | public static BandMode.AccessoryMode readMode( BluetoothGattCharacteristic characteristic ) {
83 | int mode = characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT8, 0 );
84 | return new BandMode( mode ).getMode();
85 | }
86 |
87 | public static long convertBandSecondsToTimestamp( int seconds ) {
88 | return TIMESTAMP_OF_2013 + ( (long) seconds ) * 1000;
89 | }
90 |
91 | public static Date convertBandSecondsToDate( int seconds ) {
92 | long utcTime = convertBandSecondsToTimestamp( seconds );
93 | Calendar calendar = Calendar.getInstance();
94 | calendar.setTimeInMillis( utcTime );
95 | return calendar.getTime();
96 | }
97 |
98 | public static int convertTimestampToBandSeconds( long timestamp ) {
99 | long bandMilliseconds = timestamp - TIMESTAMP_OF_2013;
100 | int bandSeconds = (int) (bandMilliseconds / 1000);
101 |
102 | return bandSeconds;
103 | }
104 |
105 | public static void readData( BluetoothGattCharacteristic characteristic ) {
106 | // TODO
107 | }
108 |
109 | public static BtBandEvent readEvent( BluetoothGattCharacteristic characteristic ) {
110 | int PAYLOAD_SIZE = 4;
111 | int payload = 0;
112 | int offset = 0;
113 |
114 | if( characteristic.getValue().length > PAYLOAD_SIZE ) {
115 | payload = characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT32, 0 );
116 | offset = PAYLOAD_SIZE;
117 | }
118 | int eventData = characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT32, offset );
119 |
120 | int code = ( 0b11111111000000000000000000000000 & eventData ) >> 24;
121 | int value = ( 0b00000000111111111111111111111111 & eventData );
122 | Log.v( CLASS, "readEvent: code=" + code + " value=" + value + " payload=" + payload );
123 |
124 | return new BtBandEvent( code, value, payload );
125 | }
126 |
127 | /**
128 | * Retrieve acceleration data from characteristic with 10bits of resolution
129 | * @param characteristic
130 | * @return int[] array with raw values
131 | */
132 | public static int[] readAccData( BluetoothGattCharacteristic characteristic ) {
133 | int accData = characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT32, 0 );
134 | int x = ( 0b111111111100000000000000000000 & accData ) >> 20;
135 | int y = ( 0b000000000011111111110000000000 & accData ) >> 10;
136 | int z = ( 0b000000000000000000001111111111 & accData );
137 |
138 | return new int[]{ x, y, z };
139 | }
140 |
141 | public static int readCurrentTime( BluetoothGattCharacteristic characteristic ) {
142 | return characteristic.getIntValue( BluetoothGattCharacteristic.FORMAT_UINT32, 0 );
143 | }
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/DebugApp/DebugApp.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/RawBandLogger/RawBandLogger.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/RawBandLogger/src/main/res/layout/activity_rawband.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
19 |
20 |
23 |
24 |
29 |
30 |
31 |
42 |
43 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
65 |
66 |
67 |
78 |
79 |
88 |
89 |
90 |
91 |
94 |
95 |
100 |
101 |
110 |
111 |
120 |
121 |
122 |
125 |
126 |
131 |
132 |
141 |
142 |
151 |
152 |
153 |
156 |
157 |
162 |
163 |
172 |
173 |
182 |
183 |
184 |
185 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/BtAction.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | import android.bluetooth.BluetoothGattCharacteristic;
4 |
5 | import java.util.HashMap;
6 | import java.util.UUID;
7 |
8 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.AADeviceServiceProfile;
9 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.AHServiceProfile;
10 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.BatteryProfile;
11 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.BleConstants;
12 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.DeviceInformationProfile;
13 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.GenericAccessProfile;
14 |
15 | /**
16 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
17 | */
18 | public class BtAction {
19 | public static class ActionDetails {
20 | public final Action mAction;
21 |
22 | public final int mFormat;
23 | public final Type mType;
24 |
25 | public final UUID mService;
26 | public final UUID mCharacteristic;
27 | public final UUID mDescriptor;
28 |
29 | public ActionDetails( Action action, Type type, UUID service, UUID characteristic, UUID descriptor, int format ) {
30 | mAction = action;
31 | mType = type;
32 | mService = service;
33 | mCharacteristic = characteristic;
34 | mDescriptor = descriptor;
35 | mFormat = format;
36 | }
37 |
38 | public ActionDetails( Action action, Type type, UUID service, UUID characteristic, UUID descriptor ) {
39 | this( action, type, service, characteristic, descriptor, 0 );
40 | }
41 |
42 | public ActionDetails( Action action, Type type, UUID service, UUID characteristic, int format ) {
43 | this( action, type, service, characteristic, null, format );
44 | }
45 |
46 | public ActionDetails( Action action, Type type, UUID service, UUID characteristic ) {
47 | this( action, type, service, characteristic, null, 0 );
48 | }
49 | }
50 |
51 | enum Type {
52 | READ_CHAR,
53 | WRITE_CHAR,
54 | ENABLE_NOTIFICATION,
55 | DISABLE_NOTIFICATION
56 | }
57 |
58 | public enum Action {
59 | REQUEST_BATTERY_LEVEL,
60 | REQUEST_PROTOCOL_VERSION,
61 | REQUEST_CURRENT_TIME,
62 | REQUEST_UPTIME,
63 | REQUEST_MODE,
64 | REQUEST_FIRMWARE_REVISION,
65 | REQUEST_HARDWARE_REVISION,
66 | REQUEST_SOFTWARE_REVISION,
67 | REQUEST_MANUFACTURER_NAME,
68 | REQUEST_AAS_VERSION,
69 | REQUEST_AAS_SMART_LINK,
70 | REQUEST_AAS_PRODUCT_ID,
71 | REQUEST_AAS_DEVICE_DATA,
72 | REQUEST_GA_DEVICE_NAME,
73 | SET_MODE,
74 | SET_ACC_INTERVAL,
75 | SET_CURRENT_TIME,
76 | ENABLE_DEBUG_NOTIFICATIONS,
77 | DISABLE_DEBUG_NOTIFICATIONS,
78 | ENABLE_EVENT_NOTIFICATIONS,
79 | DISABLE_EVENT_NOTIFICATIONS,
80 | ENABLE_DATA_NOTIFICATIONS,
81 | DISABLE_DATA_NOTIFICATIONS,
82 | ENABLE_ACC_NOTIFICATIONS,
83 | DISABLE_ACC_NOTIFICATIONS,
84 |
85 | }
86 |
87 | private final static HashMap ACTION_MAP = new HashMap<>( );
88 |
89 | private static void mapAction( Action action, Type type, UUID service, UUID characteristic ) {
90 | ACTION_MAP.put( action, new ActionDetails( action, type, service, characteristic ) );
91 | }
92 |
93 | private static void mapAction( Action action, Type type, UUID service, UUID characteristic, int format ) {
94 | ACTION_MAP.put( action, new ActionDetails( action, type, service, characteristic, format ) );
95 | }
96 |
97 | private static void mapAction( Action action, Type type, UUID service, UUID characteristic, UUID descriptor ) {
98 | ACTION_MAP.put( action, new ActionDetails( action, type, service, characteristic, descriptor ) );
99 | }
100 |
101 | static {
102 | mapAction( Action.REQUEST_BATTERY_LEVEL , Type.READ_CHAR, BatteryProfile.SERVICE_UUID , BatteryProfile.BATTERY_LEVEL_UUID );
103 |
104 | mapAction( Action.REQUEST_PROTOCOL_VERSION , Type.READ_CHAR, AHServiceProfile.SERVICE_UUID , AHServiceProfile.PROTOCOL_VERSION_UUID );
105 | mapAction( Action.REQUEST_CURRENT_TIME , Type.READ_CHAR, AHServiceProfile.SERVICE_UUID , AHServiceProfile.CURRENT_TIME_UUID );
106 | mapAction( Action.REQUEST_MODE , Type.READ_CHAR, AHServiceProfile.SERVICE_UUID , AHServiceProfile.MODE_UUID );
107 | mapAction( Action.REQUEST_UPTIME , Type.READ_CHAR, AHServiceProfile.SERVICE_UUID , AHServiceProfile.DEBUG_UUID );
108 |
109 | mapAction( Action.REQUEST_FIRMWARE_REVISION , Type.READ_CHAR, DeviceInformationProfile.SERVICE_UUID, DeviceInformationProfile.FIRMWARE_REVISION_UUID );
110 | mapAction( Action.REQUEST_HARDWARE_REVISION , Type.READ_CHAR, DeviceInformationProfile.SERVICE_UUID, DeviceInformationProfile.HARDWARE_REVISION_UUID );
111 | mapAction( Action.REQUEST_SOFTWARE_REVISION , Type.READ_CHAR, DeviceInformationProfile.SERVICE_UUID, DeviceInformationProfile.SOFTWARE_REVISION_UUID );
112 | mapAction( Action.REQUEST_MANUFACTURER_NAME , Type.READ_CHAR, DeviceInformationProfile.SERVICE_UUID, DeviceInformationProfile.MANUFACTURER_NAME_UUID );
113 |
114 | mapAction( Action.REQUEST_AAS_VERSION , Type.READ_CHAR, AADeviceServiceProfile.SERVICE_UUID , AADeviceServiceProfile.VERSION_UUID );
115 | mapAction( Action.REQUEST_AAS_SMART_LINK , Type.READ_CHAR, AADeviceServiceProfile.SERVICE_UUID , AADeviceServiceProfile.SMART_LINK_SERVICE_UUID );
116 | mapAction( Action.REQUEST_AAS_PRODUCT_ID , Type.READ_CHAR, AADeviceServiceProfile.SERVICE_UUID , AADeviceServiceProfile.PRODUCT_ID_UUID );
117 | mapAction( Action.REQUEST_AAS_DEVICE_DATA , Type.READ_CHAR, AADeviceServiceProfile.SERVICE_UUID , AADeviceServiceProfile.DATA_UUID );
118 |
119 | mapAction( Action.REQUEST_GA_DEVICE_NAME , Type.READ_CHAR, GenericAccessProfile.SERVICE_UUID , GenericAccessProfile.DEVICE_NAME_UUID );
120 |
121 | mapAction( Action.SET_CURRENT_TIME, Type.WRITE_CHAR, AHServiceProfile.SERVICE_UUID, AHServiceProfile.CURRENT_TIME_UUID, BluetoothGattCharacteristic.FORMAT_UINT32 );
122 | mapAction( Action.SET_MODE , Type.WRITE_CHAR, AHServiceProfile.SERVICE_UUID, AHServiceProfile.MODE_UUID , BluetoothGattCharacteristic.FORMAT_UINT8 );
123 | mapAction( Action.SET_ACC_INTERVAL, Type.WRITE_CHAR, AHServiceProfile.SERVICE_UUID, AHServiceProfile.ACCEL_DATA_UUID , BluetoothGattCharacteristic.FORMAT_UINT32 );
124 |
125 | mapAction( Action.ENABLE_EVENT_NOTIFICATIONS , Type.ENABLE_NOTIFICATION , AHServiceProfile.SERVICE_UUID, AHServiceProfile.EVENT_UUID, BleConstants.CLIENT_CHARACTERISTIC_CONFIGURATION );
126 | mapAction( Action.DISABLE_EVENT_NOTIFICATIONS, Type.DISABLE_NOTIFICATION, AHServiceProfile.SERVICE_UUID, AHServiceProfile.EVENT_UUID, BleConstants.CLIENT_CHARACTERISTIC_CONFIGURATION );
127 | mapAction( Action.ENABLE_DATA_NOTIFICATIONS , Type.ENABLE_NOTIFICATION , AHServiceProfile.SERVICE_UUID, AHServiceProfile.DATA_UUID, BleConstants.CLIENT_CHARACTERISTIC_CONFIGURATION );
128 | mapAction( Action.DISABLE_DATA_NOTIFICATIONS , Type.DISABLE_NOTIFICATION, AHServiceProfile.SERVICE_UUID, AHServiceProfile.DATA_UUID, BleConstants.CLIENT_CHARACTERISTIC_CONFIGURATION );
129 | mapAction( Action.ENABLE_ACC_NOTIFICATIONS , Type.ENABLE_NOTIFICATION , AHServiceProfile.SERVICE_UUID, AHServiceProfile.ACCEL_DATA_UUID, BleConstants.CLIENT_CHARACTERISTIC_CONFIGURATION );
130 | mapAction( Action.DISABLE_ACC_NOTIFICATIONS , Type.DISABLE_NOTIFICATION, AHServiceProfile.SERVICE_UUID, AHServiceProfile.ACCEL_DATA_UUID, BleConstants.CLIENT_CHARACTERISTIC_CONFIGURATION );
131 | mapAction( Action.ENABLE_DEBUG_NOTIFICATIONS , Type.ENABLE_NOTIFICATION , AHServiceProfile.SERVICE_UUID, AHServiceProfile.DEBUG_UUID, BleConstants.CLIENT_CHARACTERISTIC_CONFIGURATION );
132 | mapAction( Action.DISABLE_DEBUG_NOTIFICATIONS, Type.DISABLE_NOTIFICATION, AHServiceProfile.SERVICE_UUID, AHServiceProfile.DEBUG_UUID, BleConstants.CLIENT_CHARACTERISTIC_CONFIGURATION );
133 | }
134 |
135 | public int mParam;
136 |
137 | public final Action mAction;
138 | BtAction( Action action ) {
139 | mAction = action;
140 | }
141 |
142 | public BtAction setParameter( int param ) {
143 | mParam = param;
144 | return this;
145 | }
146 |
147 | public UUID getServiceUUID() {
148 | ActionDetails details = ACTION_MAP.get( mAction );
149 | return details.mService;
150 | }
151 |
152 | public UUID getCharacteristicUUID() {
153 | ActionDetails details = ACTION_MAP.get( mAction );
154 | return details.mCharacteristic;
155 | }
156 |
157 | public UUID getDescriptorUUID() {
158 | ActionDetails details = ACTION_MAP.get( mAction );
159 | return details.mDescriptor;
160 | }
161 |
162 | public Type getType() {
163 | ActionDetails details = ACTION_MAP.get( mAction );
164 | return details.mType;
165 | }
166 |
167 | public int getFormat() {
168 | ActionDetails details = ACTION_MAP.get( mAction );
169 | return details.mFormat;
170 | }
171 |
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/BtBridge.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | import android.bluetooth.BluetoothAdapter;
4 | import android.bluetooth.BluetoothDevice;
5 | import android.bluetooth.BluetoothGatt;
6 | import android.bluetooth.BluetoothGattCallback;
7 | import android.bluetooth.BluetoothGattCharacteristic;
8 | import android.bluetooth.BluetoothGattDescriptor;
9 | import android.bluetooth.BluetoothGattService;
10 | import android.bluetooth.BluetoothManager;
11 | import android.bluetooth.BluetoothProfile;
12 | import android.content.Context;
13 | import android.util.Log;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 | import java.util.Set;
18 | import java.util.UUID;
19 |
20 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.BaseProfile;
21 |
22 | /**
23 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
24 | */
25 |
26 | // TODO: how to handle when status != BluetoothGatt.GATT_SUCCESS
27 | public class BtBridge extends BluetoothGattCallback {
28 | public final static String[] COMPATIBLE_DEVICES = { "SWR10" };
29 | public final String CLASS = getClass().getSimpleName();
30 |
31 | public enum Status {
32 | CONNECTED,
33 | DISCONNECTED,
34 | CONNECTING
35 | }
36 |
37 | private Context mContext;
38 | ArrayList mListeners = new ArrayList<>();
39 |
40 | private BluetoothAdapter mBluetoothAdapter;
41 | private BluetoothGatt mGatt;
42 |
43 | private Status mStatus;
44 |
45 | private ArrayList mDevices = new ArrayList<>();
46 |
47 | BtBridge( Context context ) {
48 | mContext = context;
49 | BluetoothManager btManager = ( BluetoothManager ) mContext.getSystemService( Context.BLUETOOTH_SERVICE );
50 | mBluetoothAdapter = btManager.getAdapter();
51 | mStatus = Status.DISCONNECTED;
52 | }
53 |
54 | public Status getStatus() {
55 | return mStatus;
56 | }
57 |
58 | public void addListener( BtBridgeListener listener ) {
59 | if( mListeners.contains( listener ) ) {
60 | Log.w( CLASS, "addListener: Listener already registered" );
61 | } else {
62 | mListeners.add( listener );
63 | }
64 | }
65 |
66 | public boolean isDeviceCompatible( String deviceName ) {
67 | for( String device : COMPATIBLE_DEVICES ) {
68 | if( device.equals( deviceName ) ) {
69 | return true;
70 | }
71 | }
72 | return false;
73 | }
74 |
75 | public boolean connect() {
76 | Log.d( CLASS, "connect: called." );
77 |
78 | if( !mStatus.equals( Status.DISCONNECTED ) ) {
79 | Log.e( CLASS, "connect: Invalid status=" + mStatus.name() );
80 | return false;
81 | }
82 |
83 | populatePairedDevices();
84 | BluetoothDevice btDevice = getDevice();
85 | if( btDevice == null ) {
86 | Log.e( CLASS, "connect: Device not found." );
87 | return false;
88 | }
89 |
90 | mStatus = Status.CONNECTING;
91 | btDevice.connectGatt( mContext, true, this );
92 | return true;
93 | }
94 |
95 |
96 | public boolean disconnect() {
97 | Log.d( CLASS, "disconnect: called." );
98 | if( !mStatus.equals( Status.CONNECTED ) ) {
99 | Log.e( CLASS, "disconnect: Not connected: status=" + mStatus.name() );
100 | return false;
101 | }
102 |
103 | if( mGatt == null ) {
104 | Log.e( CLASS, "disconnect: mGatt not found" );
105 | return false;
106 | }
107 |
108 | Log.i( CLASS, "disconnect: disconnected." );
109 | mGatt.disconnect();
110 | return true;
111 | }
112 |
113 | public boolean isGattReady() {
114 | if( !mStatus.equals( Status.CONNECTED ) ) {
115 | Log.e( CLASS, "isGattReady: Not connected: status=" + mStatus.name() );
116 | return false;
117 | }
118 |
119 | if( mGatt == null ) {
120 | Log.e( CLASS, "isGattReady: mGatt not found" );
121 | return false;
122 | }
123 |
124 | return true;
125 | }
126 |
127 | public boolean discoverServices() {
128 | Log.d( CLASS, "discoverServices: called." );
129 | if( !isGattReady() ) {
130 | Log.e( CLASS, "discoverServices: Gatt not ready" );
131 | return false;
132 | }
133 |
134 | return true;
135 | }
136 |
137 | private BluetoothDevice getDevice() {
138 | for( BluetoothDevice btdev : mDevices ) {
139 | if( isDeviceCompatible( btdev.getName() ) ) {
140 | Log.d( CLASS, "getDevice: Device found: addr=" + btdev.getAddress() );
141 | return btdev;
142 | }
143 | }
144 |
145 | Log.w( CLASS, "getDevice: device not found." );
146 | return null;
147 | }
148 |
149 | private void populatePairedDevices() {
150 | Log.d( CLASS, "populatePairedDevices: called." );
151 | Set pairedDevices = mBluetoothAdapter.getBondedDevices();
152 |
153 | mDevices.clear();
154 | if( pairedDevices != null && pairedDevices.size() > 0 ) {
155 | mDevices.addAll( pairedDevices );
156 | }
157 | printPairedDevices();
158 | }
159 |
160 | private void printPairedDevices() {
161 | Log.i( CLASS, "printPairedDevices: mDevices=" + mDevices.size() );
162 | for( BluetoothDevice btdev : mDevices ) {
163 | Log.i( CLASS, "printPairedDevices: addr=" + btdev.getAddress() + " name=" + btdev.getName() );
164 | }
165 | }
166 |
167 | public BluetoothGattCharacteristic getCharacteristic( UUID serviceUuid, UUID characteristicUuid ) {
168 | if( !isGattReady() ) {
169 | Log.e( CLASS, "getCharacteristic: Gatt not ready" );
170 | return null;
171 | }
172 |
173 | BaseProfile serviceProfile = Profiles.getService( serviceUuid );
174 | if( serviceProfile == null ) {
175 | Log.e( CLASS, "getCharacteristic: serviceProfile not found. serviceUuid=" + serviceUuid );
176 | }
177 |
178 | BluetoothGattService service = mGatt.getService( serviceUuid );
179 | if( service == null ) {
180 | Log.e( CLASS, "getCharacteristic: service not found (on gatt). serviceUuid=" + serviceUuid );
181 | return null;
182 | }
183 |
184 | BluetoothGattCharacteristic characteristic = service.getCharacteristic( characteristicUuid );
185 | if( characteristic == null ) {
186 | Log.e( CLASS, "getCharacteristic: characteristic not found. uuid=" + characteristicUuid );
187 | return null;
188 | }
189 |
190 | return characteristic;
191 | }
192 |
193 | public boolean readCharacteristic( BluetoothGattCharacteristic characteristic ) {
194 | if( characteristic == null ) {
195 | Log.e( CLASS, "readCharacteristic: characteristic=null" );
196 | return false;
197 | }
198 |
199 | if( !isGattReady() ) {
200 | Log.e( CLASS, "readCharacteristic: Gatt not ready" );
201 | return false;
202 | }
203 |
204 | return mGatt.readCharacteristic( characteristic );
205 | }
206 |
207 | public boolean writeCharacteristic( BluetoothGattCharacteristic characteristic ) {
208 | if( !isGattReady() ) {
209 | Log.e( CLASS, "writeCharacteristic: Gatt not ready" );
210 | return false;
211 | }
212 |
213 | return mGatt.writeCharacteristic( characteristic );
214 | }
215 |
216 | public boolean writeDescriptor( BluetoothGattDescriptor descriptor ) {
217 | if( !isGattReady() ) {
218 | Log.e( CLASS, "writeDescriptor: Gatt not ready" );
219 | return false;
220 | }
221 |
222 | return mGatt.writeDescriptor( descriptor );
223 | }
224 |
225 | public boolean setCharacteristicNotification( BluetoothGattCharacteristic characteristic, boolean enabled ) {
226 | if( !isGattReady() ) {
227 | Log.e( CLASS, "setCharacteristicNotification: Gatt not ready" );
228 | return false;
229 | }
230 |
231 | return mGatt.setCharacteristicNotification( characteristic, enabled );
232 | }
233 |
234 | @Override
235 | public void onConnectionStateChange( BluetoothGatt gatt, int status, int newState ) {
236 | if( status != BluetoothGatt.GATT_SUCCESS ) {
237 | Log.e( CLASS, "onConnectionStateChange: Status != SUCCESS: status=" + status );
238 | return;
239 | }
240 |
241 | Log.d( CLASS, "onConnectionStateChange: Status=" + status );
242 |
243 | switch( newState ) {
244 | case BluetoothProfile.STATE_CONNECTED:
245 | mStatus = Status.CONNECTED;
246 | mGatt = gatt;
247 | Log.d( CLASS, "onConnectionStateChange: newState=STATE_CONNECTED" );
248 | mGatt.discoverServices();
249 | break;
250 | case BluetoothProfile.STATE_DISCONNECTED:
251 | mStatus = Status.DISCONNECTED;
252 | Log.d( CLASS, "onConnectionStateChange: newState=STATE_DISCONNECTED" );
253 | Log.e( "gattCallback", "STATE_DISCONNECTED" );
254 | break;
255 | default:
256 | Log.w( CLASS, "onConnectionStateChange: newState=" + newState );
257 | }
258 |
259 | for( BtBridgeListener listener : mListeners ) {
260 | listener.onConnectionStateChange( mStatus );
261 | }
262 | }
263 |
264 | @Override
265 | // TODO: maybe here we should set status == CONNECTED
266 | public void onServicesDiscovered( BluetoothGatt gatt, int status ) {
267 | if( status != BluetoothGatt.GATT_SUCCESS ) {
268 | Log.e( CLASS, "onServicesDiscovered: Status != SUCCESS: status=" + status );
269 | return;
270 | }
271 | mGatt = gatt;
272 |
273 | List services = gatt.getServices();
274 | Log.d( CLASS, "onServicesDiscovered: services=" + services.size() );
275 |
276 | for( BtBridgeListener listener : mListeners ) {
277 | listener.onServicesDiscovered( services );
278 | }
279 | }
280 |
281 | @Override
282 | public void onCharacteristicRead( BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status ) {
283 | if( status != BluetoothGatt.GATT_SUCCESS ) {
284 | Log.e( CLASS, "onCharacteristicRead: Status != SUCCESS: status=" + status );
285 | return;
286 | }
287 | mGatt = gatt;
288 |
289 | if( characteristic == null ) {
290 | Log.e( CLASS, "onCharacteristicRead: null characteristic" );
291 | return;
292 | }
293 |
294 | for( BtBridgeListener listener : mListeners ) {
295 | listener.onCharacteristicRead( characteristic );
296 | }
297 | }
298 |
299 | @Override
300 | public void onCharacteristicChanged( BluetoothGatt gatt, BluetoothGattCharacteristic characteristic ) {
301 | if( characteristic == null ) {
302 | Log.e( CLASS, "onCharacteristicChanged: null characteristic" );
303 | return;
304 | }
305 | mGatt = gatt;
306 |
307 | for( BtBridgeListener listener : mListeners ) {
308 | listener.onCharacteristicChanged( characteristic );
309 | }
310 | }
311 |
312 | @Override
313 | public void onCharacteristicWrite( BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status ) {
314 | if( status != BluetoothGatt.GATT_SUCCESS ) {
315 | Log.e( CLASS, "onCharacteristicWrite: Status != SUCCESS: status=" + status );
316 | return;
317 | }
318 | mGatt = gatt;
319 |
320 | if( characteristic == null ) {
321 | Log.e( CLASS, "onCharacteristicWrite: null characteristic" );
322 | return;
323 | }
324 |
325 | for( BtBridgeListener listener : mListeners ) {
326 | listener.onCharacteristicWrite( characteristic );
327 | }
328 | }
329 |
330 |
331 | @Override
332 | public void onDescriptorRead( BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status ) {
333 | if( status != BluetoothGatt.GATT_SUCCESS ) {
334 | Log.e( CLASS, "onDescriptorRead: Status != SUCCESS: status=" + status );
335 | return;
336 | }
337 | mGatt = gatt;
338 |
339 | if( descriptor == null ) {
340 | Log.e( CLASS, "onDescriptorRead: null descriptor" );
341 | return;
342 | }
343 |
344 | BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
345 | for( BtBridgeListener listener : mListeners ) {
346 | listener.onDescriptorRead( characteristic, descriptor );
347 | }
348 | }
349 |
350 | @Override
351 | public void onDescriptorWrite( BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status ) {
352 | if( status != BluetoothGatt.GATT_SUCCESS ) {
353 | Log.e( CLASS, "onDescriptorWrite: Status != SUCCESS: status=" + status );
354 | return;
355 | }
356 | mGatt = gatt;
357 |
358 | if( descriptor == null ) {
359 | Log.e( CLASS, "onDescriptorWrite: null descriptor" );
360 | return;
361 | }
362 |
363 | BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
364 | for( BtBridgeListener listener : mListeners ) {
365 | listener.onDescriptorWrite( characteristic, descriptor );
366 | }
367 | }
368 | }
369 |
--------------------------------------------------------------------------------
/DebugApp/src/main/java/cl/felipebarriga/android/sony/smartband/api/demo/DebugActivity.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.demo;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.widget.Button;
9 | import android.widget.TableLayout;
10 | import android.widget.TableRow;
11 | import android.widget.TextView;
12 |
13 | import java.text.SimpleDateFormat;
14 | import java.util.Date;
15 | import java.util.HashMap;
16 |
17 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BandMode;
18 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtAction;
19 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBand;
20 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBandEvent;
21 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBandListener;
22 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.BtBridge;
23 |
24 | /**
25 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
26 | */
27 | public class DebugActivity extends Activity implements BtBandListener {
28 | private final String CLASS = getClass().getSimpleName();
29 |
30 | @Override
31 | public void onAHServiceReadAccData( int[] data ) {
32 | Log.d( CLASS, "onAHServiceReadAccData: data=[" + data[0] + "," + data[1] + "," + data[2] + "]" );
33 | }
34 |
35 | @Override
36 | public void onAHServiceReadEvent( BtBandEvent event ) {
37 | Log.d( CLASS, "onAHServiceReadEvent: event=" + event );
38 | }
39 |
40 | @Override
41 | public void onAHServiceReadCurrentTime( int bandSeconds, Date deviceDate, long deltaMs ) {
42 | Log.d( CLASS, "onAHServiceReadCurrentTime: bandSeconds=" + bandSeconds
43 | +" deviceDate=" + deviceDate + " deltaMs=" + deltaMs );
44 |
45 | SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
46 | updateUILabel( RowId.CURRENT_TIME, sdf.format( deviceDate ) );
47 | }
48 |
49 | @Override
50 | public void onAHServiceReadProtocolVersion( int version ) {
51 | Log.d( CLASS, "onAHServiceReadProtocolVersion: version=" + version );
52 | updateUILabel( RowId.PROTOCOL_VERSION, String.valueOf( version ) );
53 | }
54 |
55 | @Override
56 | public void onAHServiceReadData( ) {
57 | Log.d( CLASS, "onAHServiceReadData: called." );
58 | }
59 |
60 | @Override
61 | public void onAHServiceReadMode( BandMode.AccessoryMode mode ) {
62 | Log.d( CLASS, "onAHServiceReadMode: mode=" + mode.name() );
63 | updateUILabel( RowId.CURRENT_MODE, mode.name() );
64 | }
65 |
66 | @Override
67 | public void onAHServiceReadUptime( int uptime, Date started ) {
68 | Log.d( CLASS, "onAHServiceReadUptime: started=" + started + " uptime=" + uptime );
69 | updateUILabel( RowId.UPTIME, String.valueOf( uptime ) );
70 | }
71 |
72 | @Override
73 | public void onBatteryLevel( int level ) {
74 | Log.d( CLASS, "onBatteryLevel: level=" + level );
75 | updateUILabel( RowId.BATTERY_LEVEL, String.valueOf( level ) );
76 | }
77 |
78 | @Override
79 | public void onFirmwareRevision( String rev ) {
80 | updateUILabel( RowId.FIRMWARE_REVISION, rev );
81 | }
82 |
83 | @Override
84 | public void onSoftwareRevision( String rev ) {
85 | updateUILabel( RowId.SOFTWARE_REVISION, rev );
86 | }
87 |
88 | @Override
89 | public void onHardwareRevision( String rev ) {
90 | updateUILabel( RowId.HARDWARE_REVISION, rev );
91 | }
92 |
93 | @Override
94 | public void onManufacturerName( String name ) {
95 | updateUILabel( RowId.MANUFACTURER_NAME, name );
96 | }
97 |
98 | @Override
99 | public void onAASDeviceVersion( int version ) {
100 | updateUILabel( RowId.AAS_VERSION, String.valueOf( version ) );
101 | }
102 |
103 | @Override
104 | public void onAASDeviceSmartLink( int smartLink ) {
105 | updateUILabel( RowId.AAS_SMART_LINK, String.valueOf( smartLink ) );
106 | }
107 |
108 | @Override
109 | public void onAASDeviceProductId( String productId ) {
110 | updateUILabel( RowId.AAS_PRODUCT_ID, productId );
111 | }
112 |
113 | @Override
114 | public void onAASDeviceData( String data ) {
115 | updateUILabel( RowId.AAS_DATA, data );
116 | }
117 |
118 | @Override
119 | public void onGADeviceName( String name ) {
120 | updateUILabel( RowId.GA_DEVICE_NAME, name );
121 | }
122 |
123 | @Override
124 | public void onConnectionStateChange( final BtBridge.Status status ) {
125 | Log.i( CLASS, "onConnectionStateChange: status=" + status.name() );
126 | updateUILabel( RowId.STATUS, status.name() );
127 | if( status == BtBridge.Status.CONNECTED ) {
128 | updateUIButton( RowId.STATUS, true, "Disconnect" );
129 | } else if( status == BtBridge.Status.DISCONNECTED ) {
130 | updateUIButton( RowId.STATUS, true, "Connect" );
131 | } else {
132 | updateUIButton( RowId.STATUS, false, "Disconnect" );
133 | }
134 | }
135 |
136 | @Override
137 | public void onServicesDiscovered() {
138 | Log.i( CLASS, "onServicesDiscovered: called" );
139 | }
140 |
141 | public enum RowId {
142 | ENABLE_EVENT_NOTIFICATIONS,
143 | ENABLE_DATA_NOTIFICATIONS,
144 | ENABLE_ACC_NOTIFICATIONS,
145 | ENABLE_DEBUG_NOTIFICATIONS,
146 | SEND_CURRENT_TIME,
147 | STATUS,
148 | UPTIME,
149 | CURRENT_MODE,
150 | BATTERY_LEVEL,
151 | CURRENT_TIME,
152 | PROTOCOL_VERSION,
153 | FIRMWARE_REVISION,
154 | SOFTWARE_REVISION,
155 | HARDWARE_REVISION,
156 | MANUFACTURER_NAME,
157 | AAS_VERSION,
158 | AAS_SMART_LINK,
159 | AAS_PRODUCT_ID,
160 | AAS_DATA,
161 | GA_DEVICE_NAME
162 | }
163 |
164 | public static final HashMap mRowActionMap = new HashMap<>( );
165 |
166 | static {
167 | mRowActionMap.put( RowId.BATTERY_LEVEL , BtAction.Action.REQUEST_BATTERY_LEVEL );
168 |
169 | mRowActionMap.put( RowId.UPTIME , BtAction.Action.REQUEST_UPTIME );
170 | mRowActionMap.put( RowId.CURRENT_MODE , BtAction.Action.REQUEST_MODE );
171 | mRowActionMap.put( RowId.CURRENT_TIME , BtAction.Action.REQUEST_CURRENT_TIME );
172 | mRowActionMap.put( RowId.PROTOCOL_VERSION , BtAction.Action.REQUEST_PROTOCOL_VERSION );
173 |
174 | mRowActionMap.put( RowId.FIRMWARE_REVISION, BtAction.Action.REQUEST_FIRMWARE_REVISION );
175 | mRowActionMap.put( RowId.SOFTWARE_REVISION, BtAction.Action.REQUEST_SOFTWARE_REVISION );
176 | mRowActionMap.put( RowId.HARDWARE_REVISION, BtAction.Action.REQUEST_HARDWARE_REVISION );
177 | mRowActionMap.put( RowId.MANUFACTURER_NAME, BtAction.Action.REQUEST_MANUFACTURER_NAME );
178 |
179 | mRowActionMap.put( RowId.AAS_VERSION , BtAction.Action.REQUEST_AAS_VERSION );
180 | mRowActionMap.put( RowId.AAS_SMART_LINK , BtAction.Action.REQUEST_AAS_SMART_LINK );
181 | mRowActionMap.put( RowId.AAS_PRODUCT_ID , BtAction.Action.REQUEST_AAS_PRODUCT_ID );
182 | mRowActionMap.put( RowId.AAS_DATA , BtAction.Action.REQUEST_AAS_DEVICE_DATA );
183 |
184 | mRowActionMap.put( RowId.GA_DEVICE_NAME , BtAction.Action.REQUEST_GA_DEVICE_NAME );
185 | }
186 |
187 | private void updateUILabel( final RowId rowId, final String textValue ) {
188 | mHandler.post(new Runnable() {
189 | @Override
190 | public void run() {
191 | TextView textView = mRowIdValueTextViewMap.get( rowId );
192 | if( textView == null ) {
193 | Log.e( CLASS, "updateUILabel: Error, view not found. rowId=" + rowId.name() );
194 | return;
195 | }
196 |
197 | textView.setText( textValue );
198 | }
199 | });
200 | }
201 |
202 | private void updateUIButton( final RowId rowId, final boolean enabled, final String textValue ) {
203 | mHandler.post(new Runnable() {
204 | @Override
205 | public void run() {
206 | Button btn = mRowIdButtonMap.get( rowId );
207 | if( btn == null ) {
208 | Log.e( CLASS, "updateUIButton: Error, btn not found. rowId=" + rowId.name() );
209 | return;
210 | }
211 | btn.setEnabled( enabled );
212 | btn.setText( textValue );
213 | }
214 | });
215 | }
216 |
217 | private static HashMap mRowIdButtonMap = new HashMap<>( );
218 | private static HashMap mRowIdValueTextViewMap = new HashMap<>( );
219 | private static HashMap mViewRowIdMap = new HashMap<>( );
220 |
221 | private TableRow createRow( RowId rowId, String label, String defaultValue,
222 | String btnText, View.OnClickListener btnListener ) {
223 |
224 | TableRow tb = new TableRow( this );
225 | TextView labelText = new TextView( this );
226 | TextView valueText = new TextView( this );
227 | Button btn = new Button( this );
228 |
229 | labelText.setText( label );
230 | valueText.setText( defaultValue );
231 | btn.setText( btnText );
232 |
233 | btn.setOnClickListener( btnListener );
234 |
235 | tb.addView( labelText );
236 | tb.addView( valueText );
237 | tb.addView( btn );
238 |
239 | mRowIdButtonMap.put( rowId, btn );
240 | mRowIdValueTextViewMap.put( rowId, valueText );
241 | mViewRowIdMap.put( btn, rowId );
242 |
243 | return tb;
244 | }
245 |
246 | private View.OnClickListener mClickListener = new View.OnClickListener() {
247 | @Override
248 | public void onClick( View v ) {
249 | RowId rowId = mViewRowIdMap.get( v );
250 | TextView valueTextView = mRowIdValueTextViewMap.get( rowId );
251 | if( rowId == RowId.STATUS ) {
252 | switch( mBtBand.getStatus() ) {
253 | case DISCONNECTED:
254 | try {
255 | mBtBand.connect();
256 | } catch( Exception e ) {
257 | e.printStackTrace();
258 | }
259 | break;
260 |
261 | case CONNECTED:
262 | mBtBand.disconnect();
263 | break;
264 |
265 | case CONNECTING:
266 | break;
267 | }
268 | valueTextView.setText( mBtBand.getStatus().name() );
269 | return;
270 | }
271 |
272 | if( !mBtBand.getStatus().equals( BtBridge.Status.CONNECTED ) ) {
273 | Log.e( CLASS, "onClick: " + rowId.name() + " not connected" );
274 | return;
275 | }
276 |
277 | if( rowId == RowId.SEND_CURRENT_TIME ) {
278 | mBtBand.syncDeviceTime();
279 | return;
280 | }
281 |
282 | if( rowId == RowId.ENABLE_EVENT_NOTIFICATIONS ) {
283 | if( mBtBand.isEventNotificationsEnabled() ) {
284 | mBtBand.addRequest( BtAction.Action.DISABLE_EVENT_NOTIFICATIONS );
285 | valueTextView.setText( "Disable" );
286 | } else {
287 | mBtBand.addRequest( BtAction.Action.ENABLE_EVENT_NOTIFICATIONS );
288 | valueTextView.setText( "Enable" );
289 | }
290 | return;
291 | }
292 |
293 | if( rowId == RowId.ENABLE_DATA_NOTIFICATIONS ) {
294 | if( mBtBand.isDataNotificationsEnabled() ) {
295 | mBtBand.addRequest( BtAction.Action.DISABLE_DATA_NOTIFICATIONS );
296 | valueTextView.setText( "Disable" );
297 | } else {
298 | mBtBand.addRequest( BtAction.Action.ENABLE_DATA_NOTIFICATIONS );
299 | valueTextView.setText( "Enable" );
300 | }
301 | return;
302 | }
303 |
304 | if( rowId == RowId.ENABLE_ACC_NOTIFICATIONS ) {
305 | if( mBtBand.isAccNotificationsEnabled() ) {
306 | mBtBand.addRequest( BtAction.Action.DISABLE_ACC_NOTIFICATIONS );
307 | valueTextView.setText( "Disable" );
308 | } else {
309 | mBtBand.addRequest( BtAction.Action.ENABLE_ACC_NOTIFICATIONS );
310 | valueTextView.setText( "Enable" );
311 | }
312 | return;
313 | }
314 |
315 | if( rowId == RowId.ENABLE_DEBUG_NOTIFICATIONS ) {
316 | if( mBtBand.isDebugNotificationsEnabled() ) {
317 | mBtBand.addRequest( BtAction.Action.DISABLE_DEBUG_NOTIFICATIONS );
318 | valueTextView.setText( "Disable" );
319 | } else {
320 | mBtBand.addRequest( BtAction.Action.ENABLE_DEBUG_NOTIFICATIONS );
321 | valueTextView.setText( "Enable" );
322 | }
323 | return;
324 | }
325 |
326 | BtAction.Action action = mRowActionMap.get( rowId );
327 | if( rowId != null ) {
328 | mBtBand.addRequest( action );
329 | return;
330 | }
331 |
332 | switch( rowId ) {
333 |
334 | default:
335 | Log.e( CLASS, "onClick: unknown rowId: " + rowId.name() );
336 | break;
337 | }
338 |
339 | }
340 | };
341 |
342 | private BtBand mBtBand;
343 | private Handler mHandler;
344 |
345 | private void uiPopulateRows( TableLayout tl ) {
346 | tl.addView( createRow( RowId.STATUS , "Status:" , "-", "Connect", mClickListener ) );
347 | tl.addView( createRow( RowId.UPTIME , "Uptime:" , "-", "Update" , mClickListener ) );
348 | tl.addView( createRow( RowId.CURRENT_MODE , "Current Mode:" , "-", "Update" , mClickListener ) );
349 | tl.addView( createRow( RowId.PROTOCOL_VERSION, "Protocol Version:", "-", "Update" , mClickListener ) );
350 | tl.addView( createRow( RowId.CURRENT_TIME , "Current Time:" , "-", "Update" , mClickListener ) );
351 |
352 | tl.addView( createRow( RowId.BATTERY_LEVEL, "Battery Level:", "-", "Update" , mClickListener ) );
353 |
354 | tl.addView( createRow( RowId.FIRMWARE_REVISION, "Firmware Rev.:", "-", "Update", mClickListener ) );
355 | tl.addView( createRow( RowId.HARDWARE_REVISION, "Hardware Rev.:", "-", "Update", mClickListener ) );
356 | tl.addView( createRow( RowId.SOFTWARE_REVISION, "Software Rev.:", "-", "Update", mClickListener ) );
357 | tl.addView( createRow( RowId.MANUFACTURER_NAME, "Manufacturer:" , "-", "Update", mClickListener ) );
358 |
359 | tl.addView( createRow( RowId.AAS_VERSION , "AAS Version:" , "-", "Update", mClickListener ) );
360 | tl.addView( createRow( RowId.AAS_SMART_LINK, "AAS SmartLink:", "-", "Update", mClickListener ) );
361 | tl.addView( createRow( RowId.AAS_PRODUCT_ID, "AAS ProductId:", "-", "Update", mClickListener ) );
362 | tl.addView( createRow( RowId.AAS_DATA , "AAS Data:" , "-", "Update", mClickListener ) );
363 |
364 | tl.addView( createRow( RowId.GA_DEVICE_NAME, "GA Device Name:", "-", "Update", mClickListener ) );
365 |
366 | tl.addView( createRow( RowId.SEND_CURRENT_TIME, "Send Current Time:", "-", "Update", mClickListener ) );
367 |
368 | tl.addView( createRow( RowId.ENABLE_EVENT_NOTIFICATIONS, "Event Notifications:" , "-", "Enable", mClickListener ) );
369 | tl.addView( createRow( RowId.ENABLE_DATA_NOTIFICATIONS , "Data Notifications:" , "-", "Enable", mClickListener ) );
370 | tl.addView( createRow( RowId.ENABLE_ACC_NOTIFICATIONS , "Accelerometer Notif.:", "-", "Enable", mClickListener ) );
371 | tl.addView( createRow( RowId.ENABLE_DEBUG_NOTIFICATIONS, "Debug Notifications:" , "-", "Enable", mClickListener ) );
372 | }
373 |
374 | private void uiAddModeRow(TableLayout tl ) {
375 | TableRow tb = new TableRow( this );
376 | TextView labelText = new TextView( this );
377 |
378 | Button btnDay = new Button( this );
379 | Button btnNight = new Button( this );
380 | Button btnMedia = new Button( this );
381 | Button btnFirmware = new Button( this );
382 |
383 | labelText.setText( "Mode:" );
384 |
385 | btnDay.setText( "Day" );
386 | btnNight.setText( "Night" );
387 | btnMedia.setText( "Media" );
388 | btnFirmware.setText( "Firmware" );
389 |
390 | btnDay.setOnClickListener( new View.OnClickListener() {
391 | @Override
392 | public void onClick( View v ) {
393 | mBtBand.addRequest( BtAction.Action.SET_MODE, BandMode.getInt( BandMode.AccessoryMode.DAY ) );
394 | }
395 | } );
396 |
397 | btnNight.setOnClickListener( new View.OnClickListener() {
398 | @Override
399 | public void onClick( View v ) {
400 | mBtBand.addRequest( BtAction.Action.SET_MODE, BandMode.getInt( BandMode.AccessoryMode.NIGHT ) );
401 | }
402 | } );
403 |
404 | btnMedia.setOnClickListener( new View.OnClickListener() {
405 | @Override
406 | public void onClick( View v ) {
407 | mBtBand.addRequest( BtAction.Action.SET_MODE, BandMode.getInt( BandMode.AccessoryMode.MEDIA ) );
408 | }
409 | } );
410 |
411 | btnFirmware.setOnClickListener( new View.OnClickListener() {
412 | @Override
413 | public void onClick( View v ) {
414 | mBtBand.addRequest( BtAction.Action.SET_MODE, BandMode.getInt( BandMode.AccessoryMode.FIRMWARE_UPDATE ) );
415 | }
416 | } );
417 |
418 | tb.addView( labelText );
419 | tb.addView( btnDay );
420 | tb.addView( btnNight );
421 | tb.addView( btnMedia );
422 | tb.addView( btnFirmware );
423 | tl.addView( tb );
424 | }
425 |
426 | @Override
427 | protected void onCreate( Bundle savedInstanceState ) {
428 | super.onCreate( savedInstanceState );
429 | Log.v( CLASS, "onCreate: called." );
430 |
431 | mHandler = new Handler( );
432 | mBtBand = new BtBand( this );
433 | mBtBand.addListener( this );
434 | setContentView( R.layout.activity_debug );
435 |
436 | TableLayout tl = ( TableLayout ) findViewById( R.id.debug_table_layout );
437 | uiPopulateRows( tl );
438 | uiAddModeRow( tl );
439 | }
440 |
441 | @Override
442 | protected void onStart() {
443 | super.onStart();
444 | Log.v( CLASS, "onStart: called." );
445 | }
446 |
447 | @Override
448 | protected void onResume() {
449 | super.onResume();
450 | Log.v( CLASS, "onResume: called." );
451 | }
452 |
453 | @Override
454 | protected void onPause() {
455 | super.onPause();
456 | Log.v( CLASS, "onPause: called." );
457 | }
458 |
459 | @Override
460 | protected void onRestart() {
461 | super.onRestart();
462 | Log.v( CLASS, "onRestart: called." );
463 | }
464 |
465 | @Override
466 | protected void onStop() {
467 | super.onStop();
468 | Log.v( CLASS, "onStop: called." );
469 | }
470 |
471 | @Override
472 | protected void onDestroy() {
473 | super.onDestroy();
474 | Log.v( CLASS, "onDestroy: called." );
475 | mBtBand.disconnect();
476 | }
477 |
478 |
479 | }
480 |
--------------------------------------------------------------------------------
/SonySmartBandOpenAPI/src/main/java/cl/felipebarriga/android/sony/smartband/api/bluetooth/BtBand.java:
--------------------------------------------------------------------------------
1 | package cl.felipebarriga.android.sony.smartband.api.bluetooth;
2 |
3 | import android.bluetooth.BluetoothGattCharacteristic;
4 | import android.bluetooth.BluetoothGattDescriptor;
5 | import android.bluetooth.BluetoothGattService;
6 | import android.content.Context;
7 | import android.util.Log;
8 |
9 | import java.util.ArrayList;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 | import java.util.List;
13 | import java.util.Queue;
14 | import java.util.UUID;
15 | import java.util.concurrent.LinkedBlockingQueue;
16 |
17 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.AADeviceServiceProfile;
18 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.AHServiceProfile;
19 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.BaseProfile;
20 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.BatteryProfile;
21 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.BleConstants;
22 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.DeviceInformationProfile;
23 | import cl.felipebarriga.android.sony.smartband.api.bluetooth.profiles.GenericAccessProfile;
24 |
25 | /**
26 | * Copyright (c) 2015 Felipe Barriga Richards. See Copyright Notice in LICENSE file.
27 | */
28 | public class BtBand implements BtBridgeListener {
29 |
30 | private final String CLASS = getClass().getSimpleName();
31 |
32 | private BtBridge mBtBridge;
33 | private Context mContext;
34 |
35 | ArrayList mListeners = new ArrayList<>();
36 |
37 | private boolean mEventNotificationsEnabled;
38 | private boolean mDataNotificationsEnabled;
39 | private boolean mDebugNotificationsEnabled;
40 | private boolean mAccNotificationsEnabled;
41 |
42 | public boolean isEventNotificationsEnabled() {
43 | return mEventNotificationsEnabled;
44 | }
45 |
46 | public boolean isDataNotificationsEnabled() {
47 | return mDataNotificationsEnabled;
48 | }
49 |
50 | public boolean isDebugNotificationsEnabled() {
51 | return mDebugNotificationsEnabled;
52 | }
53 |
54 | public boolean isAccNotificationsEnabled() {
55 | return mAccNotificationsEnabled;
56 | }
57 |
58 | public BtBridge.Status getStatus() {
59 | return mBtBridge.getStatus();
60 | }
61 |
62 | public void addListener( BtBandListener listener ) {
63 | if( mListeners.contains( listener ) ) {
64 | Log.w( CLASS, "setOnBtBandListener: Listener already registered" );
65 | } else {
66 | mListeners.add( listener );
67 | }
68 | }
69 |
70 | public BtBand( Context context ) {
71 | mEventNotificationsEnabled = false;
72 | mDataNotificationsEnabled = false;
73 | mDebugNotificationsEnabled = false;
74 | mAccNotificationsEnabled = false;
75 |
76 | mContext = context;
77 | mBtBridge = new BtBridge( mContext );
78 | mBtBridge.addListener( this );
79 | }
80 |
81 | private DescriptorInfo getDescriptorInfo( BluetoothGattDescriptor descriptor ) {
82 | BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
83 | return getDescriptorInfo( characteristic.getService().getUuid(), characteristic.getUuid(), descriptor.getUuid() );
84 | }
85 |
86 | private DescriptorInfo getDescriptorInfo( UUID serviceUuid, UUID characteristicUuid, UUID descriptorUuid ) {
87 | BaseProfile serviceProfile = Profiles.getService( serviceUuid );
88 | return new DescriptorInfo(
89 | serviceProfile.getClass().getSimpleName(),
90 | serviceProfile.getUuidName( characteristicUuid ),
91 | BleConstants.getUuidName( descriptorUuid )
92 | );
93 | }
94 |
95 | private CharacteristicInfo getCharacteristicInfo( BluetoothGattCharacteristic characteristic ) {
96 | return getCharacteristicInfo( characteristic.getService().getUuid(), characteristic.getUuid() );
97 | }
98 |
99 | private CharacteristicInfo getCharacteristicInfo( UUID serviceUuid, UUID characteristicUuid ) {
100 | BaseProfile serviceProfile = Profiles.getService( serviceUuid );
101 | if( serviceProfile == null ) {
102 | Log.e( CLASS, "getCharacteristicInfo: service not found. serviceUuid=" + serviceUuid );
103 | return null;
104 | }
105 |
106 | return new CharacteristicInfo( serviceProfile.getClass().getSimpleName(), serviceProfile.getUuidName( characteristicUuid ) );
107 | }
108 |
109 | private BluetoothGattCharacteristic readGatt( UUID serviceUuid, UUID characteristicUuid ) {
110 | Log.d( CLASS, "readGatt: " + getCharacteristicInfo( serviceUuid, characteristicUuid ) );
111 |
112 | BluetoothGattCharacteristic characteristic = mBtBridge.getCharacteristic( serviceUuid, characteristicUuid );
113 | if( characteristic == null ) {
114 | Log.e( CLASS, "readGatt: characteristic not found" );
115 | return null;
116 | }
117 | return characteristic;
118 | }
119 |
120 | private void updateNotification( BtAction action, boolean enable ) {
121 | UUID serviceUuid = action.getServiceUUID();
122 | UUID characteristicUuid = action.getCharacteristicUUID();
123 | UUID descriptorUuid = action.getDescriptorUUID();
124 | Log.d( CLASS, "updateNotification: enable=" + enable + " " + getCharacteristicInfo( serviceUuid, characteristicUuid ) );
125 |
126 | BluetoothGattCharacteristic characteristic = mBtBridge.getCharacteristic( serviceUuid, characteristicUuid );
127 | if( characteristic == null ) {
128 | Log.e( CLASS, "updateNotification: characteristic not found" );
129 | return;
130 | }
131 |
132 | BluetoothGattDescriptor descriptor = characteristic.getDescriptor( descriptorUuid );
133 | if( descriptor == null ) {
134 | Log.e( CLASS, "updateNotification: descriptor not found" );
135 | return;
136 | }
137 |
138 | mBtBridge.setCharacteristicNotification( characteristic, enable );
139 | if( enable ) {
140 | descriptor.setValue( BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE );
141 | } else {
142 | descriptor.setValue( BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE );
143 | }
144 | Log.d( CLASS, "updateNotification: " + getDescriptorInfo( descriptor ) );
145 |
146 | if( !mBtBridge.writeDescriptor( descriptor ) ) {
147 | Log.e( CLASS, "updateNotification: success = false " + getDescriptorInfo( descriptor ) );
148 | }
149 | }
150 |
151 | private BluetoothGattCharacteristic setValue( UUID serviceUuid, UUID characteristicUuid, int value, int format, int offset ) {
152 | BluetoothGattCharacteristic characteristic = mBtBridge.getCharacteristic( serviceUuid, characteristicUuid );
153 | if( characteristic == null ) {
154 | Log.e( CLASS, "setValue: characteristic not found" );
155 | return null;
156 | }
157 |
158 | if( !characteristic.setValue( value, format, offset ) ) {
159 | Log.e( CLASS, "setValue: error setting value" );
160 | return null;
161 | }
162 |
163 | return characteristic;
164 | }
165 |
166 | private Queue mRequestQueue = new LinkedBlockingQueue<>();
167 |
168 | public void addRequest( BtAction.Action action ) {
169 | mRequestQueue.add( new BtAction( action ) );
170 | processQueue();
171 | }
172 |
173 | public void addRequest( BtAction.Action action, int parameter ) {
174 | mRequestQueue.add( new BtAction( action ).setParameter( parameter ) );
175 | processQueue();
176 | }
177 |
178 | public void syncDeviceTime() {
179 | long now = Calendar.getInstance().getTimeInMillis();
180 | setDeviceTime( AHServiceProfile.convertTimestampToBandSeconds( now ) );
181 | }
182 |
183 | /**
184 | * Set the device time.
185 | * @param bandTimestamp Number of seconds since 2013
186 | */
187 | public void setDeviceTime( int bandTimestamp ) {
188 | Date date = AHServiceProfile.convertBandSecondsToDate( bandTimestamp );
189 | Log.d( CLASS, "sendCurrentTime: called. bandTimestamp=" + bandTimestamp + " date=" + date );
190 | mRequestQueue.add( new BtAction( BtAction.Action.SET_CURRENT_TIME ).setParameter( bandTimestamp ) );
191 | }
192 |
193 | private void processQueue() {
194 | Log.d( CLASS, "processQueue: called." );
195 | BtAction action = mRequestQueue.poll();
196 | if( action == null ) {
197 | Log.d( CLASS, "processQueue: the queue is empty" );
198 | return;
199 | }
200 |
201 | executeAction( action );
202 | }
203 |
204 | private void executeAction( BtAction action ) {
205 | BtAction.Type type = action.getType();
206 | Log.i( CLASS, "executeAction: action=" + action.mAction.name() + " type=" + type.name() );
207 |
208 | if( type.equals( BtAction.Type.READ_CHAR ) ) {
209 | mBtBridge.readCharacteristic( readGatt( action.getServiceUUID(), action.getCharacteristicUUID() ) );
210 | } else if( type.equals( BtAction.Type.WRITE_CHAR ) ) {
211 | mBtBridge.writeCharacteristic(
212 | setValue(
213 | action.getServiceUUID(),
214 | action.getCharacteristicUUID(),
215 | action.mParam,
216 | action.getFormat(),
217 | 0
218 | )
219 | );
220 | } else if( type.equals( BtAction.Type.ENABLE_NOTIFICATION ) ) {
221 | updateNotification( action, true );
222 | } else if( type.equals( BtAction.Type.DISABLE_NOTIFICATION ) ) {
223 | updateNotification( action, false );
224 | } else {
225 | Log.e( CLASS, "executeAction: don't know how to handle: action=" + action.mAction.name() );
226 | }
227 | }
228 |
229 | public void onConnectionStateChange( BtBridge.Status newStatus ) {
230 | if( newStatus.equals( BtBridge.Status.CONNECTED ) ) {
231 | mBtBridge.discoverServices();
232 | }
233 |
234 | for( BtBandListener listener : mListeners ) {
235 | listener.onConnectionStateChange( newStatus );
236 | }
237 | }
238 |
239 | public void onServicesDiscovered( List services ) {
240 | Log.d( CLASS, "onServicesDiscovered: services=" + services.size() );
241 |
242 | for( BluetoothGattService service : services ) {
243 | BaseProfile serviceProfile = Profiles.getService( service.getUuid() );
244 | if( serviceProfile == null ) {
245 | Log.w( CLASS, "- service=unknown uuid=" + service.getUuid() );
246 | continue;
247 | }
248 | Log.d( CLASS, "-> service name=" + serviceProfile.getClass().getSimpleName() + " (" + service.getUuid() + ")" );
249 | List chars = service.getCharacteristics();
250 | for( BluetoothGattCharacteristic c : chars ) {
251 | Log.d( CLASS, "--> characteristic name=" + serviceProfile.getUuidName( c.getUuid() ) + " (" + c.getUuid() + ")" );
252 | List descriptors = c.getDescriptors();
253 | for( BluetoothGattDescriptor d : descriptors ) {
254 | Log.d( CLASS, "---> descriptor name=" + BleConstants.getUuidName( d.getUuid() ) + " (" + d.getUuid() + ")" );
255 | }
256 | }
257 | }
258 |
259 | for( BtBandListener listener : mListeners ) {
260 | listener.onServicesDiscovered( );
261 | }
262 | }
263 |
264 | private void handleDeviceInfoFirmwareRevision( BluetoothGattCharacteristic characteristic ) {
265 | String revision = characteristic.getStringValue( 0 );
266 | for( BtBandListener listener : mListeners ) {
267 | listener.onFirmwareRevision( revision );
268 | }
269 | }
270 |
271 | private void handleDeviceInfoSoftwareRevision( BluetoothGattCharacteristic characteristic ) {
272 | String revision = characteristic.getStringValue( 0 );
273 | for( BtBandListener listener : mListeners ) {
274 | listener.onSoftwareRevision( revision );
275 | }
276 | }
277 |
278 | private void handleDeviceInfoHardwareRevision( BluetoothGattCharacteristic characteristic ) {
279 | String revision = characteristic.getStringValue( 0 );
280 | for( BtBandListener listener : mListeners ) {
281 | listener.onHardwareRevision( revision );
282 | }
283 | }
284 |
285 | private void handleDeviceInfoManufacturerName( BluetoothGattCharacteristic characteristic ) {
286 | String name = characteristic.getStringValue( 0 );
287 | for( BtBandListener listener : mListeners ) {
288 | listener.onManufacturerName( name );
289 | }
290 | }
291 |
292 | private void handleDeviceInfoCallback( BluetoothGattCharacteristic characteristic ) {
293 | UUID uuid = characteristic.getUuid();
294 |
295 | if( uuid.equals( DeviceInformationProfile.FIRMWARE_REVISION_UUID ) ) {
296 | handleDeviceInfoFirmwareRevision( characteristic );
297 | } else if( uuid.equals( DeviceInformationProfile.SOFTWARE_REVISION_UUID) ) {
298 | handleDeviceInfoSoftwareRevision( characteristic );
299 | } else if( uuid.equals( DeviceInformationProfile.HARDWARE_REVISION_UUID) ) {
300 | handleDeviceInfoHardwareRevision( characteristic );
301 | } else if( uuid.equals( DeviceInformationProfile.MANUFACTURER_NAME_UUID) ) {
302 | handleDeviceInfoManufacturerName( characteristic );
303 | } else {
304 | Log.e( CLASS, "handleDeviceInfoCallback: unknown response" );
305 | }
306 | }
307 |
308 | private void handleAASDeviceVersion( BluetoothGattCharacteristic characteristic ) {
309 | int version = AADeviceServiceProfile.readDeviceAASVersion( characteristic );
310 | for( BtBandListener listener : mListeners ) {
311 | listener.onAASDeviceVersion( version );
312 | }
313 | }
314 |
315 | private void handleAASDeviceSmartLink( BluetoothGattCharacteristic characteristic ) {
316 | int smartLink = AADeviceServiceProfile.readDeviceSmartLinkService( characteristic );
317 | for( BtBandListener listener : mListeners ) {
318 | listener.onAASDeviceSmartLink( smartLink );
319 | }
320 | }
321 |
322 | private void handleAASDeviceProductId( BluetoothGattCharacteristic characteristic ) {
323 | String productId = characteristic.getStringValue( 0 );
324 | for( BtBandListener listener : mListeners ) {
325 | listener.onAASDeviceProductId( productId );
326 | }
327 | }
328 |
329 | private void handleAASDeviceData( BluetoothGattCharacteristic characteristic ) {
330 | String data = characteristic.getStringValue( 0 );
331 | for( BtBandListener listener : mListeners ) {
332 | listener.onAASDeviceData( data );
333 | }
334 | }
335 |
336 | private void handleAADeviceServiceCallback( BluetoothGattCharacteristic characteristic ) {
337 | UUID uuid = characteristic.getUuid();
338 |
339 | if( uuid.equals( AADeviceServiceProfile.VERSION_UUID ) ) {
340 | handleAASDeviceVersion( characteristic );
341 | } else if( uuid.equals( AADeviceServiceProfile.SMART_LINK_SERVICE_UUID ) ) {
342 | handleAASDeviceSmartLink( characteristic );
343 | } else if( uuid.equals( AADeviceServiceProfile.PRODUCT_ID_UUID ) ) {
344 | handleAASDeviceProductId( characteristic );
345 | } else if( uuid.equals( AADeviceServiceProfile.DATA_UUID ) ) {
346 | handleAASDeviceData( characteristic );
347 | } else {
348 | Log.e( CLASS, "handleAADeviceServiceCallback: unknown response" );
349 | }
350 | }
351 |
352 | private void handleGADeviceName( BluetoothGattCharacteristic characteristic ) {
353 | String name = characteristic.getStringValue( 0 );
354 | for( BtBandListener listener : mListeners ) {
355 | listener.onGADeviceName( name );
356 | }
357 | }
358 |
359 | private void handleGenericAccessCallback( BluetoothGattCharacteristic characteristic ) {
360 | UUID uuid = characteristic.getUuid();
361 |
362 | if( uuid.equals( GenericAccessProfile.DEVICE_NAME_UUID ) ) {
363 | handleGADeviceName( characteristic );
364 | } else {
365 | Log.e( CLASS, "handleGenericAccessCallback: unknown response" );
366 | }
367 | }
368 |
369 | private void handleBatteryReadLevel( BluetoothGattCharacteristic characteristic ) {
370 | int level = BatteryProfile.readBatteryLevel( characteristic );
371 | for( BtBandListener listener : mListeners ) {
372 | listener.onBatteryLevel( level );
373 | }
374 | }
375 |
376 | private void handleBatteryCallback( BluetoothGattCharacteristic characteristic ) {
377 | UUID uuid = characteristic.getUuid();
378 | if( uuid .equals( BatteryProfile.BATTERY_LEVEL_UUID ) ) {
379 | handleBatteryReadLevel( characteristic );
380 | }
381 | }
382 |
383 | private void handleAHServiceReadMode( BluetoothGattCharacteristic characteristic ) {
384 | BandMode.AccessoryMode mode = AHServiceProfile.readMode( characteristic );
385 | for( BtBandListener listener : mListeners ) {
386 | listener.onAHServiceReadMode( mode );
387 | }
388 | }
389 |
390 | private void handleAHServiceReadProtocolVersion( BluetoothGattCharacteristic characteristic ) {
391 | int version = AHServiceProfile.readProtocolVersion( characteristic );
392 | for( BtBandListener listener : mListeners ) {
393 | listener.onAHServiceReadProtocolVersion( version );
394 | }
395 | }
396 |
397 | private void handleAHServiceReadData( BluetoothGattCharacteristic characteristic ) {
398 | for( BtBandListener listener : mListeners ) {
399 | listener.onAHServiceReadData( );
400 | }
401 | }
402 |
403 | private void handleAHServiceReadCurrentTime( BluetoothGattCharacteristic characteristic ) {
404 | int bandSeconds = AHServiceProfile.readCurrentTime( characteristic );
405 | Date deviceDate = AHServiceProfile.convertBandSecondsToDate( bandSeconds );
406 | long deltaMs = deviceDate.getTime() - System.currentTimeMillis();
407 | for( BtBandListener listener : mListeners ) {
408 | listener.onAHServiceReadCurrentTime( bandSeconds, deviceDate, deltaMs );
409 | }
410 | }
411 |
412 | private void handleAHServiceReadUptime( BluetoothGattCharacteristic characteristic ) {
413 | int uptime = AHServiceProfile.readUptime( characteristic );
414 | Date started = new Date( System.currentTimeMillis() - uptime * 1000 );
415 | for( BtBandListener listener : mListeners ) {
416 | listener.onAHServiceReadUptime( uptime, started );
417 | }
418 | }
419 |
420 | private void handleAHServiceReadEvent( BluetoothGattCharacteristic characteristic ) {
421 | BtBandEvent btBandEvent = AHServiceProfile.readEvent( characteristic );
422 | for( BtBandListener listener : mListeners ) {
423 | listener.onAHServiceReadEvent( btBandEvent );
424 | }
425 | }
426 |
427 | private void handleAHServiceReadAccData( BluetoothGattCharacteristic characteristic ) {
428 | int[] data = AHServiceProfile.readAccData( characteristic );
429 | for( BtBandListener listener : mListeners ) {
430 | listener.onAHServiceReadAccData( data );
431 | }
432 | }
433 |
434 | private void handleAHServiceCallback( BluetoothGattCharacteristic characteristic ) {
435 | UUID uuid = characteristic.getUuid();
436 |
437 | if( uuid.equals( AHServiceProfile.MODE_UUID ) ) {
438 | handleAHServiceReadMode( characteristic );
439 | } else if( uuid.equals( AHServiceProfile.PROTOCOL_VERSION_UUID ) ) {
440 | handleAHServiceReadProtocolVersion( characteristic );
441 | } else if( uuid.equals( AHServiceProfile.DATA_UUID ) ) {
442 | handleAHServiceReadData( characteristic );
443 | } else if( uuid.equals( AHServiceProfile.CURRENT_TIME_UUID ) ) {
444 | handleAHServiceReadCurrentTime( characteristic );
445 | } else if( uuid.equals( AHServiceProfile.DEBUG_UUID ) ) {
446 | handleAHServiceReadUptime( characteristic );
447 | } else if( uuid.equals( AHServiceProfile.EVENT_UUID ) ) {
448 | handleAHServiceReadEvent( characteristic );
449 | } else if( uuid.equals( AHServiceProfile.ACCEL_DATA_UUID ) ) {
450 | handleAHServiceReadAccData( characteristic );
451 | } else {
452 | Log.e( CLASS, "handleOnCharacteristicRead: unknown response" );
453 | }
454 | }
455 |
456 | public void onCharacteristicRead( BluetoothGattCharacteristic characteristic ) {
457 | BluetoothGattService service = characteristic.getService();
458 | BaseProfile serviceProfile = Profiles.getService( service.getUuid() );
459 |
460 | Log.d( CLASS, "onCharacteristicRead: " + getCharacteristicInfo( characteristic ) );
461 | if( serviceProfile.getClass().equals( BatteryProfile.class ) ) {
462 | handleBatteryCallback( characteristic );
463 | } else if( serviceProfile.getClass().equals( AHServiceProfile.class ) ) {
464 | handleAHServiceCallback( characteristic );
465 | } else if( serviceProfile.getClass().equals( DeviceInformationProfile.class ) ) {
466 | handleDeviceInfoCallback( characteristic );
467 | } else if( serviceProfile.getClass().equals( AADeviceServiceProfile.class ) ) {
468 | handleAADeviceServiceCallback( characteristic );
469 | } else if( serviceProfile.getClass().equals( GenericAccessProfile.class ) ) {
470 | handleGenericAccessCallback( characteristic );
471 | } else {
472 | Log.w( CLASS, "onCharacteristicRead: unhandled event. class=" + serviceProfile.getClass() );
473 | }
474 | processQueue();
475 | }
476 |
477 | public void onCharacteristicChanged( BluetoothGattCharacteristic characteristic ) {
478 | BluetoothGattService service = characteristic.getService();
479 | BaseProfile serviceProfile = Profiles.getService( service.getUuid() );
480 |
481 | Log.d( CLASS, "onCharacteristicChanged: " + getCharacteristicInfo( characteristic ) );
482 | if( serviceProfile.getClass().equals( BatteryProfile.class ) ) {
483 | handleBatteryCallback( characteristic );
484 | } else if( serviceProfile.getClass().equals( AHServiceProfile.class ) ) {
485 | handleAHServiceCallback( characteristic );
486 | } else if( serviceProfile.getClass().equals( DeviceInformationProfile.class ) ) {
487 | handleDeviceInfoCallback( characteristic );
488 | } else if( serviceProfile.getClass().equals( AADeviceServiceProfile.class ) ) {
489 | handleAADeviceServiceCallback( characteristic );
490 | } else if( serviceProfile.getClass().equals( GenericAccessProfile.class ) ) {
491 | handleGenericAccessCallback( characteristic );
492 | } else {
493 | Log.w( CLASS, "onCharacteristicChanged: unhandled event. class=" + serviceProfile.getClass() );
494 | }
495 | processQueue();
496 | }
497 |
498 | public void onCharacteristicWrite( BluetoothGattCharacteristic characteristic ) {
499 | Log.d( CLASS, "onCharacteristicWrite: " + getCharacteristicInfo( characteristic ) );
500 | processQueue();
501 | }
502 |
503 | public void onDescriptorRead( BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor ) {
504 | Log.d( CLASS, "onDescriptorRead: " + getDescriptorInfo( descriptor ) );
505 | processQueue();
506 | }
507 |
508 | // TODO: Add callbacks
509 | // TODO: track in a better way if a notification is enabled
510 | public void onDescriptorWrite( BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor descriptor ) {
511 | BluetoothGattService service = characteristic.getService();
512 | BaseProfile serviceProfile = Profiles.getService( service.getUuid() );
513 |
514 | Log.d( CLASS, "onDescriptorWrite: " + getDescriptorInfo( descriptor ) );
515 |
516 | UUID uuid = characteristic.getUuid();
517 |
518 | if( serviceProfile.getClass().equals( AHServiceProfile.class ) ) {
519 | if( uuid.equals( AHServiceProfile.DATA_UUID ) ) {
520 | mDataNotificationsEnabled = !mDataNotificationsEnabled;
521 | } else if( uuid.equals( AHServiceProfile.DEBUG_UUID ) ) {
522 | mDebugNotificationsEnabled = !mDebugNotificationsEnabled;
523 | } else if( uuid.equals( AHServiceProfile.EVENT_UUID ) ) {
524 | mEventNotificationsEnabled = !mEventNotificationsEnabled;
525 | } else if( uuid.equals( AHServiceProfile.ACCEL_DATA_UUID ) ) {
526 | mAccNotificationsEnabled = !mAccNotificationsEnabled ;
527 | } else {
528 | Log.w( CLASS, "onCharacteristicChanged: unhandled event. uuid=" + uuid
529 | + " class=" + serviceProfile.getClass() );
530 | }
531 | } else {
532 | Log.w( CLASS, "onCharacteristicChanged: unhandled event. class=" + serviceProfile.getClass() );
533 | }
534 |
535 | processQueue();
536 | }
537 |
538 | public boolean connect() {
539 | return mBtBridge.connect();
540 | }
541 |
542 | public boolean disconnect() {
543 | return mBtBridge.disconnect();
544 | }
545 |
546 | }
547 |
--------------------------------------------------------------------------------