From 800ad63ca88db8511a063c00fb11aa605df2ff2d Mon Sep 17 00:00:00 2001 From: Nikola Antic Date: Fri, 22 Jul 2016 14:30:38 +0200 Subject: [PATCH] Android --- android/.gitignore | 9 + android/LICENCE | 674 ++++++++++++++++++ android/app/.gitignore | 1 + android/app/build.gradle | 67 ++ android/app/proguard-rules.pro | 17 + android/app/src/main/AndroidManifest.xml | 100 +++ .../HEXIWEAR_KW40_factory_settings.img | Bin 0 -> 162926 bytes .../HEXIWEAR_MK64_factory_settings.img | Bin 0 -> 948618 bytes .../hexiwear/HexiwearApplication.java | 59 ++ .../activity/FirmwareSelectActivity.java | 201 ++++++ .../hexiwear/activity/LoginActivity.java | 197 +++++ .../hexiwear/activity/MainActivity.java | 237 ++++++ .../activity/PasswordChangeActivity.java | 107 +++ .../hexiwear/activity/ReadingsActivity.java | 330 +++++++++ .../activity/ResetPasswordActivity.java | 68 ++ .../hexiwear/activity/SettingsActivity.java | 53 ++ .../hexiwear/activity/SignUpActivity.java | 147 ++++ .../hexiwear/adapter/DeviceListAdapter.java | 149 ++++ .../hexiwear/adapter/FirmwareListAdapter.java | 121 ++++ .../hexiwear/adapter/HexiwearListAdapter.java | 132 ++++ .../fragment/HexiwearSettingsFragment.java | 156 ++++ .../model/BluetoothDeviceWrapper.java | 81 +++ .../hexiwear/model/Characteristic.java | 109 +++ .../hexiwear/model/HexiwearDevice.java | 75 ++ .../hexiwear/model/ManufacturerInfo.java | 39 + .../com/wolkabout/hexiwear/model/Mode.java | 98 +++ .../hexiwear/model/otap/Command.java | 53 ++ .../wolkabout/hexiwear/model/otap/Image.java | 93 +++ .../hexiwear/model/otap/ImageBlock.java | 70 ++ .../hexiwear/model/otap/ImageHeader.java | 111 +++ .../hexiwear/model/otap/ImageVersion.java | 76 ++ .../otap/response/ErrorNotification.java | 101 +++ .../otap/response/ImageBlockRequest.java | 81 +++ .../otap/response/ImageTransferComplete.java | 53 ++ .../otap/response/NewImageInfoRequest.java | 54 ++ .../hexiwear/service/BluetoothService.java | 555 ++++++++++++++ .../service/DeviceDiscoveryService.java | 171 +++++ .../service/DeviceRegistrationService.java | 169 +++++ .../service/FirmwareUpdateService.java | 298 ++++++++ .../hexiwear/service/NotificationService.java | 184 +++++ .../hexiwear/util/ByteInputStream.java | 85 +++ .../wolkabout/hexiwear/util/ByteUtils.java | 99 +++ .../hexiwear/util/DataConverter.java | 140 ++++ .../com/wolkabout/hexiwear/util/Dialog.java | 69 ++ .../hexiwear/util/HexiwearDevices.java | 191 +++++ .../hexiwear/view/DeviceActivation.java | 94 +++ .../com/wolkabout/hexiwear/view/Input.java | 160 +++++ .../com/wolkabout/hexiwear/view/Reading.java | 63 ++ .../hexiwear/view/SingleReading.java | 50 ++ .../hexiwear/view/TripleReading.java | 63 ++ .../ic_arrow_forward_black_24dp.png | Bin 0 -> 147 bytes .../res/drawable-hdpi/ic_clear_white_24dp.png | Bin 0 -> 221 bytes .../drawable-hdpi/ic_settings_white_24dp.png | Bin 0 -> 460 bytes .../ic_arrow_forward_black_24dp.png | Bin 0 -> 114 bytes .../res/drawable-mdpi/ic_clear_white_24dp.png | Bin 0 -> 175 bytes .../drawable-mdpi/ic_settings_white_24dp.png | Bin 0 -> 326 bytes .../res/drawable-xhdpi/ic_accelerometer.png | Bin 0 -> 4347 bytes .../ic_arrow_forward_black_24dp.png | Bin 0 -> 150 bytes .../main/res/drawable-xhdpi/ic_battery.png | Bin 0 -> 5574 bytes .../ic_bluetooth_connected_white_48dp.png | Bin 0 -> 652 bytes .../ic_bluetooth_searching_white_48dp.png | Bin 0 -> 945 bytes .../main/res/drawable-xhdpi/ic_calories.png | Bin 0 -> 3219 bytes .../drawable-xhdpi/ic_clear_white_24dp.png | Bin 0 -> 257 bytes .../ic_cloud_off_black_24dp.png | Bin 0 -> 582 bytes .../ic_cloud_off_white_48dp.png | Bin 0 -> 1126 bytes .../ic_cloud_queue_white_48dp.png | Bin 0 -> 1035 bytes .../main/res/drawable-xhdpi/ic_gyroscope.png | Bin 0 -> 8495 bytes .../main/res/drawable-xhdpi/ic_heartbeat.png | Bin 0 -> 7612 bytes .../main/res/drawable-xhdpi/ic_humidity.png | Bin 0 -> 9495 bytes .../src/main/res/drawable-xhdpi/ic_light.png | Bin 0 -> 8383 bytes .../src/main/res/drawable-xhdpi/ic_magnet.png | Bin 0 -> 4843 bytes .../main/res/drawable-xhdpi/ic_pressure.png | Bin 0 -> 10395 bytes .../drawable-xhdpi/ic_settings_white_24dp.png | Bin 0 -> 562 bytes .../drawable-xhdpi/ic_signal_strength_1.png | Bin 0 -> 1122 bytes .../drawable-xhdpi/ic_signal_strength_2.png | Bin 0 -> 1207 bytes .../drawable-xhdpi/ic_signal_strength_3.png | Bin 0 -> 1260 bytes .../drawable-xhdpi/ic_signal_strength_4.png | Bin 0 -> 1321 bytes .../drawable-xhdpi/ic_signal_strength_5.png | Bin 0 -> 1408 bytes .../src/main/res/drawable-xhdpi/ic_steps.png | Bin 0 -> 8496 bytes .../res/drawable-xhdpi/ic_temperature.png | Bin 0 -> 4647 bytes .../app/src/main/res/drawable-xhdpi/logo.png | Bin 0 -> 2912 bytes .../ic_arrow_forward_black_24dp.png | Bin 0 -> 186 bytes .../drawable-xxhdpi/ic_clear_white_24dp.png | Bin 0 -> 347 bytes .../ic_settings_white_24dp.png | Bin 0 -> 843 bytes .../ic_arrow_forward_black_24dp.png | Bin 0 -> 222 bytes .../drawable-xxxhdpi/ic_clear_white_24dp.png | Bin 0 -> 436 bytes .../ic_settings_white_24dp.png | Bin 0 -> 1074 bytes .../app/src/main/res/drawable/button_text.xml | 5 + .../res/layout/activity_firmware_select.xml | 34 + .../src/main/res/layout/activity_login.xml | 149 ++++ .../app/src/main/res/layout/activity_main.xml | 53 ++ .../res/layout/activity_password_change.xml | 73 ++ .../src/main/res/layout/activity_readings.xml | 143 ++++ .../res/layout/activity_reset_password.xml | 41 ++ .../src/main/res/layout/activity_settings.xml | 32 + .../src/main/res/layout/activity_sign_up.xml | 121 ++++ .../app/src/main/res/layout/item_device.xml | 63 ++ .../app/src/main/res/layout/item_firmware.xml | 43 ++ .../app/src/main/res/layout/item_hexiwear.xml | 20 + .../app/src/main/res/layout/view_input.xml | 14 + .../main/res/layout/view_reading_single.xml | 36 + .../main/res/layout/view_reading_tripple.xml | 56 ++ .../main/res/layout/view_register_device.xml | 29 + android/app/src/main/res/menu/menu_main.xml | 17 + .../app/src/main/res/menu/menu_readings.xml | 24 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 4147 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2186 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 5433 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 8307 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9704 bytes .../app/src/main/res/values-v21/styles.xml | 9 + .../app/src/main/res/values-w820dp/dimens.xml | 6 + android/app/src/main/res/values/array.xml | 15 + android/app/src/main/res/values/attrs.xml | 36 + android/app/src/main/res/values/colors.xml | 31 + android/app/src/main/res/values/dimens.xml | 7 + .../app/src/main/res/values/dslv_attrs.xml | 30 + android/app/src/main/res/values/strings.xml | 126 ++++ android/app/src/main/res/values/styles.xml | 40 ++ .../main/res/xml/pref_hexiwear_settings.xml | 104 +++ android/build.gradle | 23 + android/gradle.properties | 18 + android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 52266 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + android/gradlew | 164 +++++ android/gradlew.bat | 90 +++ android/settings.gradle | 1 + 127 files changed, 7969 insertions(+) create mode 100644 android/.gitignore create mode 100644 android/LICENCE create mode 100644 android/app/.gitignore create mode 100644 android/app/build.gradle create mode 100644 android/app/proguard-rules.pro create mode 100644 android/app/src/main/AndroidManifest.xml create mode 100644 android/app/src/main/assets/factory_settings/HEXIWEAR_KW40_factory_settings.img create mode 100644 android/app/src/main/assets/factory_settings/HEXIWEAR_MK64_factory_settings.img create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/HexiwearApplication.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/activity/FirmwareSelectActivity.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/activity/LoginActivity.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/activity/MainActivity.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/activity/PasswordChangeActivity.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/activity/ReadingsActivity.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/activity/ResetPasswordActivity.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/activity/SettingsActivity.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/activity/SignUpActivity.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/adapter/DeviceListAdapter.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/adapter/FirmwareListAdapter.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/adapter/HexiwearListAdapter.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/fragment/HexiwearSettingsFragment.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/BluetoothDeviceWrapper.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/Characteristic.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/HexiwearDevice.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/ManufacturerInfo.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/Mode.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/Command.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/Image.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageBlock.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageHeader.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageVersion.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ErrorNotification.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ImageBlockRequest.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ImageTransferComplete.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/NewImageInfoRequest.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/service/BluetoothService.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/service/DeviceDiscoveryService.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/service/DeviceRegistrationService.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/service/FirmwareUpdateService.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/service/NotificationService.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/util/ByteInputStream.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/util/ByteUtils.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/util/DataConverter.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/util/Dialog.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/util/HexiwearDevices.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/view/DeviceActivation.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/view/Input.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/view/Reading.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/view/SingleReading.java create mode 100644 android/app/src/main/java/com/wolkabout/hexiwear/view/TripleReading.java create mode 100644 android/app/src/main/res/drawable-hdpi/ic_arrow_forward_black_24dp.png create mode 100644 android/app/src/main/res/drawable-hdpi/ic_clear_white_24dp.png create mode 100644 android/app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_arrow_forward_black_24dp.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_clear_white_24dp.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_accelerometer.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_arrow_forward_black_24dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_battery.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_bluetooth_connected_white_48dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_bluetooth_searching_white_48dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_calories.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_clear_white_24dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_cloud_off_black_24dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_cloud_off_white_48dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_cloud_queue_white_48dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_gyroscope.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_heartbeat.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_humidity.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_light.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_magnet.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_pressure.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_signal_strength_1.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_signal_strength_2.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_signal_strength_3.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_signal_strength_4.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_signal_strength_5.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_steps.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_temperature.png create mode 100644 android/app/src/main/res/drawable-xhdpi/logo.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_arrow_forward_black_24dp.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_clear_white_24dp.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_arrow_forward_black_24dp.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_clear_white_24dp.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png create mode 100644 android/app/src/main/res/drawable/button_text.xml create mode 100644 android/app/src/main/res/layout/activity_firmware_select.xml create mode 100644 android/app/src/main/res/layout/activity_login.xml create mode 100644 android/app/src/main/res/layout/activity_main.xml create mode 100644 android/app/src/main/res/layout/activity_password_change.xml create mode 100644 android/app/src/main/res/layout/activity_readings.xml create mode 100644 android/app/src/main/res/layout/activity_reset_password.xml create mode 100644 android/app/src/main/res/layout/activity_settings.xml create mode 100644 android/app/src/main/res/layout/activity_sign_up.xml create mode 100644 android/app/src/main/res/layout/item_device.xml create mode 100644 android/app/src/main/res/layout/item_firmware.xml create mode 100644 android/app/src/main/res/layout/item_hexiwear.xml create mode 100644 android/app/src/main/res/layout/view_input.xml create mode 100644 android/app/src/main/res/layout/view_reading_single.xml create mode 100644 android/app/src/main/res/layout/view_reading_tripple.xml create mode 100644 android/app/src/main/res/layout/view_register_device.xml create mode 100644 android/app/src/main/res/menu/menu_main.xml create mode 100644 android/app/src/main/res/menu/menu_readings.xml create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/values-v21/styles.xml create mode 100644 android/app/src/main/res/values-w820dp/dimens.xml create mode 100644 android/app/src/main/res/values/array.xml create mode 100644 android/app/src/main/res/values/attrs.xml create mode 100644 android/app/src/main/res/values/colors.xml create mode 100644 android/app/src/main/res/values/dimens.xml create mode 100644 android/app/src/main/res/values/dslv_attrs.xml create mode 100644 android/app/src/main/res/values/strings.xml create mode 100644 android/app/src/main/res/values/styles.xml create mode 100644 android/app/src/main/res/xml/pref_hexiwear_settings.xml create mode 100644 android/build.gradle create mode 100644 android/gradle.properties create mode 100644 android/gradle/wrapper/gradle-wrapper.jar create mode 100644 android/gradle/wrapper/gradle-wrapper.properties create mode 100644 android/gradlew create mode 100644 android/gradlew.bat create mode 100644 android/settings.gradle diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..2ac5e53 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,9 @@ +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.idea +*.iml diff --git a/android/LICENCE b/android/LICENCE new file mode 100644 index 0000000..2d2584b --- /dev/null +++ b/android/LICENCE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/android/app/.gitignore b/android/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/android/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..23585cd --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' +apply plugin: 'android-apt' + +android { + compileSdkVersion 23 + buildToolsVersion '23.0.3' + + defaultConfig { + applicationId "com.wolkabout.hexiwear" + minSdkVersion 19 + targetSdkVersion 22 + versionCode 23 + versionName "1.23" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + packagingOptions { + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/NOTICE' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/notice.txt' + exclude 'META-INF/LICENSE' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/license.txt' + exclude 'META-INF/ASL2.0' + exclude 'LICENSE.txt' + exclude 'META-INF/services/org.androidannotations.plugin.AndroidAnnotationsPlugin' + exclude 'asm-license.txt' + } +} + +def SupportVersion = '23.4.0' +def AAVersion = '4.0.0' +def ParcelerVersion = '1.0.4' + +dependencies { + + // Android support libraries + compile "com.android.support:appcompat-v7:$SupportVersion" + compile "com.android.support:design:$SupportVersion" + compile "com.android.support:cardview-v7:$SupportVersion" + + // Android annotations + compile "org.androidannotations:androidannotations:$AAVersion" + compile "org.androidannotations:rest-spring-api:$AAVersion" + compile "org.androidannotations:rest-spring:$AAVersion" + + // Parceler + compile "org.parceler:parceler-api:$ParcelerVersion" + apt "org.parceler:parceler:$ParcelerVersion" + + compile 'com.wolkabout:restandroid:1.0.6' + compile 'com.wolkabout:wolk:1.0' + + compile 'org.springframework.android:spring-android-rest-template:2.0.0.M3' + compile 'com.fasterxml.jackson.core:jackson-databind:2.7.5' +} + +apt { + arguments { + androidManifestFile variant.outputs[0].processResources.manifestFile + } +} diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 0000000..a4c0140 --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/nmaksimovic/android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a231456 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/assets/factory_settings/HEXIWEAR_KW40_factory_settings.img b/android/app/src/main/assets/factory_settings/HEXIWEAR_KW40_factory_settings.img new file mode 100644 index 0000000000000000000000000000000000000000..31d0611a191e422716b6b27ceea6cecb0e03a88e GIT binary patch literal 162926 zcmeFadw5jUxj+8yJ$o*hT$lhtf|IakATS9RC&(qJ)yWKo2?j*ORxRxrTJ;1fb_WzD zpk>0%NdOIM+u*IiYp}MZscEq_HQ0J8+RF?`tI(daIjw^Bw!zEHWHPhApLg#h&~Lxr z-|sxX|9;QYJkOrJ_PW07U2DDTy{(nXbCrc8TtP&-Ado;*Us_r!G~C!E2b->yuU}ce zTwZkhy06NO>sJ5!?Q+AKJ8wr;y6aw%U-(T=Ci%}+qI+!r-yW{!Uw{9?z`ro?|4$6) z7yacC?g&$}vY7hX!yS!|NdAoQ(wBZHG`D@^h*JeM(_-O}vN+ba1G&g^G!zetNzyLO zkV>-Huk=Y&OcUtd(NtS<4poy(v0l<Q~meH@ZJLL$cDZ z^?kMJ*+o<(Ous8^>C{s%>uUi6Y4$-q^|~&+KpsifQ@_;7CnWULcl6tqNFEt6KO2sD zM*o%^6L$u;922^}*ccC5j>qHyqE0~-x~S9AMbWz8Es0ygJA{2z zOh;0e#e-bHlY2I+4E^%$NZ@yWV3N?e^^D{d4|>C- zeSNs(rMjLf*DJ$27is;mKJs8FG%+po6V>%usfgD9uq<58IF`%sJ1)$>6M6Ka49$3i z0tnfXMd2|>afbC&Dle#dss{a?)4vG&heU(cqQ8>*F_HY2tgZv!vH(=jc%lJ3<2j5! z2l7yx6wr_!>(f)e&I|qSKE_&LrgV(tV58%v+uZ3hgK|KiPLkI R0`Z2US}1VH|i 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 w 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

GWlE6FeB>*%duQYFUDeeE6u^LvEB-pV^ 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Ξ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. + * + */ + +package com.wolkabout.hexiwear; + +import android.app.Application; +import android.content.Intent; + +import com.wolkabout.hexiwear.activity.LoginActivity_; +import com.wolkabout.wolkrestandroid.Credentials_; +import com.wolkabout.wolkrestandroid.DefaultErrorHandler; + +import org.androidannotations.annotations.AfterInject; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EApplication; +import org.androidannotations.annotations.sharedpreferences.Pref; + +@EApplication +public class HexiwearApplication extends Application{ + + @Pref + Credentials_ credentials; + + @Bean + DefaultErrorHandler defaultErrorHandler; + + @AfterInject + void setUpServices() { + defaultErrorHandler.setErrorHandler(new DefaultErrorHandler.ErrorHandler() { + @Override + public void onAuthenticationError() { + if (credentials.username().get().equals("Demo")) { + return; + } + + LoginActivity_.intent(HexiwearApplication.this).flags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK).start(); + } + }); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/activity/FirmwareSelectActivity.java b/android/app/src/main/java/com/wolkabout/hexiwear/activity/FirmwareSelectActivity.java new file mode 100644 index 0000000..188d0fa --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/activity/FirmwareSelectActivity.java @@ -0,0 +1,201 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.activity; + +import android.app.ProgressDialog; +import android.bluetooth.BluetoothDevice; +import android.content.ComponentName; +import android.content.DialogInterface; +import android.content.ServiceConnection; +import android.content.res.AssetManager; +import android.os.Environment; +import android.os.IBinder; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.View; +import android.widget.ListView; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.adapter.FirmwareListAdapter; +import com.wolkabout.hexiwear.model.otap.Image; +import com.wolkabout.hexiwear.service.FirmwareUpdateService; +import com.wolkabout.hexiwear.service.FirmwareUpdateService_; +import com.wolkabout.hexiwear.util.ByteUtils; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.Extra; +import org.androidannotations.annotations.ItemClick; +import org.androidannotations.annotations.Receiver; +import org.androidannotations.annotations.ViewById; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +@EActivity(R.layout.activity_firmware_select) +public class FirmwareSelectActivity extends AppCompatActivity implements ServiceConnection { + + private static final String TAG = FirmwareSelectActivity.class.getSimpleName(); + + private static final String UPDATE_INITIATED = "updateStarted"; + private static final String UPDATE_CANCELED = "updateCanceled"; + private static final String UPDATE_FINISHED = "updateFinished"; + private static final String UPDATE_PROGRESS = "updateProgress"; + private static final String UPDATE_ERROR = "updateError"; + + private static final String HEXIWEAR_PREFIX = "HEXIWEAR"; + private static final String IMAGE_EXTENSION = ".img"; + private static final int PREFIX_LENGTH = 14; + private static final String FACTORY_SETTINGS = "factory_settings"; + + + @ViewById + Toolbar toolbar; + + @ViewById + ListView firmwareList; + + @Bean + FirmwareListAdapter adapter; + + @Extra + BluetoothDevice device; + + private ProgressDialog progressDialog; + private FirmwareUpdateService firmwareUpdateService; + + @AfterViews + void init() { + setSupportActionBar(toolbar); + firmwareList.setAdapter(adapter); + addFactorySettingImages(); + discoverFirmwareImages(); + FirmwareUpdateService_.intent(this).start(); + bindService(FirmwareUpdateService_.intent(this).get(), this, 0); + } + + void addFactorySettingImages() { + try { + final AssetManager assetManager = getAssets(); + for (String factorySetting : assetManager.list(FACTORY_SETTINGS)) { + final InputStream inputStream = assetManager.open(FACTORY_SETTINGS + "/" + factorySetting); + final String imageName = factorySetting.substring(PREFIX_LENGTH).replace(IMAGE_EXTENSION, ""); + final Image image = new Image(imageName, ByteUtils.readBytes(inputStream)); + adapter.add(image); + } + } catch (IOException e) { + Log.e(TAG, "Couldn't open factory images.", e); + } + } + + void discoverFirmwareImages() { + final File downloadsDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + for (final File file : downloadsDirectory.listFiles()) { + if (file.getName().startsWith(HEXIWEAR_PREFIX)) { + final String imageName = file.getName().substring(PREFIX_LENGTH).replace(IMAGE_EXTENSION, ""); + final Image image = new Image(imageName, ByteUtils.readBytes(file)); + adapter.add(image); + } + } + } + + @ItemClick(R.id.firmwareList) + void updateFirmware(final Image image) { + progressDialog = new ProgressDialog(this); + progressDialog.setTitle(R.string.firmware_update_activity_title); + progressDialog.setMessage(getString(R.string.firmware_update_start)); + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.firmware_update_cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int which) { + firmwareUpdateService.cancelUpdate(); + } + }); + progressDialog.setButton(DialogInterface.BUTTON_NEUTRAL, getString(R.string.firmware_update_hide), new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int which) { + progressDialog.dismiss(); + finish(); + } + }); + progressDialog.show(); + + progressDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setVisibility(View.INVISIBLE); + firmwareUpdateService.updateFirmware(device, image); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unbindService(this); + if (progressDialog != null) { + progressDialog.dismiss(); + } + } + + @Override + public void onServiceConnected(final ComponentName name, final IBinder service) { + final FirmwareUpdateService.ServiceBinder binder = (FirmwareUpdateService.ServiceBinder) service; + firmwareUpdateService = binder.getService(); + } + + @Override + public void onServiceDisconnected(final ComponentName name) { + // Something terrible happened. + } + + @Receiver(actions = UPDATE_INITIATED, local = true) + void onUpdateInitiated() { + progressDialog.setMessage(getString(R.string.firmware_update_in_progress)); + progressDialog.setMax(100); + progressDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setVisibility(View.VISIBLE); + } + + @Receiver(actions = UPDATE_PROGRESS, local = true) + void onUpdateProgress(@Receiver.Extra final int progress) { + progressDialog.setProgress(progress); + } + + @Receiver(actions = UPDATE_CANCELED, local = true) + void onUpdateCanceled() { + progressDialog.hide(); + } + + @Receiver(actions = UPDATE_FINISHED, local = true) + void onUpdateFinished() { + progressDialog.setProgress(100); + progressDialog.setMessage(getString(R.string.firmware_update_complete)); + progressDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.INVISIBLE); + } + + @Receiver(actions = UPDATE_ERROR, local = true) + void onUpdateError() { + progressDialog.setMax(0); + progressDialog.setProgress(0); + progressDialog.setMessage(getString(R.string.firmware_update_error)); + progressDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.INVISIBLE); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/activity/LoginActivity.java b/android/app/src/main/java/com/wolkabout/hexiwear/activity/LoginActivity.java new file mode 100644 index 0000000..ee4d5f5 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/activity/LoginActivity.java @@ -0,0 +1,197 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.activity; + +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.util.Dialog; +import com.wolkabout.hexiwear.view.Input; +import com.wolkabout.wolkrestandroid.Credentials_; +import com.wolkabout.wolkrestandroid.dto.AuthenticationResponseDto; +import com.wolkabout.wolkrestandroid.dto.EmailVerificationRequest; +import com.wolkabout.wolkrestandroid.dto.SignInDto; +import com.wolkabout.wolkrestandroid.service.AuthenticationService; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.Background; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.Click; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.EditorAction; +import org.androidannotations.annotations.SystemService; +import org.androidannotations.annotations.UiThread; +import org.androidannotations.annotations.ViewById; +import org.androidannotations.annotations.sharedpreferences.Pref; +import org.androidannotations.rest.spring.annotations.RestService; + +@EActivity(R.layout.activity_login) +public class LoginActivity extends AppCompatActivity { + + public static final String TAG = LoginActivity.class.getSimpleName(); + + @ViewById + Input emailField; + + @ViewById + Input passwordField; + + @ViewById + View signInElements; + + @ViewById + TextView signingInLabel; + + @ViewById + View signingInElements; + + @ViewById + Button signInButton; + + @Pref + Credentials_ credentials; + + @SystemService + InputMethodManager inputMethodManager; + + @Bean + Dialog dialog; + + @RestService + AuthenticationService authenticationService; + + @Override + protected void onResume() { + super.onResume(); + String dataString = getIntent().getDataString(); + Log.i(TAG, "Data string: " + dataString); + if (dataString != null && dataString.contains("activationCode=")) { + Log.i(TAG, "Activate"); + verifyEmail(dataString.substring(dataString.indexOf('=') + 1)); + } + } + + @AfterViews + void startMainActivity() { + if (credentials.username().exists() && !credentials.username().get().equals("Demo")) { + MainActivity_.intent(this).start(); + finish(); + } + } + + @Click(R.id.signUp) + void openSignUpScreen() { + SignUpActivity_.intent(this).start(); + } + + @Click(R.id.signInButton) + @EditorAction(R.id.passwordField) + void attemptSignIn() { + if ("demo".equals(emailField.getValue()) && "demo".equals(passwordField.getValue())) { + credentials.username().put("Demo"); + MainActivity_.intent(LoginActivity.this).start(); + finish(); + return; + } + + if (!validateCredentials()) { + return; + } + + inputMethodManager.hideSoftInputFromWindow(passwordField.getWindowToken(), 0); + + signInElements.setVisibility(View.GONE); + signingInElements.setVisibility(View.VISIBLE); + + signIn(); + } + + @Background + void signIn() { + try { + final String emailAddress = emailField.getValue(); + final String password = passwordField.getValue(); + + final AuthenticationResponseDto response = authenticationService.signIn(new SignInDto(emailAddress, password)); + credentials.username().put(response.getEmail()); + credentials.accessToken().put(response.getAccessToken()); + credentials.refreshToken().put(response.getRefreshToken()); + credentials.accessTokenExpires().put(response.getAccessTokenExpires().getTime()); + credentials.refreshTokenExpires().put(response.getRefreshTokenExpires().getTime()); + MainActivity_.intent(LoginActivity.this).start(); + } catch (Exception e) { + onSignInError(); + } + } + + @UiThread + void onSignInError() { + signInElements.setVisibility(View.VISIBLE); + signingInElements.setVisibility(View.GONE); + emailField.requestFocus(); + passwordField.clear(); + dialog.showWarning(R.string.login_error_invalid_credentials); + } + + @Click + void resetPassword() { + ResetPasswordActivity_.intent(this).start(); + } + + private boolean validateCredentials() { + if (emailField.isEmpty()) { + emailField.setError(R.string.registration_error_field_required); + return false; + } + + if (passwordField.isEmpty()) { + passwordField.setError(R.string.registration_error_field_required); + return false; + } + + if (!android.util.Patterns.EMAIL_ADDRESS.matcher(emailField.getValue()).matches()) { + emailField.setError(R.string.registration_error_invalid_email); + return false; + } + + return true; + } + + @Background + void verifyEmail(String code) { + try { + Log.i(TAG, "Verifying email - code: " + code); + final EmailVerificationRequest request = new EmailVerificationRequest(code); + authenticationService.verifyEmail(request); + Toast.makeText(LoginActivity.this, "Email verified.", Toast.LENGTH_LONG).show(); + } catch (Exception e) { + Toast.makeText(LoginActivity.this, "Failed to verify email.", Toast.LENGTH_LONG).show(); + } + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/activity/MainActivity.java b/android/app/src/main/java/com/wolkabout/hexiwear/activity/MainActivity.java new file mode 100644 index 0000000..22d70cb --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/activity/MainActivity.java @@ -0,0 +1,237 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.activity; + +import android.bluetooth.BluetoothDevice; +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.Toast; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.adapter.DeviceListAdapter; +import com.wolkabout.hexiwear.model.BluetoothDeviceWrapper; +import com.wolkabout.hexiwear.service.BluetoothService; +import com.wolkabout.hexiwear.service.BluetoothService_; +import com.wolkabout.hexiwear.service.DeviceDiscoveryService; +import com.wolkabout.hexiwear.service.DeviceRegistrationService; +import com.wolkabout.hexiwear.util.HexiwearDevices; +import com.wolkabout.wolkrestandroid.Credentials_; + +import org.androidannotations.annotations.AfterInject; +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.ItemClick; +import org.androidannotations.annotations.ItemLongClick; +import org.androidannotations.annotations.OptionsItem; +import org.androidannotations.annotations.OptionsMenu; +import org.androidannotations.annotations.OptionsMenuItem; +import org.androidannotations.annotations.Receiver; +import org.androidannotations.annotations.ViewById; +import org.androidannotations.annotations.sharedpreferences.Pref; + +@OptionsMenu(R.menu.menu_main) +@EActivity(R.layout.activity_main) +public class MainActivity extends AppCompatActivity implements ServiceConnection { + + private static final String TAG = MainActivity.class.getSimpleName(); + private static final String OTAP_PREFIX = "OTAP"; + + @Bean + DeviceListAdapter adapter; + + @ViewById + ListView listDevices; + + @ViewById + ProgressBar progressBar; + + @ViewById + SwipeRefreshLayout swipeRefresh; + + @ViewById + Toolbar toolbar; + + @OptionsMenuItem + MenuItem toggleTracking; + + @Pref + Credentials_ credentials; + + @Bean + DeviceDiscoveryService deviceDiscoveryService; + + @Bean + DeviceRegistrationService deviceRegistrationService; + + @Bean + HexiwearDevices devicesStore; + + private boolean serviceBound; + + @AfterInject + void setStore() { + devicesStore.init(); + } + + @AfterViews + void setViews() { + setSupportActionBar(toolbar); + listDevices.setAdapter(adapter); + deviceDiscoveryService.startScan(); + swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + swipeRefresh.setRefreshing(false); + adapter.clear(); + deviceDiscoveryService.startScan(); + } + }); + } + + @AfterInject + void checkService() { + serviceBound = bindService(BluetoothService_.intent(this).get(), this, 0); + } + + @ItemClick(R.id.listDevices) + void bondWithDevice(final BluetoothDeviceWrapper wrapper) { + deviceDiscoveryService.cancelScan(); + final BluetoothDevice device = wrapper.getDevice(); + if (device.getBondState() == BluetoothDevice.BOND_BONDED) { + onBonded(device); + } else { + device.createBond(); + } + } + + // TODO This is a method to help with development. Remove once its no longer needed. + @ItemLongClick(R.id.listDevices) + void unbindDevice(final BluetoothDeviceWrapper wrapper) { + try { + final BluetoothDevice device = wrapper.getDevice(); + device.getClass().getMethod("removeBond", (Class[]) null).invoke(device, (Object[]) null); + Toast.makeText(this, "Device unpaired.", Toast.LENGTH_SHORT).show(); + adapter.notifyDataSetChanged(); + } catch (Exception e) { + Log.e(TAG, "Can't remove bond", e); + } + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + final BluetoothService.ServiceBinder binder = (BluetoothService.ServiceBinder) service; + final BluetoothService bluetoothService = binder.getService(); + final BluetoothDevice currentDevice = bluetoothService.getCurrentDevice(); + if (currentDevice != null) { + ReadingsActivity_.intent(this).device(currentDevice).flags(Intent.FLAG_ACTIVITY_NEW_TASK).start(); + final BluetoothDeviceWrapper wrapper = new BluetoothDeviceWrapper(); + wrapper.setDevice(currentDevice); + wrapper.setSignalStrength(-65); + adapter.add(wrapper); + + } + + unbindService(this); + serviceBound = false; + } + + @Override + public void onServiceDisconnected(ComponentName name) { + // Something terrible happened. + } + + @Override + protected void onDestroy() { + if (serviceBound) { + unbindService(this); + } + super.onDestroy(); + } + + @Receiver(actions = DeviceDiscoveryService.SCAN_STARTED, local = true) + void onScanningStarted() { + progressBar.setVisibility(View.VISIBLE); + toolbar.setTitle(R.string.discovery_scanning); + } + + @Receiver(actions = DeviceDiscoveryService.SCAN_STOPPED, local = true) + void onScanningStopped() { + progressBar.setVisibility(View.INVISIBLE); + toolbar.setTitle(credentials.username().get()); + } + + @Receiver(actions = DeviceDiscoveryService.DEVICE_DISCOVERED, local = true) + void onBluetoothDeviceFound(@Receiver.Extra final BluetoothDeviceWrapper wrapper) { + adapter.add(wrapper); + } + + @Receiver(actions = BluetoothDevice.ACTION_BOND_STATE_CHANGED) + void onBondStateChanged(Intent intent) { + final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1); + final int newBondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1); + + Log.d(TAG, device.getName() + "(" + device.getAddress() + ") changed state: " + previousBondState + " -> " + newBondState); + adapter.notifyDataSetChanged(); + + if (newBondState == BluetoothDevice.BOND_BONDED) { + onBonded(device); + } else if (previousBondState == BluetoothDevice.BOND_BONDING && newBondState == BluetoothDevice.BOND_NONE) { + device.createBond(); + } + } + + private void onBonded(BluetoothDevice device) { + Log.i(TAG, "Successfully bonded to: " + device.getName()); + if (!devicesStore.isRegistered(device)) { + deviceRegistrationService.registerHexiwearDevice(device); + } else if (device.getName().contains(OTAP_PREFIX)) { + FirmwareSelectActivity_.intent(this).device(device).start(); + } else { + ReadingsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_SINGLE_TOP).device(device).start(); + } + } + + @OptionsItem + void changePassword() { + PasswordChangeActivity_.intent(this).start(); + } + + @OptionsItem + void signOut() { + credentials.clear(); + LoginActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK).start(); + finish(); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/activity/PasswordChangeActivity.java b/android/app/src/main/java/com/wolkabout/hexiwear/activity/PasswordChangeActivity.java new file mode 100644 index 0000000..e0326c2 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/activity/PasswordChangeActivity.java @@ -0,0 +1,107 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.activity; + +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.util.Dialog; +import com.wolkabout.hexiwear.view.Input; +import com.wolkabout.wolkrestandroid.Credentials_; +import com.wolkabout.wolkrestandroid.dto.ChangePasswordRequest; +import com.wolkabout.wolkrestandroid.service.AuthenticationService; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.Background; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.Click; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.UiThread; +import org.androidannotations.annotations.ViewById; +import org.androidannotations.annotations.sharedpreferences.Pref; +import org.androidannotations.rest.spring.annotations.RestService; + +@EActivity(R.layout.activity_password_change) +public class PasswordChangeActivity extends AppCompatActivity { + + @ViewById + Toolbar toolbar; + + @ViewById + Input currentPassword; + + @ViewById + Input newPassword; + + @Bean + Dialog dialog; + + @Pref + Credentials_ credentials; + + @RestService + AuthenticationService authenticationService; + + @AfterViews + void init() { + setSupportActionBar(toolbar); + } + + @Click + @Background + void changePassword() { + if (!validate()) { + return; + } + + try { + final ChangePasswordRequest requestDto = new ChangePasswordRequest(credentials.username().get(), currentPassword.getValue(), newPassword.getValue()); + authenticationService.changePassword(requestDto); + onPasswordChanged(requestDto); + } catch (Exception e) { + dialog.showWarning(R.string.change_password_error); + } + } + + @UiThread + void onPasswordChanged(ChangePasswordRequest requestDto) { + currentPassword.clear(); + newPassword.clear(); + dialog.showInfo(R.string.change_password_success, false); + } + + private boolean validate() { + if (newPassword.isEmpty()) { + newPassword.setError(R.string.registration_error_field_required); + return false; + } + + if (newPassword.getValue().length() < 8) { + newPassword.setError(R.string.registration_error_invalid_password); + return false; + } + + return true; + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/activity/ReadingsActivity.java b/android/app/src/main/java/com/wolkabout/hexiwear/activity/ReadingsActivity.java new file mode 100644 index 0000000..49a8ecb --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/activity/ReadingsActivity.java @@ -0,0 +1,330 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.activity; + +import android.bluetooth.BluetoothDevice; +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.Menu; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.model.Characteristic; +import com.wolkabout.hexiwear.model.HexiwearDevice; +import com.wolkabout.hexiwear.model.Mode; +import com.wolkabout.hexiwear.service.BluetoothService; +import com.wolkabout.hexiwear.service.BluetoothService_; +import com.wolkabout.hexiwear.util.Dialog; +import com.wolkabout.hexiwear.util.HexiwearDevices; +import com.wolkabout.hexiwear.view.Reading; +import com.wolkabout.hexiwear.view.SingleReading; +import com.wolkabout.hexiwear.view.TripleReading; +import com.wolkabout.wolkrestandroid.Credentials_; + +import org.androidannotations.annotations.AfterInject; +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.Extra; +import org.androidannotations.annotations.OptionsItem; +import org.androidannotations.annotations.OptionsMenu; +import org.androidannotations.annotations.Receiver; +import org.androidannotations.annotations.ViewById; +import org.androidannotations.annotations.sharedpreferences.Pref; + +import java.util.List; +import java.util.Map; + +@EActivity(R.layout.activity_readings) +@OptionsMenu(R.menu.menu_readings) +public class ReadingsActivity extends AppCompatActivity implements ServiceConnection { + + private static final String TAG = ReadingsActivity.class.getSimpleName(); + + @Extra + BluetoothDevice device; + + @ViewById + View coordinator; + + @ViewById + Toolbar toolbar; + + @ViewById + SingleReading readingBattery; + + @ViewById + SingleReading readingTemperature; + + @ViewById + SingleReading readingHumidity; + + @ViewById + SingleReading readingPressure; + + @ViewById + SingleReading readingHeartRate; + + @ViewById + SingleReading readingLight; + + @ViewById + SingleReading readingSteps; + + @ViewById + SingleReading readingCalories; + + @ViewById + TripleReading readingAcceleration; + + @ViewById + TripleReading readingMagnet; + + @ViewById + TripleReading readingGyro; + + @ViewById + TextView connectionStatus; + + @ViewById + ProgressBar progressBar; + + @ViewById + LinearLayout readings; + + @Bean + HexiwearDevices hexiwearDevices; + + @Pref + Credentials_ credentials; + + @Bean + Dialog dialog; + + private HexiwearDevice hexiwearDevice; + private BluetoothService bluetoothService; + private boolean isBound; + private Mode mode = Mode.IDLE; + + @AfterInject + void startService() { + hexiwearDevice = hexiwearDevices.getDevice(device.getAddress()); + if (hexiwearDevices.shouldKeepAlive(hexiwearDevice)) { + BluetoothService_.intent(this).start(); + } + isBound = bindService(BluetoothService_.intent(this).get(), this, BIND_AUTO_CREATE); + } + + @AfterViews + void setViews() { + toolbar.setTitle(hexiwearDevice.getWolkName()); + setSupportActionBar(toolbar); + progressBar.setVisibility(View.VISIBLE); + } + + @Override + protected void onResume() { + super.onResume(); + invalidateOptionsMenu(); + setReadingVisibility(mode); + } + + @Receiver(actions = BluetoothService.MODE_CHANGED, local = true) + void onModeChanged(@Receiver.Extra final Mode mode) { + this.mode = mode; + connectionStatus.setText(mode.getStringResource()); + + if (mode == Mode.IDLE) { + dialog.showInfo(R.string.readings_idle_mode, false); + } + + setReadingVisibility(mode); + } + + private void setReadingVisibility(final Mode mode) { + final Map displayPreferences = hexiwearDevices.getDisplayPreferences(device.getAddress()); + for (int i = 0; i < readings.getChildCount(); i++) { + final Reading reading = (Reading) readings.getChildAt(i); + final Characteristic readingType = reading.getReadingType(); + final boolean readingEnabled = displayPreferences.get(readingType.name()); + reading.setVisibility(readingEnabled && mode.hasCharacteristic(readingType) ? View.VISIBLE : View.GONE); + } + } + + @Override + public void onServiceConnected(final ComponentName name, final IBinder service) { + final BluetoothService.ServiceBinder binder = (BluetoothService.ServiceBinder) service; + bluetoothService = binder.getService(); + if (!bluetoothService.isConnected()) { + bluetoothService.startReading(device); + } + final Mode mode = bluetoothService.getCurrentMode(); + if (mode != null) { + onModeChanged(mode); + } + } + + @Override + public void onServiceDisconnected(final ComponentName name) { + // Something terrible happened. + } + + @Override + protected void onDestroy() { + if (isBound) { + unbindService(this); + isBound = false; + } + super.onDestroy(); + } + + @Receiver(actions = BluetoothService.ACTION_NEEDS_BOND, local = true) + void onBondRequested() { + connectionStatus.setText(R.string.discovery_bonding); + Snackbar.make(coordinator, R.string.discovery_bonding, Snackbar.LENGTH_LONG).show(); + } + + @Receiver(actions = BluetoothService.CONNECTION_STATE_CHANGED, local = true) + void onConnectionStateChanged(@Receiver.Extra final boolean connectionState) { + connectionStatus.setText(connectionState ? R.string.readings_connection_connected : R.string.readings_connection_reconnecting); + } + + @Receiver(actions = BluetoothService.DATA_AVAILABLE, local = true) + void onDataAvailable(Intent intent) { + progressBar.setVisibility(View.INVISIBLE); + + final String uuid = intent.getStringExtra(BluetoothService.READING_TYPE); + final String data = intent.getStringExtra(BluetoothService.STRING_DATA); + + if (data.isEmpty()) { + return; + } + + final Characteristic characteristic = Characteristic.byUuid(uuid); + if (characteristic == null) { + Log.w(TAG, "UUID " + uuid + " is unknown. Skipping."); + return; + } + + switch (characteristic) { + case BATTERY: + readingBattery.setValue(data); + break; + case TEMPERATURE: + readingTemperature.setValue(data); + break; + case HUMIDITY: + readingHumidity.setValue(data); + break; + case PRESSURE: + readingPressure.setValue(data); + break; + case HEARTRATE: + readingHeartRate.setValue(data); + break; + case LIGHT: + readingLight.setValue(data); + break; + case STEPS: + readingSteps.setValue(data); + break; + case CALORIES: + readingCalories.setValue(data); + break; + case ACCELERATION: + final String[] accelerationReadings = data.split(";"); + readingAcceleration.setFirstValue(accelerationReadings[0]); + readingAcceleration.setSecondValue(accelerationReadings[1]); + readingAcceleration.setThirdValue(accelerationReadings[2]); + break; + case MAGNET: + final String[] magnetReadings = data.split(";"); + readingMagnet.setFirstValue(magnetReadings[0]); + readingMagnet.setSecondValue(magnetReadings[1]); + readingMagnet.setThirdValue(magnetReadings[2]); + break; + case GYRO: + final String[] gyroscopeReadings = data.split(";"); + readingGyro.setFirstValue(gyroscopeReadings[0]); + readingGyro.setSecondValue(gyroscopeReadings[1]); + readingGyro.setThirdValue(gyroscopeReadings[2]); + break; + default: + break; + } + } + + @Receiver(actions = BluetoothService.STOP) + void onStopReading() { + Log.i(TAG, "Stop command received. Finishing..."); + finish(); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + final boolean shouldTransmit = hexiwearDevices.shouldTransmit(device); + final int icon = shouldTransmit ? R.drawable.ic_cloud_queue_white_48dp : R.drawable.ic_cloud_off_white_48dp; + menu.getItem(0).setIcon(icon); + return super.onPrepareOptionsMenu(menu); + } + + @OptionsItem + void openSettings() { + SettingsActivity_.intent(this).device(hexiwearDevice).manufacturerInfo(bluetoothService.getManufacturerInfo()).start(); + } + + @OptionsItem + void setTime() { + bluetoothService.setTime(); + } + + @OptionsItem + void toggleTracking() { + if (credentials.username().get().equals("Demo")) { + return; + } + + hexiwearDevices.toggleTracking(device); + final boolean shouldTransmit = hexiwearDevices.shouldTransmit(device); + bluetoothService.setTracking(shouldTransmit); + supportInvalidateOptionsMenu(); + } + + @Override + public void onBackPressed() { + if (isTaskRoot()) { + MainActivity_.intent(this).start(); + } + BluetoothService_.intent(this).stop(); + super.onBackPressed(); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/activity/ResetPasswordActivity.java b/android/app/src/main/java/com/wolkabout/hexiwear/activity/ResetPasswordActivity.java new file mode 100644 index 0000000..4601ba2 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/activity/ResetPasswordActivity.java @@ -0,0 +1,68 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.activity; + +import android.support.v7.app.AppCompatActivity; +import android.util.Log; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.util.Dialog; +import com.wolkabout.hexiwear.view.Input; +import com.wolkabout.wolkrestandroid.dto.ResetPasswordRequest; +import com.wolkabout.wolkrestandroid.service.AuthenticationService; + +import org.androidannotations.annotations.Background; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.Click; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.EditorAction; +import org.androidannotations.annotations.ViewById; +import org.androidannotations.rest.spring.annotations.RestService; + +@EActivity(R.layout.activity_reset_password) +public class ResetPasswordActivity extends AppCompatActivity { + + private static final String TAG = ResetPasswordActivity.class.getSimpleName(); + + @ViewById + Input email; + + @Bean + Dialog dialog; + + @RestService + AuthenticationService authenticationService; + + @Click + @EditorAction(R.id.email) + @Background + void resetPassword() { + try { + authenticationService.resetPassword(new ResetPasswordRequest(email.getValue())); + dialog.showInfo(R.string.reset_password_success, true); + } catch (Exception e) { + Log.e(TAG, "Couldn't reset password", e); + dialog.showWarning(R.string.reset_password_error); + } + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/activity/SettingsActivity.java b/android/app/src/main/java/com/wolkabout/hexiwear/activity/SettingsActivity.java new file mode 100644 index 0000000..db3f51e --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/activity/SettingsActivity.java @@ -0,0 +1,53 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.activity; + +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.model.HexiwearDevice; +import com.wolkabout.hexiwear.model.ManufacturerInfo; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.Extra; +import org.androidannotations.annotations.ViewById; + +@EActivity(R.layout.activity_settings) +public class SettingsActivity extends AppCompatActivity { + + @Extra + public HexiwearDevice device; + + @Extra + public ManufacturerInfo manufacturerInfo; + + @ViewById + Toolbar toolbar; + + @AfterViews + void setToolbar() { + setSupportActionBar(toolbar); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/activity/SignUpActivity.java b/android/app/src/main/java/com/wolkabout/hexiwear/activity/SignUpActivity.java new file mode 100644 index 0000000..9665120 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/activity/SignUpActivity.java @@ -0,0 +1,147 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.activity; + + +import android.support.v7.app.AppCompatActivity; +import android.text.method.LinkMovementMethod; +import android.widget.CheckBox; +import android.widget.Toast; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.util.Dialog; +import com.wolkabout.hexiwear.view.Input; +import com.wolkabout.wolkrestandroid.dto.SignUpDto; +import com.wolkabout.wolkrestandroid.service.AuthenticationService; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.Background; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.Click; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.UiThread; +import org.androidannotations.annotations.ViewById; +import org.androidannotations.rest.spring.annotations.RestService; + +@EActivity(R.layout.activity_sign_up) +public class SignUpActivity extends AppCompatActivity { + + @ViewById + Input emailField; + + @ViewById + Input passwordField; + + @ViewById + Input firstNameField; + + @ViewById + Input lastNameField; + + @ViewById + CheckBox termsAndConditions; + + @Bean + Dialog dialog; + + @RestService + AuthenticationService authenticationService; + + @AfterViews + void init() { + termsAndConditions.setMovementMethod(LinkMovementMethod.getInstance()); + } + + @Click(R.id.signUpButton) + @Background + void signUp() { + if (!validate()) { + return; + } + + if (!termsAndConditions.isChecked()) { + Toast.makeText(this, R.string.registration_accept_terms, Toast.LENGTH_LONG).show(); + return; + } + + final SignUpDto signUpDto = parseUserInput(); + try { + authenticationService.signUp(signUpDto); + onSignUpSuccess(); + } catch (Exception e) { + onSignUpError(); + } + } + + @UiThread + void onSignUpSuccess() { + dialog.showInfo(R.string.registration_success, true); + } + + @UiThread + void onSignUpError() { + Toast.makeText(this, R.string.registration_failed, Toast.LENGTH_LONG).show(); + } + + private boolean validate() { + if (emailField.isEmpty()) { + emailField.setError(R.string.registration_error_field_required); + return false; + } + + if (passwordField.isEmpty()) { + passwordField.setError(R.string.registration_error_field_required); + return false; + } + + if (passwordField.getValue().length() < 8) { + passwordField.setError(R.string.registration_error_invalid_password); + return false; + } + + if (!android.util.Patterns.EMAIL_ADDRESS.matcher(emailField.getValue()).matches()) { + emailField.setError(R.string.registration_error_invalid_email); + return false; + } + + if (firstNameField.isEmpty()) { + firstNameField.setError(R.string.registration_error_field_required); + return false; + } + + if (lastNameField.isEmpty()) { + lastNameField.setError(R.string.registration_error_field_required); + return false; + } + + return true; + } + + private SignUpDto parseUserInput() { + final String email = emailField.getValue(); + final String password = passwordField.getValue(); + final String firstName = firstNameField.getValue(); + final String lastName = lastNameField.getValue(); + return new SignUpDto(email, password, firstName, lastName); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/adapter/DeviceListAdapter.java b/android/app/src/main/java/com/wolkabout/hexiwear/adapter/DeviceListAdapter.java new file mode 100644 index 0000000..f0d0520 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/adapter/DeviceListAdapter.java @@ -0,0 +1,149 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.adapter; + +import android.bluetooth.BluetoothDevice; +import android.content.Context; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.model.BluetoothDeviceWrapper; +import com.wolkabout.hexiwear.model.HexiwearDevice; +import com.wolkabout.hexiwear.util.HexiwearDevices; + +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.EViewGroup; +import org.androidannotations.annotations.RootContext; +import org.androidannotations.annotations.UiThread; +import org.androidannotations.annotations.ViewById; + +import java.util.ArrayList; +import java.util.List; + +@EBean +public class DeviceListAdapter extends BaseAdapter { + + private final List devices = new ArrayList<>(); + + @RootContext + Context context; + + @Bean + static HexiwearDevices hexiwearDevices; + + @Override + public int getCount() { + return devices.size(); + } + + @Override + public BluetoothDeviceWrapper getItem(int position) { + return devices.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @UiThread + public void add(BluetoothDeviceWrapper wrapper) { + for (BluetoothDeviceWrapper deviceWrapper : devices) { + if(deviceWrapper.getDevice().getAddress().equals(wrapper.getDevice().getAddress())) { + return; + } + } + + devices.add(wrapper); + notifyDataSetChanged(); + } + + @UiThread + public void clear() { + devices.clear(); + notifyDataSetChanged(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + DeviceItemView deviceItemView; + if (convertView == null) { + deviceItemView = DeviceListAdapter_.DeviceItemView_.build(context); + } else { + deviceItemView = (DeviceItemView) convertView; + } + deviceItemView.bind(getItem(position)); + return deviceItemView; + } + + @EViewGroup(R.layout.item_device) + public static class DeviceItemView extends LinearLayout { + + @ViewById + TextView deviceName; + + @ViewById + TextView deviceUUID; + + @ViewById + TextView status; + + @ViewById + ImageView signalStrength; + + @ViewById + TextView otapMode; + + public DeviceItemView(Context context) { + super(context); + } + + void bind(BluetoothDeviceWrapper wrapper) { + final BluetoothDevice device = wrapper.getDevice(); + + final String name = device.getName(); + final HexiwearDevice hexiwearDevice = hexiwearDevices.getDevice(device.getAddress()); + if (hexiwearDevice != null) { + deviceName.setText(hexiwearDevice.getWolkName()); + } else if (!TextUtils.isEmpty(name)) { + deviceName.setText(name); + } else { + deviceName.setText(device.getAddress()); + } + + status.setVisibility(device.getBondState() == BluetoothDevice.BOND_BONDED ? VISIBLE : GONE); + + deviceUUID.setText(device.getAddress()); + signalStrength.setImageResource(wrapper.getSignalStrength()); + otapMode.setVisibility(wrapper.isInOtapMode() ? VISIBLE : GONE); + } + + } + +} \ No newline at end of file diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/adapter/FirmwareListAdapter.java b/android/app/src/main/java/com/wolkabout/hexiwear/adapter/FirmwareListAdapter.java new file mode 100644 index 0000000..516d9c2 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/adapter/FirmwareListAdapter.java @@ -0,0 +1,121 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.model.otap.Image; + +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.EViewGroup; +import org.androidannotations.annotations.RootContext; +import org.androidannotations.annotations.UiThread; +import org.androidannotations.annotations.ViewById; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +@EBean +public class FirmwareListAdapter extends BaseAdapter { + + @RootContext + Context context; + + private final List images = new ArrayList<>(); + + @Override + public int getCount() { + return images.size(); + } + + @Override + public Image getItem(final int position) { + return images.get(position); + } + + @Override + public long getItemId(final int position) { + return position; + } + + @Override + public View getView(final int position, final View convertView, final ViewGroup parent) { + FirmwareItemView firmwareItemView; + if (convertView == null) { + firmwareItemView = FirmwareListAdapter_.FirmwareItemView_.build(context); + } else { + firmwareItemView = (FirmwareItemView) convertView; + } + firmwareItemView.bind(getItem(position)); + return firmwareItemView; + } + + public void clear() { + images.clear(); + refreshList(); + } + + public void add(final Image image) { + images.add(image); + refreshList(); + } + + @UiThread + void refreshList() { + notifyDataSetChanged(); + } + + @EViewGroup(R.layout.item_firmware) + public static class FirmwareItemView extends LinearLayout { + + @ViewById + TextView fileName; + + @ViewById + TextView version; + + @ViewById + TextView type; + + public FirmwareItemView(Context context) { + super(context); + } + + void bind(final Image image) { + fileName.setText(image.getFileName()); + version.setText(formatValue(R.string.firmware_update_version, image.getVersion())); + type.setText(formatValue(R.string.firmware_update_type, image.getType().name())); + } + + private String formatValue(final int stringResource, final String value) { + return String.format(Locale.ENGLISH, getContext().getString(stringResource), value); + } + + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/adapter/HexiwearListAdapter.java b/android/app/src/main/java/com/wolkabout/hexiwear/adapter/HexiwearListAdapter.java new file mode 100644 index 0000000..06fa818 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/adapter/HexiwearListAdapter.java @@ -0,0 +1,132 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.adapter; + +import android.content.Context; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.Checkable; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.model.HexiwearDevice; + +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.EViewGroup; +import org.androidannotations.annotations.RootContext; +import org.androidannotations.annotations.UiThread; +import org.androidannotations.annotations.ViewById; + +import java.util.ArrayList; +import java.util.List; + +@EBean +public class HexiwearListAdapter extends BaseAdapter { + + private final List devices = new ArrayList<>(); + + @RootContext + Context context; + + @Override + public int getCount() { + return devices.size(); + } + + @Override + public HexiwearDevice getItem(int position) { + return devices.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + HexiwearItemView hexiwearItemView; + if (convertView == null) { + hexiwearItemView = HexiwearListAdapter_.HexiwearItemView_.build(context); + } else { + hexiwearItemView = (HexiwearItemView) convertView; + } + hexiwearItemView.bind(getItem(position)); + return hexiwearItemView; + } + + @UiThread + public void update(List devices) { + this.devices.clear(); + this.devices.add(new HexiwearDevice()); + this.devices.addAll(devices); + notifyDataSetChanged(); + } + + @EViewGroup(R.layout.item_hexiwear) + static class HexiwearItemView extends LinearLayout implements Checkable { + + @ViewById + ImageView icon; + + @ViewById + TextView deviceName; + + private boolean checked; + + public HexiwearItemView(final Context context) { + super(context); + } + + public void bind(HexiwearDevice device) { + final String wolkName = device.getWolkName(); + final boolean isNewDevice = TextUtils.isEmpty(wolkName); + deviceName.setText(isNewDevice ? getContext().getString(R.string.activation_dialog_new_device) : wolkName); + } + + @Override + public void setChecked(final boolean checked) { + this.checked = checked; + onCheckedChanged(); + } + + @Override + public boolean isChecked() { + return checked; + } + + @Override + public void toggle() { + checked = !checked; + onCheckedChanged(); + } + + private void onCheckedChanged() { + icon.setBackgroundResource(checked ? R.drawable.ic_arrow_forward_black_24dp : 0); + } + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/fragment/HexiwearSettingsFragment.java b/android/app/src/main/java/com/wolkabout/hexiwear/fragment/HexiwearSettingsFragment.java new file mode 100644 index 0000000..bb66008 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/fragment/HexiwearSettingsFragment.java @@ -0,0 +1,156 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.fragment; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.preference.SwitchPreference; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.activity.SettingsActivity; +import com.wolkabout.hexiwear.model.HexiwearDevice; +import com.wolkabout.hexiwear.service.BluetoothService; +import com.wolkabout.hexiwear.service.BluetoothService_; +import com.wolkabout.hexiwear.util.HexiwearDevices; +import com.wolkabout.wolkrestandroid.Credentials_; + +import org.androidannotations.annotations.AfterPreferences; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EFragment; +import org.androidannotations.annotations.PreferenceByKey; +import org.androidannotations.annotations.PreferenceScreen; +import org.androidannotations.annotations.sharedpreferences.Pref; + +import java.util.Map; + + +@PreferenceScreen(R.xml.pref_hexiwear_settings) +@EFragment +public class HexiwearSettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener, Preference.OnPreferenceChangeListener { + + private static final String TAG = HexiwearSettingsFragment.class.getSimpleName(); + + @Bean + HexiwearDevices hexiwearDevices; + + @PreferenceByKey(R.string.preferences_manufacturer_info) + Preference manufacturerInfo; + + @PreferenceByKey(R.string.preferences_fw_version) + Preference fwVersion; + + @PreferenceByKey(R.string.preferences_publish_interval_key) + Preference publishInterval; + + @PreferenceByKey(R.string.preferences_keep_alive_key) + SwitchPreference keepAlive; + + @PreferenceByKey(R.string.preferences_publish_key) + SwitchPreference publish; + + @Pref + Credentials_ credentials; + + private HexiwearDevice device; + private Map displayPreferences; + + @AfterPreferences + void initPrefs() { + SettingsActivity settingsActivity = (SettingsActivity) getActivity(); + device = settingsActivity.device; + displayPreferences = hexiwearDevices.getDisplayPreferences(device.getDeviceAddress()); + + for (Map.Entry entry : displayPreferences.entrySet()) { + Log.d(TAG, "Key: " + entry.getKey() + " value " + entry.getValue()); + final SwitchPreference displayPref = (SwitchPreference) findPreference(entry.getKey()); + if (displayPref != null) { + displayPref.setChecked(entry.getValue()); + displayPref.setOnPreferenceChangeListener(this); + } + } + + final String interval = String.format(getActivity().getString(R.string.preferences_publish_interval_value), hexiwearDevices.getPublishInterval(device)); + publishInterval.setSummary(interval); + publishInterval.setOnPreferenceChangeListener(this); + keepAlive.setChecked(hexiwearDevices.shouldKeepAlive(device)); + keepAlive.setOnPreferenceChangeListener(this); + publish.setChecked(hexiwearDevices.shouldTransmit(device)); + publish.setOnPreferenceChangeListener(this); + manufacturerInfo.setSummary(settingsActivity.manufacturerInfo.manufacturer); + fwVersion.setSummary(settingsActivity.manufacturerInfo.firmwareRevision); + + getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean isDemo = credentials.username().get().equals("Demo"); + if (preference == publishInterval) { + if (isDemo) { + return true; + } + + Log.d(TAG, "Publishing time changed. New value is: " + newValue); + hexiwearDevices.setPublishInterval(device, Integer.valueOf((String) newValue)); + final String interval = String.format(getActivity().getString(R.string.preferences_publish_interval_value), hexiwearDevices.getPublishInterval(device)); + publishInterval.setSummary(interval); + LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(new Intent(BluetoothService.PUBLISH_TIME_CHANGED)); + } else if (preference == keepAlive) { + Log.d(TAG, "Keep alive changed. New value: " + newValue); + final boolean shouldKeepAlive = (boolean) newValue; + hexiwearDevices.setKeepAlive(device, shouldKeepAlive); + if (shouldKeepAlive) { + BluetoothService_.intent(getActivity()).start(); + } else { + BluetoothService_.intent(getActivity()).stop(); + } + } else if (preference == publish) { + if (isDemo) { + return true; + } + + Log.d(TAG, "Should publish changed. New value: " + newValue); + hexiwearDevices.toggleTracking(device); + LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(new Intent(BluetoothService.SHOULD_PUBLISH_CHANGED)); + } else { + Log.d(TAG, "Key: " + preference.getKey() + " value " + newValue); + displayPreferences.put(preference.getKey(), (Boolean) newValue); + hexiwearDevices.setDisplayPreferences(device.getDeviceAddress(), displayPreferences); + + final Intent preferenceChanged = new Intent(BluetoothService.PREFERENCE_CHANGED); + preferenceChanged.putExtra(BluetoothService.PREFERENCE_NAME, preference.getKey()); + preferenceChanged.putExtra(BluetoothService.PREFERENCE_ENABLED, (boolean) newValue); + LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(preferenceChanged); + } + + return true; + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + // Preferences are changed on this screen only. + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/BluetoothDeviceWrapper.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/BluetoothDeviceWrapper.java new file mode 100644 index 0000000..91403da --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/BluetoothDeviceWrapper.java @@ -0,0 +1,81 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model; + +import android.bluetooth.BluetoothDevice; + +import com.wolkabout.hexiwear.R; + +import org.parceler.Parcel; + +@Parcel +public class BluetoothDeviceWrapper { + + BluetoothDevice device; + + int signalStrength; + + boolean isInOtapMode; + + public BluetoothDevice getDevice() { + return device; + } + + public void setDevice(BluetoothDevice device) { + this.device = device; + } + + public int getSignalStrength() { + if (signalStrength > -50.0) { + return R.drawable.ic_signal_strength_5; + } else if (signalStrength > -60.0) { + return R.drawable.ic_signal_strength_4; + } else if (signalStrength > -70.0) { + return R.drawable.ic_signal_strength_3; + } else if (signalStrength > -80.0) { + return R.drawable.ic_signal_strength_2; + } else { + return R.drawable.ic_signal_strength_1; + } + } + + public void setSignalStrength(int signalStrength) { + this.signalStrength = signalStrength; + } + + public boolean isInOtapMode() { + return isInOtapMode; + } + + public void setInOtapMode(boolean inOtapMode) { + isInOtapMode = inOtapMode; + } + + @Override + public String toString() { + return "BluetoothDeviceWrapper{" + + "device=" + device + + ", signalStrength=" + signalStrength + + ", isInOtapMode=" + isInOtapMode + + '}'; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/Characteristic.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/Characteristic.java new file mode 100644 index 0000000..046ebf7 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/Characteristic.java @@ -0,0 +1,109 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model; + +import java.util.ArrayList; +import java.util.List; + +public enum Characteristic { + + ACCELERATION(Type.READING, "00002001-0000-1000-8000-00805f9b34fb", "g"), + GYRO(Type.READING, "00002002-0000-1000-8000-00805f9b34fb", "\u00B0/s"), + MAGNET(Type.READING, "00002003-0000-1000-8000-00805f9b34fb", "\u00B5T"), + LIGHT(Type.READING, "00002011-0000-1000-8000-00805f9b34fb", "%"), + TEMPERATURE(Type.READING, "00002012-0000-1000-8000-00805f9b34fb", "\u2103"), + HUMIDITY(Type.READING, "00002013-0000-1000-8000-00805f9b34fb", "%"), + PRESSURE(Type.READING, "00002014-0000-1000-8000-00805f9b34fb", "kPa"), + BATTERY(Type.READING, "00002a19-0000-1000-8000-00805f9b34fb", "%"), + HEARTRATE(Type.READING, "00002021-0000-1000-8000-00805f9b34fb", "bpm"), + STEPS(Type.READING, "00002022-0000-1000-8000-00805f9b34fb", ""), + CALORIES(Type.READING, "00002023-0000-1000-8000-00805f9b34fb", ""), + + ALERT_IN(Type.ALERT, "00002031-0000-1000-8000-00805f9b34fb"), + ALERT_OUT(Type.ALERT, "00002032-0000-1000-8000-00805f9b34fb"), + + MODE(Type.MODE, "00002041-0000-1000-8000-00805f9b34fb"), + + SERIAL(Type.INFO, "00002a25-0000-1000-8000-00805f9b34fb"), + FW_REVISION(Type.INFO, "00002a26-0000-1000-8000-00805f9b34fb"), + HW_REVISION(Type.INFO, "00002a27-0000-1000-8000-00805f9b34fb"), + MANUFACTURER(Type.INFO, "00002a29-0000-1000-8000-00805f9b34fb"), + + CONTROL_POINT(Type.OTAP, "01ff5551-ba5e-f4ee-5ca1-eb1e5e4b1ce0"), + DATA(Type.OTAP, "01ff5552-ba5e-f4ee-5ca1-eb1e5e4b1ce0"), + STATE(Type.OTAP, "01ff5553-ba5e-f4ee-5ca1-eb1e5e4b1ce0"); + + private final Type type; + private final String uuid; + private final String unit; + + Characteristic(final Type type, final String uuid) { + this.type = type; + this.uuid = uuid; + this.unit = ""; + } + + Characteristic(final Type type, final String uuid, final String unit) { + this.type = type; + this.uuid = uuid; + this.unit = unit; + } + + public Type getType() { + return type; + } + + public String getUuid() { + return uuid; + } + + public String getUnit() { + return unit; + } + + public static Characteristic byUuid(final String uuid) { + for (final Characteristic characteristic : values()) { + if (characteristic.uuid.equals(uuid)) { + return characteristic; + } + } + return null; + } + + public static Characteristic byOrdinal(final int ordinal) { + return values()[ordinal]; + } + + public static List getReadings() { + final List readingCharacteristics = new ArrayList<>(); + for (Characteristic characteristic : values()) { + if (characteristic.type == Type.READING) { + readingCharacteristics.add(characteristic); + } + } + return readingCharacteristics; + } + + public enum Type { + READING, ALERT, MODE, INFO, OTAP + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/HexiwearDevice.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/HexiwearDevice.java new file mode 100644 index 0000000..5221f76 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/HexiwearDevice.java @@ -0,0 +1,75 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model; + +import com.wolkabout.wolk.Device; + +import java.io.Serializable; + + +public class HexiwearDevice extends Device implements Serializable { + + private String deviceName; + private String deviceAddress; + private String wolkName; + + public HexiwearDevice() {} + + public HexiwearDevice(String deviceName, String deviceSerial, String deviceAddress, String devicePassword, String wolkName) { + this.deviceName = deviceName; + this.serialId = deviceSerial; + this.deviceAddress = deviceAddress; + this.wolkName = wolkName; + this.password = devicePassword; + } + + public String getDeviceName() { + return deviceName; + } + + public String getDeviceSerial() { + return serialId; + } + + public String getDeviceAddress() { + return deviceAddress; + } + + public String getWolkName() { + return wolkName; + } + + public String getDevicePassword() { + return password; + } + + @Override + public String toString() { + return "HexiwearDevice{" + + "deviceName='" + deviceName + '\'' + + ", deviceSerial='" + serialId + '\'' + + ", deviceAddress='" + deviceAddress + '\'' + + ", devicePassword='" + password + '\'' + + ", wolkName='" + wolkName + '\'' + + '}'; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/ManufacturerInfo.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/ManufacturerInfo.java new file mode 100644 index 0000000..c83af02 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/ManufacturerInfo.java @@ -0,0 +1,39 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.wolkabout.hexiwear.model; + +import org.parceler.Parcel; + +@Parcel +public class ManufacturerInfo { + public String manufacturer; + public String hardwareRevision; + public String firmwareRevision; + + @Override + public String toString() { + return "ManufacturerInfo{" + + "manufacturer='" + manufacturer + '\'' + + ", hardwareRevision='" + hardwareRevision + '\'' + + ", firmwareRevision='" + firmwareRevision + '\'' + + '}'; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/Mode.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/Mode.java new file mode 100644 index 0000000..f75b481 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/Mode.java @@ -0,0 +1,98 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model; + +import com.wolkabout.hexiwear.R; + +import java.util.ArrayList; +import java.util.List; + +public enum Mode { + + IDLE(0, R.string.mode_idle), + WATCH(1, R.string.mode_watch), + SENSOR_TAG(2, R.string.mode_sensor_tag), + WEATHER_STATION(3, R.string.mode_weather_station), + MOTION_CONTROL(4, R.string.mode_motion_control), + HEARTRATE(5, R.string.mode_heartrate), + PEDOMETER(6, R.string.mode_pedometer), + COMPASS(7, R.string.mode_compass); + + private final int symbol; + private final int stringResource; + + Mode(final int symbol, final int stringResource) { + this.symbol = symbol; + this.stringResource = stringResource; + } + + public int getStringResource() { + return stringResource; + } + + public static Mode bySymbol(final int symbol) { + for (Mode mode : values()) { + if (mode.symbol == symbol) { + return mode; + } + } + throw new IllegalArgumentException("No mode with such symbol: " + symbol); + } + + public List getCharacteristics() { + final List characteristics = new ArrayList<>(); + + switch (this) { + case SENSOR_TAG: + characteristics.add(Characteristic.BATTERY); + characteristics.add(Characteristic.ACCELERATION); + characteristics.add(Characteristic.MAGNET); + characteristics.add(Characteristic.GYRO); + characteristics.add(Characteristic.TEMPERATURE); + characteristics.add(Characteristic.HUMIDITY); + characteristics.add(Characteristic.PRESSURE); + characteristics.add(Characteristic.LIGHT); + break; + case PEDOMETER: + characteristics.add(Characteristic.STEPS); + characteristics.add(Characteristic.CALORIES); + break; + case HEARTRATE: + characteristics.add(Characteristic.HEARTRATE); + break; + default: + break; + } + + return characteristics; + } + + public boolean hasCharacteristic(final String characteristicName) { + return hasCharacteristic(Characteristic.valueOf(characteristicName)); + } + + public boolean hasCharacteristic(final Characteristic characteristic) { + final List characteristics = getCharacteristics(); + return characteristics.contains(characteristic); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/Command.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/Command.java new file mode 100644 index 0000000..579dfd7 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/Command.java @@ -0,0 +1,53 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap; + +public enum Command { + + NEW_IMAGE_NOTIFICATION(1), + NEW_IMAGE_INFO_REQUEST(2), + NEW_IMAGE_INFO_RESPONSE(3), + IMAGE_BLOCK_REQUEST(4), + IMAGE_CHUNK(5), + IMAGE_TRANSFER_COMPLETE(6), + ERROR_NOTIFICATION(7), + STOP_IMAGE_TRANSFER(8); + + private final byte commandByte; + + Command(final int commandByte) { + this.commandByte = (byte) commandByte; + } + + public byte getCommandByte() { + return commandByte; + } + + public static Command byCommandByte(final byte commandByte) { + for (Command command : values()) { + if (command.getCommandByte() == commandByte) { + return command; + } + } + throw new IllegalArgumentException("Unknown command: " + commandByte); + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/Image.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/Image.java new file mode 100644 index 0000000..5f83161 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/Image.java @@ -0,0 +1,93 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap; + +import com.wolkabout.hexiwear.model.otap.response.ImageBlockRequest; +import com.wolkabout.hexiwear.util.ByteInputStream; +import com.wolkabout.hexiwear.util.ByteUtils; + +import org.parceler.Parcel; + +import java.nio.ByteBuffer; + +public class Image { + + private final String fileName; + private final ImageHeader header; + + byte[] data; + + public Image(final String fileName, final byte[] bytes) { + this.fileName = fileName; + final ByteInputStream inputStream = new ByteInputStream(bytes); + header = new ImageHeader(inputStream.nextBytes(ImageHeader.SIZE)); + data = bytes; + } + + public byte[] getNewImageInfoResponse() { + final ByteBuffer buffer = ByteBuffer.allocate(15); + buffer.put(Command.NEW_IMAGE_INFO_RESPONSE.getCommandByte()); + buffer.put(header.getImageId()); + buffer.put(header.getImageVersion().getRawData()); + buffer.put(header.getTotalImageFileSize()); + return buffer.array(); + } + + public ImageBlock getBlock(final ImageBlockRequest imageBlockRequest) { + final ByteInputStream inputStream = new ByteInputStream(data, imageBlockRequest.getStartPosition()); + final byte[] blockData = inputStream.nextBytes(imageBlockRequest.getBlockSize()); + return new ImageBlock(blockData, imageBlockRequest); + } + + public String getFileName() { + return fileName; + } + + public String getVersion() { + return header.getImageVersion().getBuildVersion(); + } + + public long getSize() { + return ByteUtils.parseLong(header.getTotalImageFileSize()); + } + + public Type getType() { + return Type.fromBytes(header.getImageId()); + } + + public enum Type { + KW40, MK64; + + public static Type fromBytes(final byte[] bytes) { + final int id = (int) ByteUtils.parseLong(bytes); + switch (id) { + case 1: + return KW40; + case 2: + return MK64; + default: + throw new IllegalArgumentException("No such type: " + id); + } + } + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageBlock.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageBlock.java new file mode 100644 index 0000000..5ca019e --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageBlock.java @@ -0,0 +1,70 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap; + +import com.wolkabout.hexiwear.model.otap.response.ImageBlockRequest; +import com.wolkabout.hexiwear.util.ByteInputStream; +import com.wolkabout.hexiwear.util.ByteUtils; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public class ImageBlock { + + private final List chunks = new ArrayList<>(); + private final int numberOfChunks; + private int position = 0; + + public ImageBlock(final byte[] data, final ImageBlockRequest imageBlockRequest) { + final int chunkSize = imageBlockRequest.getChunkSize(); + numberOfChunks = (int) Math.ceil((double) imageBlockRequest.getBlockSize() / chunkSize); + final ByteInputStream inputStream = new ByteInputStream(data); + for (int i = 0; i < numberOfChunks - 1; i++) { + chunks.add(inputStream.nextBytes(chunkSize)); + } + chunks.add(inputStream.remainingBytes()); + } + + public byte[] getNextChunk() { + final byte[] nextChunk = chunks.get(position); + final ByteBuffer buffer = ByteBuffer.allocate(nextChunk.length + 2); + buffer.put(Command.IMAGE_CHUNK.getCommandByte()); + buffer.put(ByteUtils.intToByte(position)); + buffer.put(nextChunk); + position++; + return buffer.array(); + } + + public boolean isCompleted() { + return position == numberOfChunks; + } + + public int getNumberOfChunks() { + return numberOfChunks; + } + + public int getPosition() { + return position + 1; + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageHeader.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageHeader.java new file mode 100644 index 0000000..2263615 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageHeader.java @@ -0,0 +1,111 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap; + +import com.wolkabout.hexiwear.util.ByteInputStream; +import com.wolkabout.hexiwear.util.ByteUtils; + +import org.parceler.Parcel; + + +public class ImageHeader { + + public static final int SIZE = 58; + + private final byte[] upgradeFileIdentifier; + private final byte[] headerVersion; + private final byte[] headerLength; + private final byte[] headerFieldControl; + private final byte[] companyIdentifier; + private final byte[] imageId; + private final ImageVersion imageVersion; + private final byte[] headerString; + private final byte[] totalImageFileSize; + + public ImageHeader(final byte[] bytes) { + if (bytes.length != SIZE) { + throw new IllegalArgumentException("Header data must contain exactly " + SIZE + " bytes."); + } + + final ByteInputStream inputStream = new ByteInputStream(bytes); + upgradeFileIdentifier = inputStream.nextBytes(4); + headerVersion = inputStream.nextBytes(2); + headerLength = inputStream.nextBytes(2); + headerFieldControl = inputStream.nextBytes(2); + companyIdentifier = inputStream.nextBytes(2); + imageId = inputStream.nextBytes(2); + imageVersion = new ImageVersion(inputStream.nextBytes(8)); + headerString = inputStream.nextBytes(32); + totalImageFileSize = inputStream.nextBytes(4); + } + + public byte[] getUpgradeFileIdentifier() { + return upgradeFileIdentifier; + } + + public byte[] getHeaderVersion() { + return headerVersion; + } + + public byte[] getHeaderLength() { + return headerLength; + } + + public byte[] getHeaderFieldControl() { + return headerFieldControl; + } + + public byte[] getCompanyIdentifier() { + return companyIdentifier; + } + + public byte[] getImageId() { + return imageId; + } + + public ImageVersion getImageVersion() { + return imageVersion; + } + + public byte[] getHeaderString() { + return headerString; + } + + public byte[] getTotalImageFileSize() { + return totalImageFileSize; + } + + @Override + public String toString() { + return "ImageHeader{" + + "upgradeFileIdentifier=" + ByteUtils.parseLong(upgradeFileIdentifier) + + ", headerVersion=" + ByteUtils.parseLong(headerVersion) + + ", headerLength=" + ByteUtils.parseLong(headerLength) + + ", headerFieldControl=" + ByteUtils.parseLong(headerFieldControl) + + ", companyIdentifier=" + ByteUtils.parseLong(companyIdentifier) + + ", imageId=" + ByteUtils.parseLong(imageId) + + ", imageVersion=" + imageVersion + + ", headerString=" + ByteUtils.parseString(headerString) + + ", totalImageFileSize=" + ByteUtils.parseLong(totalImageFileSize) + + '}'; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageVersion.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageVersion.java new file mode 100644 index 0000000..f552521 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/ImageVersion.java @@ -0,0 +1,76 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap; + +import com.wolkabout.hexiwear.util.ByteInputStream; + +import org.parceler.Parcel; + +public class ImageVersion { + + byte[] rawData; + + private final String buildVersion; + private final int stackVersion; + private final String hardwareId; + private final int endManufacturerId; + + public ImageVersion(final byte[] bytes) { + rawData = bytes; + + final ByteInputStream inputStream = new ByteInputStream(bytes); + buildVersion = inputStream.nextNumberArray(3, 1); + stackVersion = inputStream.nextInt(1); + hardwareId = inputStream.nextNumberArray(3, 1); + endManufacturerId = inputStream.nextInt(1); + } + + public byte[] getRawData() { + return rawData; + } + + public String getBuildVersion() { + return buildVersion; + } + + public int getStackVersion() { + return stackVersion; + } + + public String getHardwareId() { + return hardwareId; + } + + public int getEndManufacturerId() { + return endManufacturerId; + } + + @Override + public String toString() { + return "ImageVersion{" + + "buildVersion=" + buildVersion + + ", stackVersion=" + stackVersion + + ", hardwareId=" + hardwareId + + ", endManufacturerId=" + endManufacturerId + + '}'; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ErrorNotification.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ErrorNotification.java new file mode 100644 index 0000000..050c4f9 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ErrorNotification.java @@ -0,0 +1,101 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap.response; + +import com.wolkabout.hexiwear.util.ByteInputStream; + +public class ErrorNotification { + + private final int commandId; + private final ErrorStatus errorStatus; + + public ErrorNotification(final byte[] bytes) { + final ByteInputStream inputStream = new ByteInputStream(bytes); + inputStream.nextBytes(1); // Skip command byte + commandId = inputStream.nextInt(1); + errorStatus = ErrorStatus.byValue(inputStream.nextInt(1)); + } + + public int getCommandId() { + return commandId; + } + + public ErrorStatus getErrorStatus() { + return errorStatus; + } + + @Override + public String toString() { + return "ErrorNotification{" + + "commandId=" + commandId + + ", errorStatus=" + errorStatus + + '}'; + } + + public enum ErrorStatus { + SUCCESS(0), /*!< The operation was successful. */ + IMAGE_DATA_NOT_EXPECTED(1), /*!< The OTAP Server tried to send an image data chunk to the OTAP Client but the Client was not expecting it. */ + UNEXPECTED_TRANSFER_METHOD(2), /*!< The OTAP Server tried to send an image data chunk using a transfer method the OTAP Client does not support/expect. */ + UNEXPECTED_COMMAND_ON_DATA_CHANNEL(3), /*!< The OTAP Server tried to send an unexpected command (different from a data chunk), on a data Channel (ATT or CoC), */ + UNEXPECTED_L2CAP_OR_PSM(4), /*!< The selected channel or PSM is not valid for the selected transfer method (ATT or CoC),. */ + UNEXPECTED_OTAP_PEER(5), /*!< A command was received from an unexpected OTAP Server or Client device. */ + UNEXPECTED_COMMAND(6), /*!< The command sent from the OTAP peer device is not expected in the current state. */ + UNKNOWN_COMMAND(7), /*!< The command sent from the OTAP peer device is not known. */ + INVALID_COMMAND_LENGTH(8), /*!< Invalid command length. */ + INVALID_COMMAND_PARAMETER(9), /*!< A parameter of the command was not valid. */ + FAILED_IMAGE_INTEGRITY_CHECK(10), /*!< The image integrity check has failed. */ + UNEXPECTED_SEQUENCE_NUMBER(11), /*!< A chunk with an unexpected sequence number has been received. */ + IMAGE_SIZE_TOO_LARGE(12), /*!< The upgrade image size is too large for the OTAP Client. */ + UNEXPECTED_DATA_LENGTH(13), /*!< The length of a Data Chunk was not expected. */ + UNKNOWN_FILE_IDENTIFIER(14), /*!< The image file identifier is not recognized. */ + UNKNOWN_HEADER_VERSION(15), /*!< The image file header version is not recognized. */ + UNEXPECTED_HEADER_LENGTH(0x16), /*!< The image file header length is not expected for the current header version. */ + UNEXPECTED_HEADER_FIELD_CONTROL(0x17), /*!< The image file header field control is not expected for the current header version. */ + UNKNOWN_COMPANY_ID(0x18), /*!< The image file header company identifier is not recognized. */ + UNEXPECTED_IMAGE_ID(0x19), /*!< The image file header image identifier is not as expected. */ + UNEXPECTED_IMAGE_VERSION(20), /*!< The image file header image version is not as expected. */ + UNEXPECTED_IMAGE_FILE_SIZE(21), /*!< The image file header image file size is not as expected. */ + INVALID_SUB_ELEMENT_LENGTH(22), /*!< One of the sub-elements has an invalid length. */ + IMAGE_STORAGE_ERROR(23), /*!< An image storage error has occurred. */ + INVALID_IMAGE_CRC(24), /*!< The computed CRC does not match the received CRC. */ + INVALID_IMAGE_FILE_SIZE(25), /*!< The image file size is not valid. */ + INVALID_L2CAP_PSM(26), /*!< A block transfer request has been made via the L2CAP CoC method but the specified Psm is not known. */ + NO_L2CAP_PSM_CONNECTION(27), /*!< A block transfer request has been made via the L2CAP CoC method but there is no valid PSM connection. */ + NUMBER_OF_STATUSES(28); + + private final int value; + + ErrorStatus(final int value) { + this.value = (byte) value; + } + + public static ErrorStatus byValue(final int value) { + for (ErrorStatus errorStatus : values()) { + if (errorStatus.value == value) { + return errorStatus; + } + } + return null; + } + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ImageBlockRequest.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ImageBlockRequest.java new file mode 100644 index 0000000..87bfff1 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ImageBlockRequest.java @@ -0,0 +1,81 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap.response; + +import com.wolkabout.hexiwear.util.ByteInputStream; + +public class ImageBlockRequest { + + private final int imageId; // Image ID + private final int startPosition; // Start position of the image block to be transferred. + private final int blockSize; // Requested total block size in bytes. + private final int chunkSize; // Chunk size in bytes. Maximum of 256 chunks per block. + private final int transferMethod; // 0 = ATT, 1 = L2CAP PSM Credit based channel + private final int l2capChannelOrPsm; // 4 = ATT, Other values = PSM for credit based channels + + public ImageBlockRequest(final byte[] bytes) { + final ByteInputStream inputStream = new ByteInputStream(bytes); + inputStream.nextBytes(1); // Skip command byte + imageId = inputStream.nextInt(2); + startPosition = inputStream.nextInt(4); + blockSize = inputStream.nextInt(4); + chunkSize = inputStream.nextInt(2); + transferMethod = inputStream.nextInt(1); + l2capChannelOrPsm = inputStream.nextInt(2); + } + + public int getImageId() { + return imageId; + } + + public int getStartPosition() { + return startPosition; + } + + public int getBlockSize() { + return blockSize; + } + + public int getChunkSize() { + return chunkSize; + } + + public int getTransferMethod() { + return transferMethod; + } + + public int getL2capChannelOrPsm() { + return l2capChannelOrPsm; + } + + @Override + public String toString() { + return "ImageBlockRequest{" + + "imageId=" + imageId + + ", startPosition=" + startPosition + + ", blockSize=" + blockSize + + ", chunkSize=" + chunkSize + + ", transferMethod=" + transferMethod + + ", l2capChannelOrPsm=" + l2capChannelOrPsm + + '}'; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ImageTransferComplete.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ImageTransferComplete.java new file mode 100644 index 0000000..e8a9b7d --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/ImageTransferComplete.java @@ -0,0 +1,53 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap.response; + +import com.wolkabout.hexiwear.util.ByteInputStream; + +public class ImageTransferComplete { + + private final int imageId; + private final int status; // 0 = Success + + public ImageTransferComplete(final byte[] bytes) { + final ByteInputStream inputStream = new ByteInputStream(bytes); + inputStream.nextBytes(1); // Skip command byte + imageId = inputStream.nextInt(2); + status = inputStream.nextInt(1); + } + + public int getImageId() { + return imageId; + } + + public boolean isSuccessful() { + return status == 0; + } + + @Override + public String toString() { + return "ImageTransferComplete{" + + "imageId=" + imageId + + ", status=" + status + + '}'; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/NewImageInfoRequest.java b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/NewImageInfoRequest.java new file mode 100644 index 0000000..9e4d71e --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/model/otap/response/NewImageInfoRequest.java @@ -0,0 +1,54 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.model.otap.response; + +import com.wolkabout.hexiwear.model.otap.ImageVersion; +import com.wolkabout.hexiwear.util.ByteInputStream; + +public class NewImageInfoRequest { + + private final long currentImageId; // Should be 0. + private final ImageVersion currentImageVersion; + + public NewImageInfoRequest(final byte[] bytes) { + final ByteInputStream inputStream = new ByteInputStream(bytes); + inputStream.nextBytes(1); // Skip command byte + currentImageId = inputStream.nextLong(2); + currentImageVersion = new ImageVersion(inputStream.nextBytes(8)); + } + + public long getCurrentImageId() { + return currentImageId; + } + + public ImageVersion getCurrentImageVersion() { + return currentImageVersion; + } + + @Override + public String toString() { + return "NewImageInfoRequest{" + + "currentImageId=" + currentImageId + + ", currentImageVersion=" + currentImageVersion + + '}'; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/service/BluetoothService.java b/android/app/src/main/java/com/wolkabout/hexiwear/service/BluetoothService.java new file mode 100644 index 0000000..6d55f7a --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/service/BluetoothService.java @@ -0,0 +1,555 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.service; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothProfile; +import android.content.Intent; +import android.graphics.Color; +import android.os.Binder; +import android.os.IBinder; +import android.support.v4.app.NotificationCompat; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.activity.MainActivity_; +import com.wolkabout.hexiwear.activity.ReadingsActivity_; +import com.wolkabout.hexiwear.model.Characteristic; +import com.wolkabout.hexiwear.model.HexiwearDevice; +import com.wolkabout.hexiwear.model.ManufacturerInfo; +import com.wolkabout.hexiwear.model.Mode; +import com.wolkabout.hexiwear.util.ByteUtils; +import com.wolkabout.hexiwear.util.DataConverter; +import com.wolkabout.hexiwear.util.HexiwearDevices; +import com.wolkabout.wolk.Logger; +import com.wolkabout.wolk.ReadingType; +import com.wolkabout.wolk.Wolk; +import com.wolkabout.wolkrestandroid.Credentials_; + +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EService; +import org.androidannotations.annotations.Receiver; +import org.androidannotations.annotations.SystemService; +import org.androidannotations.annotations.sharedpreferences.Pref; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.TimeZone; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; + +@EService +public class BluetoothService extends Service { + + private static final String TAG = BluetoothService.class.getSimpleName(); + + public static final String SERVICES_AVAILABLE = "servicesAvailable"; + public static final String DATA_AVAILABLE = "dataAvailable"; + public static final String READING_TYPE = "readingType"; + public static final String CONNECTION_STATE_CHANGED = "ConnectionStateChange"; + public static final String CONNECTION_STATE = "connectionState"; + public static final String STRING_DATA = "stringData"; + public static final String STOP = "stop"; + public static final String ACTION_NEEDS_BOND = "noBond"; + public static final String PREFERENCE_CHANGED = "preferenceChanged"; + public static final String PREFERENCE_NAME = "preferenceName"; + public static final String PREFERENCE_ENABLED = "preferenceEnabled"; + public static final String PUBLISH_TIME_CHANGED = "publishTimeChanged"; + public static final String SHOULD_PUBLISH_CHANGED = "shouldPublishChanged"; + public static final String MODE_CHANGED = "modeChanged"; + public static final String MODE = "mode"; + + // Notification types + private static final byte MISSED_CALLS = 2; + private static final byte UNREAD_MESSAGES = 4; + private static final byte UNREAD_EMAILS = 6; + + // Alert In commands + private static final byte WRITE_NOTIFICATION = 1; + private static final byte WRITE_TIME = 3; + + private static final Map readableCharacteristics = new HashMap<>(); + private static final ManufacturerInfo manufacturerInfo = new ManufacturerInfo(); + private static final Queue readingQueue = new ArrayBlockingQueue<>(12); + private static final Queue notificationsQueue = new LinkedBlockingDeque<>(); + + private volatile boolean isConnected; + private BluetoothDevice bluetoothDevice; + private HexiwearDevice hexiwearDevice; + private BluetoothGattCharacteristic alertIn; + private BluetoothGatt bluetoothGatt; + private Wolk wolk; + private Mode mode; + + @Bean + HexiwearDevices hexiwearDevices; + + @SystemService + NotificationManager notificationManager; + + @Pref + Credentials_ credentials; + + @Receiver(actions = BluetoothDevice.ACTION_BOND_STATE_CHANGED) + void onBondStateChanged(Intent intent) { + final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1); + final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1); + + Log.d(TAG, "Bond state changed for: " + device.getAddress() + " new state: " + bondState + " previous: " + previousBondState); + + if (bondState == BluetoothDevice.BOND_BONDED) { + Log.i(TAG, "Bonded"); + createGATT(device); + } else if (bondState == BluetoothDevice.BOND_NONE) { + device.createBond(); + } + } + + @Receiver(actions = STOP) + void onStopCommand() { + Log.i(TAG, "Stop command received."); + stopForeground(true); + stopSelf(); + } + + @Override + public void onDestroy() { + Log.i(TAG, "Stopping service..."); + if (bluetoothGatt != null) { + bluetoothGatt.close(); + NotificationService_.intent(this).stop(); + } + if (wolk != null && hexiwearDevices.shouldTransmit(hexiwearDevice)) { + wolk.stopAutoPublishing(); + } + } + + public void startReading(BluetoothDevice device) { + Log.i(TAG, "Starting to read data for device: " + device.getName()); + hexiwearDevice = hexiwearDevices.getDevice(device.getAddress()); + bluetoothDevice = device; + createGATT(device); + + if(credentials.username().get().equals("Demo")) { + return; + } + + wolk = new Wolk(hexiwearDevice); + wolk.setLogger(new Logger() { + @Override + public void info(final String message) { + Log.i(TAG, message); + } + + @Override + public void error(final String message, final Throwable e) { + Log.e(TAG, message, e); + } + }); + + if (hexiwearDevices.shouldTransmit(device)) { + final int publishInterval = hexiwearDevices.getPublishInterval(hexiwearDevice); + wolk.startAutoPublishing(publishInterval); + } + } + + private void createGATT(final BluetoothDevice device) { + bluetoothGatt = device.connectGatt(this, true, new BluetoothGattCallback() { + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + isConnected = BluetoothProfile.STATE_CONNECTED == newState; + if (isConnected) { + Log.i(TAG, "GATT connected."); + startForeground(442, getNotification(device)); + gatt.discoverServices(); + } else { + Log.i(TAG, "GATT disconnected."); + NotificationService_.intent(BluetoothService.this).stop(); + notificationManager.notify(442, getNotification(device)); + gatt.connect(); + } + + final Intent connectionStateChanged = new Intent(CONNECTION_STATE_CHANGED); + connectionStateChanged.putExtra(CONNECTION_STATE, isConnected); + sendBroadcast(connectionStateChanged); + } + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + Log.i(TAG, "Services discovered."); + if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) { + handleAuthenticationError(gatt); + return; + } + + discoverCharacteristics(gatt); + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + Log.i(TAG, "Characteristic written: " + status); + + if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) { + handleAuthenticationError(gatt); + return; + } + + final byte command = characteristic.getValue()[0]; + switch (command) { + case WRITE_TIME: + Log.i(TAG, "Time written."); + final BluetoothGattCharacteristic batteryCharacteristic = readableCharacteristics.get(Characteristic.BATTERY.getUuid()); + gatt.setCharacteristicNotification(batteryCharacteristic, true); + for (BluetoothGattDescriptor descriptor : batteryCharacteristic.getDescriptors()) { + if (descriptor.getUuid().toString().startsWith("00002904")) { + descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); + gatt.writeDescriptor(descriptor); + } + } + break; + case WRITE_NOTIFICATION: + Log.i(TAG, "Notification sent."); + if (notificationsQueue.isEmpty()) { + Log.i(TAG, "Reading characteristics..."); + readNextCharacteristics(gatt); + } else { + Log.i(TAG, "writing next notification..."); + alertIn.setValue(notificationsQueue.poll()); + gatt.writeCharacteristic(alertIn); + } + break; + default: + Log.w(TAG, "No such ALERT IN command: " + command); + break; + } + } + + @Override + public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + readCharacteristic(gatt, Characteristic.MANUFACTURER); + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic gattCharacteristic, int status) { + if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) { + handleAuthenticationError(gatt); + return; + } + + final String characteristicUuid = gattCharacteristic.getUuid().toString(); + final Characteristic characteristic = Characteristic.byUuid(characteristicUuid); + switch (characteristic) { + case MANUFACTURER: + manufacturerInfo.manufacturer = gattCharacteristic.getStringValue(0); + readCharacteristic(gatt, Characteristic.FW_REVISION); + break; + case FW_REVISION: + manufacturerInfo.firmwareRevision = gattCharacteristic.getStringValue(0); + readCharacteristic(gatt, Characteristic.MODE); + break; + default: + Log.v(TAG, "Characteristic read: " + characteristic.name()); + if (characteristic == Characteristic.MODE) { + final Mode newMode = Mode.bySymbol(gattCharacteristic.getValue()[0]); + if (mode != newMode) { + onModeChanged(newMode); + } + } else { + onBluetoothDataReceived(characteristic, gattCharacteristic.getValue()); + } + + if (notificationsQueue.isEmpty()) { + readNextCharacteristics(gatt); + } else { + alertIn.setValue(notificationsQueue.poll()); + gatt.writeCharacteristic(alertIn); + } + + break; + } + } + + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic gattCharacteristic) { + final String characteristicUuid = gattCharacteristic.getUuid().toString(); + final Characteristic characteristic = Characteristic.byUuid(characteristicUuid); + Log.d(TAG, "Characteristic changed: " + characteristic); + + if (characteristic == Characteristic.BATTERY) { + onBluetoothDataReceived(Characteristic.BATTERY, gattCharacteristic.getValue()); + } + } + }); + } + + private void onModeChanged(final Mode newMode) { + Log.i(TAG, "Mode changed. New mode is: " + mode); + mode = newMode; + + setReadingQueue(); + + final Intent modeChanged = new Intent(MODE_CHANGED); + modeChanged.putExtra(MODE, newMode); + LocalBroadcastManager.getInstance(this).sendBroadcast(modeChanged); + } + + private void setReadingQueue() { + readingQueue.clear(); + readingQueue.add(Characteristic.MODE.name()); + final List enabledPreferences = hexiwearDevices.getEnabledPreferences(bluetoothDevice.getAddress()); + for (String characteristic : enabledPreferences) { + if (mode.hasCharacteristic(characteristic)) { + readingQueue.add(characteristic); + } + } + } + + @Receiver(actions = PREFERENCE_CHANGED, local = true) + void preferenceChanged(@Receiver.Extra String preferenceName, @Receiver.Extra boolean preferenceEnabled) { + if (!mode.hasCharacteristic(preferenceName)) { + return; + } + + if (preferenceEnabled) { + readingQueue.add(preferenceName); + } else { + readingQueue.remove(preferenceName); + } + } + + @Receiver(actions = PUBLISH_TIME_CHANGED, local = true) + void onPublishTimeChanged() { + if (hexiwearDevices.shouldTransmit(hexiwearDevice)) { + setTracking(false); + setTracking(true); + } + } + + @Receiver(actions = SHOULD_PUBLISH_CHANGED, local = true) + void onShouldPublishChanged() { + setTracking(hexiwearDevices.shouldTransmit(hexiwearDevice)); + } + + @Receiver(actions = NotificationService.MISSED_CALLS_AMOUNT_CHANGED, local = true) + void onMissedCallsAmountChanged(@Receiver.Extra final int value) { + queueNotification(MISSED_CALLS, value); + } + + @Receiver(actions = NotificationService.UNREAD_MESSAGES_AMOUNT_CHANGED, local = true) + void onUnreadMessagesAmountChanged(@Receiver.Extra final int value) { + queueNotification(UNREAD_MESSAGES, value); + } + + @Receiver(actions = NotificationService.UNREAD_EMAILS_AMOUNT_CHANGED, local = true) + void onUnreadEmailAmountChanged(@Receiver.Extra final int value) { + queueNotification(UNREAD_EMAILS, value); + } + + private void queueNotification(final byte type, final int amount) { + final byte[] notification = new byte[20]; + notification[0] = WRITE_NOTIFICATION; + notification[1] = type; + notification[2] = ByteUtils.intToByte(amount); + notificationsQueue.add(notification); + } + + private void onBluetoothDataReceived(final Characteristic type, final byte[] data) { + if (wolk != null && hexiwearDevices.shouldTransmit(hexiwearDevice) && type != Characteristic.BATTERY) { + final ReadingType readingType = ReadingType.valueOf(type.name()); + wolk.addReading(readingType, DataConverter.formatForPublushing(type, data)); + } + + final Intent dataRead = new Intent(DATA_AVAILABLE); + dataRead.putExtra(READING_TYPE, type.getUuid()); + dataRead.putExtra(STRING_DATA, DataConverter.parseBluetoothData(type, data)); + sendBroadcast(dataRead); + } + + void readNextCharacteristics(final BluetoothGatt gatt) { + final String characteristicUuid = readingQueue.poll(); + readingQueue.add(characteristicUuid); + readCharacteristic(gatt, Characteristic.valueOf(characteristicUuid)); + } + + private void readCharacteristic(final BluetoothGatt gatt, final Characteristic characteristic) { + if (!isConnected) { + return; + } + + final BluetoothGattCharacteristic gattCharacteristic = readableCharacteristics.get(characteristic.getUuid()); + if (gattCharacteristic != null) { + gatt.readCharacteristic(gattCharacteristic); + } + } + + private void discoverCharacteristics(final BluetoothGatt gatt) { + if (gatt.getServices().size() == 0) { + Log.i(TAG, "No services found."); + } + + for (BluetoothGattService gattService : gatt.getServices()) { + storeCharacteristicsFromService(gattService); + } + + sendBroadcast(new Intent(SERVICES_AVAILABLE)); + } + + private void storeCharacteristicsFromService(BluetoothGattService gattService) { + for (BluetoothGattCharacteristic gattCharacteristic : gattService.getCharacteristics()) { + final String characteristicUuid = gattCharacteristic.getUuid().toString(); + final Characteristic characteristic = Characteristic.byUuid(characteristicUuid); + + if (characteristic == Characteristic.ALERT_IN) { + Log.d(TAG, "ALERT_IN DISCOVERED"); + alertIn = gattCharacteristic; + setTime(); + NotificationService_.intent(BluetoothService.this).start(); + } else if (characteristic != null) { + Log.v(TAG, characteristic.getType() + ": " + characteristic.name()); + readableCharacteristics.put(characteristicUuid, gattCharacteristic); + } else { + Log.v(TAG, "UNKNOWN: " + characteristicUuid); + } + } + } + + public void setTime() { + Log.d(TAG, "Setting time..."); + if (!isConnected || alertIn == null) { + Log.w(TAG, "Time not set."); + return; + } + + final byte[] time = new byte[20]; + final long currentTime = System.currentTimeMillis(); + final long currentTimeWithTimeZoneOffset = (currentTime + TimeZone.getDefault().getOffset(currentTime)) / 1000; + + final ByteBuffer buffer = ByteBuffer.allocate(8); + buffer.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().put(currentTimeWithTimeZoneOffset); + final byte[] utcBytes = buffer.array(); + + final byte length = 0x04; + + time[0] = WRITE_TIME; + time[1] = length; + time[2] = utcBytes[0]; + time[3] = utcBytes[1]; + time[4] = utcBytes[2]; + time[5] = utcBytes[3]; + + alertIn.setValue(time); + alertIn.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + bluetoothGatt.writeCharacteristic(alertIn); + } + + public void setTracking(final boolean enabled) { + if (enabled) { + final int publishInterval = hexiwearDevices.getPublishInterval(hexiwearDevice); + wolk.startAutoPublishing(publishInterval); + } else { + wolk.stopAutoPublishing(); + } + } + + public boolean isConnected() { + return isConnected; + } + + public Mode getCurrentMode() { + return mode; + } + + public BluetoothDevice getCurrentDevice() { + return bluetoothDevice; + } + + private void handleAuthenticationError(final BluetoothGatt gatt) { + gatt.close(); + sendBroadcast(new Intent(BluetoothService.ACTION_NEEDS_BOND)); + gatt.getDevice().createBond(); + } + + @Override + public IBinder onBind(Intent intent) { + return new ServiceBinder(this); + } + + public ManufacturerInfo getManufacturerInfo() { + return manufacturerInfo; + } + + protected Notification getNotification(final BluetoothDevice device) { + final boolean connectionEstablished = isConnected && bluetoothGatt != null && bluetoothGatt.getDevice() != null; + final String text = connectionEstablished ? "Device is connected to " + hexiwearDevice.getWolkName() : "Device is not connected."; + final int icon = connectionEstablished ? R.drawable.ic_bluetooth_connected_white_48dp : R.drawable.ic_bluetooth_searching_white_48dp; + + final Intent readingsActivityIntent = ReadingsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_SINGLE_TOP).device(device).get(); + final Intent mainActivityIntent = MainActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_SINGLE_TOP).get(); + final Intent launchActivity = connectionEstablished ? readingsActivityIntent : mainActivityIntent; + final PendingIntent pendingIntentMain = PendingIntent.getActivity(this, 71, launchActivity, PendingIntent.FLAG_UPDATE_CURRENT); + + final Intent stopIntent = new Intent(STOP); + final PendingIntent pendingStopIntent = PendingIntent.getBroadcast(this, 0, stopIntent, 0); + + return new NotificationCompat.Builder(this) + .setSmallIcon(icon) + .setContentTitle(getResources().getString(R.string.app_name)) + .setContentIntent(pendingIntentMain) + .setLights(Color.GREEN, 100, 5000) + .addAction(R.drawable.ic_cloud_off_black_24dp, "Stop", pendingStopIntent) + .setContentText(text).build(); + } + + @Override + public void sendBroadcast(Intent intent) { + LocalBroadcastManager.getInstance(this).sendBroadcast(intent); + } + + public class ServiceBinder extends Binder { + + private BluetoothService service; + + public ServiceBinder(BluetoothService service) { + this.service = service; + } + + public BluetoothService getService() { + return service; + } + + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/service/DeviceDiscoveryService.java b/android/app/src/main/java/com/wolkabout/hexiwear/service/DeviceDiscoveryService.java new file mode 100644 index 0000000..df1dd0c --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/service/DeviceDiscoveryService.java @@ -0,0 +1,171 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.service; + +import android.annotation.TargetApi; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.le.ScanCallback; +import android.bluetooth.le.ScanResult; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; + +import com.wolkabout.hexiwear.model.BluetoothDeviceWrapper; + +import org.androidannotations.annotations.AfterInject; +import org.androidannotations.annotations.Background; +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.RootContext; +import org.androidannotations.api.BackgroundExecutor; +import org.parceler.Parcels; + +@EBean +public class DeviceDiscoveryService { + + private static final String TAG = DeviceDiscoveryService.class.getSimpleName(); + + private static final long SCAN_PERIOD = 5000; + private static final String SCAN_TASK = "scan"; + private static final String HEXIWEAR_TAG = "hexiwear"; + private static final String HEXI_OTAP_TAG = "hexiotap"; + + public static final String SCAN_STARTED = "scanStarted"; + public static final String SCAN_STOPPED = "scanStopped"; + public static final String DEVICE_DISCOVERED = "deviceDiscovered"; + public static final String WRAPPER = "wrapper"; + + private static final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + + @RootContext + Context context; + + private static ScanCallback lolipopScanCallback; + private static BluetoothAdapter.LeScanCallback kitKatScanCallback; + + @AfterInject + void checkEnabled() { + isEnabled(); + } + + public void startScan() { + if (!isEnabled()) { + return; + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + startKitKatScan(); + } else { + startLolipopScan(); + } + + setScanTimeLimit(); + sendBroadcast(new Intent(SCAN_STARTED)); + Log.i(TAG, "Bluetooth device discovery started."); + } + + @SuppressWarnings("deprecation") + @TargetApi(Build.VERSION_CODES.KITKAT) + public void startKitKatScan() { + kitKatScanCallback = new BluetoothAdapter.LeScanCallback() { + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + final BluetoothDeviceWrapper wrapper = new BluetoothDeviceWrapper(); + wrapper.setDevice(device); + wrapper.setSignalStrength(rssi); + onDeviceDiscovered(wrapper); + } + }; + bluetoothAdapter.startLeScan(kitKatScanCallback); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private void startLolipopScan() { + lolipopScanCallback = new ScanCallback() { + @Override + public void onScanResult(int callbackType, ScanResult result) { + super.onScanResult(callbackType, result); + final BluetoothDeviceWrapper wrapper = new BluetoothDeviceWrapper(); + wrapper.setDevice(result.getDevice()); + wrapper.setSignalStrength(result.getRssi()); + onDeviceDiscovered(wrapper); + } + }; + bluetoothAdapter.getBluetoothLeScanner().startScan(lolipopScanCallback); + } + + private void onDeviceDiscovered(final BluetoothDeviceWrapper wrapper) { + final BluetoothDevice device = wrapper.getDevice(); + Log.i(TAG, "Discovered device: " + device.getName() + "(" + device.getAddress() + ")"); + final String name = wrapper.getDevice().getName(); + if (HEXI_OTAP_TAG.equalsIgnoreCase(name)) { + wrapper.setInOtapMode(true); + } else if (!HEXIWEAR_TAG.equalsIgnoreCase(name)) { + return; + } + + final Intent deviceDiscovered = new Intent(DEVICE_DISCOVERED); + deviceDiscovered.putExtra(WRAPPER, Parcels.wrap(wrapper)); + sendBroadcast(deviceDiscovered); + } + + @Background(id = SCAN_TASK, delay = SCAN_PERIOD) + void setScanTimeLimit() { + cancelScan(); + } + + @SuppressWarnings("deprecation") + public void cancelScan() { + if (!isEnabled()) { + return; + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + bluetoothAdapter.stopLeScan(kitKatScanCallback); + } else { + bluetoothAdapter.getBluetoothLeScanner().stopScan(lolipopScanCallback); + } + + sendBroadcast(new Intent(SCAN_STOPPED)); + Log.i(TAG, "Bluetooth device discovery canceled"); + BackgroundExecutor.cancelAll(SCAN_TASK, true); + } + + boolean isEnabled() { + if (bluetoothAdapter == null) { + Log.e(TAG, "Bluetooth not supported"); + return false; + } else if (!bluetoothAdapter.isEnabled()) { + context.startActivity(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)); + return false; + } else { + Log.v(TAG, "Bluetooth is enabled and functioning properly."); + return true; + } + } + + private void sendBroadcast(Intent intent) { + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/service/DeviceRegistrationService.java b/android/app/src/main/java/com/wolkabout/hexiwear/service/DeviceRegistrationService.java new file mode 100644 index 0000000..7493d70 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/service/DeviceRegistrationService.java @@ -0,0 +1,169 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.service; + +import android.app.AlertDialog; +import android.bluetooth.BluetoothDevice; +import android.content.Context; +import android.content.DialogInterface; +import android.util.Log; +import android.widget.Toast; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.activity.ReadingsActivity_; +import com.wolkabout.hexiwear.model.HexiwearDevice; +import com.wolkabout.hexiwear.util.HexiwearDevices; +import com.wolkabout.hexiwear.view.DeviceActivation; +import com.wolkabout.hexiwear.view.DeviceActivation_; +import com.wolkabout.wolkrestandroid.Credentials_; +import com.wolkabout.wolkrestandroid.dto.CreatePointBodyDTO; +import com.wolkabout.wolkrestandroid.dto.CreatedPointDto; +import com.wolkabout.wolkrestandroid.dto.PointWithFeedsResponse; +import com.wolkabout.wolkrestandroid.dto.SerialDto; +import com.wolkabout.wolkrestandroid.enumeration.SensorType; +import com.wolkabout.wolkrestandroid.service.DeviceService; +import com.wolkabout.wolkrestandroid.service.PointService; + +import org.androidannotations.annotations.Background; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.RootContext; +import org.androidannotations.annotations.UiThread; +import org.androidannotations.annotations.sharedpreferences.Pref; +import org.androidannotations.rest.spring.annotations.RestService; + +import java.util.ArrayList; +import java.util.List; + +@EBean +public class DeviceRegistrationService { + + private static final String TAG = DeviceRegistrationService.class.getSimpleName(); + + @RootContext + Context context; + + @Pref + Credentials_ credentials; + + @Bean + HexiwearDevices devicesStore; + + @RestService + DeviceService deviceService; + + @RestService + PointService pointService; + + @Background + public void registerHexiwearDevice(final BluetoothDevice device) { + if (credentials.username().get().equals("Demo")) { + final int demoNumber = devicesStore.getDevices().size() + 1; + final HexiwearDevice hexiwearDevice = new HexiwearDevice(device.getName(), "", device.getAddress(), "", "Demo device " + demoNumber); + devicesStore.storeDevice(hexiwearDevice); + ReadingsActivity_.intent(context).device(device).start(); + } + + final SerialDto serialDto = deviceService.getRandomSerial(SensorType.HEXIWEAR); + final String serial = serialDto.getSerial(); + getDevices(device, serial); + } + + @Background + void getDevices(final BluetoothDevice device, final String serial) { + final List points = pointService.getPoints(); + final List hexiwearDevices = HexiwearDevices.getDevices(points); + displayActivationDialog(device, serial, hexiwearDevices); + } + + @UiThread + void displayActivationDialog(final BluetoothDevice device, final String serial, final List hexiwearDevices) { + final DeviceActivation view = DeviceActivation_.build(context); + view.setDevices(hexiwearDevices); + + final AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setView(view); + builder.setMessage(R.string.activation_dialog_title); + builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + //dialog.cancel(); + } + }); + builder.setPositiveButton(R.string.activation_dialog_confirm, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final String wolkName = view.getWolkName(); + if (view.isNewDeviceSelected()) { + Log.d(TAG, "New device selected. Activating..."); + registerHexiwearDevice(device, serial, wolkName); + } else { + deactivateDeviceAndRegister(device, serial, wolkName, view.getDeviceSerial()); + } + } + }); + builder.show(); + } + + @Background + void deactivateDeviceAndRegister(final BluetoothDevice device, final String serial, final String wolkName, String existingDeviceSerial) { + try { + Log.d(TAG, "Deactivating existing device..."); + deviceService.deactivateDevice(existingDeviceSerial); + Log.d(TAG, "Deactivated."); + registerHexiwearDevice(device, serial, wolkName); + } catch (Exception e) { + onDeactivateError(); + } + } + + @UiThread + void onDeactivateError() { + Toast.makeText(context, "Failed to activate as exiting device", Toast.LENGTH_LONG).show(); + } + + @Background + void registerHexiwearDevice(final BluetoothDevice device, final String serial, final String wolkName) { + Log.d(TAG, "Registering hexiwear device."); + final CreatePointBodyDTO bodyDto = new CreatePointBodyDTO(wolkName, "", "T:ON,P:ON,H:ON"); + final ArrayList bodyDtos = new ArrayList<>(); + bodyDtos.add(bodyDto); + final List response = deviceService.createPointWithThings(serial, bodyDtos); + if (!response.isEmpty()) { + final String name = device.getName(); + final String address = device.getAddress(); + final String password = response.get(0).getPassword(); + final HexiwearDevice hexiwearDevice = new HexiwearDevice(name, serial, address, password, wolkName); + devicesStore.storeDevice(hexiwearDevice); + Log.d(TAG, "Hexiwear registered." + hexiwearDevice); + + ReadingsActivity_.intent(context).device(device).start(); + } else { + onRegistrationError(); + } + } + + @UiThread + void onRegistrationError() { + Toast.makeText(context, "Failed to activate device.", Toast.LENGTH_LONG).show(); + Log.e(TAG, "Registration failed"); + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/service/FirmwareUpdateService.java b/android/app/src/main/java/com/wolkabout/hexiwear/service/FirmwareUpdateService.java new file mode 100644 index 0000000..929556c --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/service/FirmwareUpdateService.java @@ -0,0 +1,298 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.service; + +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothProfile; +import android.content.Intent; +import android.graphics.Color; +import android.os.Binder; +import android.os.IBinder; +import android.support.annotation.Nullable; +import android.support.v4.app.NotificationCompat; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.model.Characteristic; +import com.wolkabout.hexiwear.model.otap.Command; +import com.wolkabout.hexiwear.model.otap.Image; +import com.wolkabout.hexiwear.model.otap.ImageBlock; +import com.wolkabout.hexiwear.model.otap.response.ErrorNotification; +import com.wolkabout.hexiwear.model.otap.response.ImageBlockRequest; +import com.wolkabout.hexiwear.model.otap.response.ImageTransferComplete; +import com.wolkabout.hexiwear.util.ByteUtils; + +import org.androidannotations.annotations.EService; +import org.androidannotations.annotations.Receiver; +import org.androidannotations.annotations.SystemService; + +import java.util.UUID; + +@EService +public class FirmwareUpdateService extends Service { + + public static final String UPDATE_INITIATED = "updateStarted"; + public static final String UPDATE_CANCELED = "updateCanceled"; + public static final String UPDATE_FINISHED = "updateFinished"; + public static final String UPDATE_ERROR = "updateError"; + public static final String UPDATE_PROGRESS = "updateProgress"; + public static final String UPDATE_PROGRESS_VALUE = "progress"; + public static final String CANCEL_UPDATE = "cancelUpdate"; + + private static final String TAG = FirmwareUpdateService.class.getSimpleName(); + private static final int NOTIFICATION_ID = 1; + + @SystemService + static NotificationManager notificationManager; + + private static NotificationCompat.Builder notificationBuilder; + private static BluetoothGatt bluetoothGatt; + + @Override + public int onStartCommand(final Intent intent, final int flags, final int startId) { + return START_STICKY; + } + + @Nullable + @Override + public IBinder onBind(final Intent intent) { + return new ServiceBinder(this); + } + + public void updateFirmware(final BluetoothDevice device, final Image image) { + notificationBuilder = new NotificationCompat.Builder(this) + .setSmallIcon(R.drawable.ic_bluetooth_connected_white_48dp) + .setContentTitle(getResources().getString(R.string.app_name)) + .setLights(Color.GREEN, 100, 5000); + startForeground(NOTIFICATION_ID, notificationBuilder.build()); + + bluetoothGatt = device.connectGatt(this, true, new FirmwareUpdater(image)); + } + + @Receiver(actions = CANCEL_UPDATE) + public void cancelUpdate() { + sendBroadcast(UPDATE_CANCELED); + stopService(); + } + + private void stopService() { + if (bluetoothGatt != null) { + bluetoothGatt.close(); + } + stopForeground(true); + stopSelf(); + } + + private void sendBroadcast(final String event) { + sendBroadcast(new Intent(event)); + } + + public void sendBroadcast(final Intent intent) { + LocalBroadcastManager.getInstance(this).sendBroadcast(intent); + } + + private class FirmwareUpdater extends BluetoothGattCallback { + + private static final String OTAP_SERVICE_UUID = "01ff5550-ba5e-f4ee-5ca1-eb1e5e4b1ce0"; + private static final String CONTROL_POINT_DESCRIPTOR_UUID = "00002902-0000-1000-8000-00805f9b34fb"; + + private final Image image; + + private BluetoothGattCharacteristic controlPoint; + private BluetoothGattCharacteristic data; + private BluetoothGattCharacteristic state; + + private ImageBlock currentBlock; + + public FirmwareUpdater(final Image image) { + this.image = image; + } + + @Override + public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) { + if (BluetoothProfile.STATE_CONNECTED == newState) { + Log.i(TAG, "GATT connected."); + gatt.discoverServices(); + } else { + Log.i(TAG, "GATT disconnected."); + gatt.connect(); + } + } + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + Log.i(TAG, "Services discovered."); + if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) { + gatt.disconnect(); + gatt.getDevice().createBond(); + return; + } + + // Get GATT characteristics from the device. + final BluetoothGattService otapService = gatt.getService(UUID.fromString(OTAP_SERVICE_UUID)); + controlPoint = otapService.getCharacteristic(UUID.fromString(Characteristic.CONTROL_POINT.getUuid())); + data = otapService.getCharacteristic(UUID.fromString(Characteristic.DATA.getUuid())); + state = otapService.getCharacteristic(UUID.fromString(Characteristic.STATE.getUuid())); + + gatt.readCharacteristic(state); + } + + @Override + public void onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) { + if (characteristic != state) { + return; + } + + final int value = ByteUtils.parseInt(characteristic.getValue()); + if (value == 0) { + Log.e(TAG, "OTAP mode is not enabled."); + return; + } + + final boolean wrongModeForMK64 = value == 1 && image.getType() == Image.Type.MK64; + final boolean wrongModeForKW40 = value == 2 && image.getType() == Image.Type.KW40; + if (wrongModeForMK64 || wrongModeForKW40) { + Log.e(TAG, "Wrong OTAP mode for the selected image."); + sendBroadcast(UPDATE_ERROR); + return; + } + + Log.i(TAG, "The device is in the correct OTAP mode. Starting communication."); + + gatt.setCharacteristicNotification(controlPoint, true); + + final BluetoothGattDescriptor descriptor = controlPoint.getDescriptor(UUID.fromString(CONTROL_POINT_DESCRIPTOR_UUID)); + gatt.readDescriptor(descriptor); + } + + @Override + public void onDescriptorRead(final BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, final int status) { + descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); + gatt.writeDescriptor(descriptor); + } + + @Override + public void onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) { + final byte[] value = characteristic.getValue(); + final Command command = Command.byCommandByte(value[0]); + Log.i(TAG, "Received command: " + command); + switch (command) { + case NEW_IMAGE_INFO_REQUEST: + controlPoint.setValue(image.getNewImageInfoResponse()); + gatt.writeCharacteristic(controlPoint); + Log.i(TAG, "Writing command: NEW_IMAGE_INFO_RESPONSE"); + final PendingIntent pendingIntent = PendingIntent.getBroadcast(FirmwareUpdateService.this, 0, new Intent(CANCEL_UPDATE), 0); + notificationBuilder.addAction(R.drawable.ic_clear_white_24dp, getString(R.string.firmware_update_cancel), pendingIntent); + setNotificationText(R.string.firmware_update_start); + sendBroadcast(UPDATE_INITIATED); + break; + case IMAGE_BLOCK_REQUEST: + final ImageBlockRequest imageBlockRequest = new ImageBlockRequest(value); + Log.i(TAG, "Block request is: " + imageBlockRequest); + currentBlock = image.getBlock(imageBlockRequest); + setProgress(imageBlockRequest.getStartPosition()); + writeChunk(gatt); + break; + case IMAGE_TRANSFER_COMPLETE: + final ImageTransferComplete imageTransferComplete = new ImageTransferComplete(value); + Log.i(TAG, "Image transfer completed: " + imageTransferComplete); + setNotificationText(R.string.firmware_update_complete); + sendBroadcast(UPDATE_FINISHED); + stopService(); + break; + case ERROR_NOTIFICATION: + final ErrorNotification errorNotification = new ErrorNotification(value); + Log.e(TAG, "Error during firmware update: " + errorNotification); + setNotificationText(R.string.firmware_update_error); + sendBroadcast(UPDATE_ERROR); + stopService(); + break; + default: + break; + } + } + + @Override + public void onCharacteristicWrite(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) { + if (characteristic == controlPoint) { + Log.i(TAG, "Successfully written to control point."); + } else if (characteristic == data && !currentBlock.isCompleted()) { + writeChunk(gatt); + } + } + + private synchronized void writeChunk(BluetoothGatt gatt) { + // The first block will block and stop OTAP if the chunks are sent too fast. + try { + wait(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + Log.v(TAG, "Writing chunk " + currentBlock.getPosition() + " / " + currentBlock.getNumberOfChunks()); + data.setValue(currentBlock.getNextChunk()); + gatt.writeCharacteristic(data); + } + + private void setProgress(final int value) { + notificationBuilder.setContentText(getString(R.string.firmware_update_notification_text)); + final int progress = (int)(((double)value / image.getSize()) * 100); + notificationBuilder.setProgress(100, progress, false); + notificationBuilder.setOngoing(true); + notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); + + final Intent progressUpdated = new Intent(UPDATE_PROGRESS); + progressUpdated.putExtra(UPDATE_PROGRESS_VALUE, progress); + sendBroadcast(progressUpdated); + } + + private void setNotificationText(final int stringResource) { + notificationBuilder.setContentText(FirmwareUpdateService.this.getString(stringResource)); + notificationBuilder.setProgress(0, 0, false); + notificationBuilder.setOngoing(false); + notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); + } + } + + public class ServiceBinder extends Binder { + + private FirmwareUpdateService service; + + public ServiceBinder(final FirmwareUpdateService service) { + this.service = service; + } + + public FirmwareUpdateService getService() { + return service; + } + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/service/NotificationService.java b/android/app/src/main/java/com/wolkabout/hexiwear/service/NotificationService.java new file mode 100644 index 0000000..de91cab --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/service/NotificationService.java @@ -0,0 +1,184 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.service; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.app.Service; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.ContentObserver; +import android.database.Cursor; +import android.net.Uri; +import android.os.Handler; +import android.os.IBinder; +import android.provider.CallLog; +import android.support.annotation.Nullable; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; + +import org.androidannotations.annotations.AfterInject; +import org.androidannotations.annotations.Background; +import org.androidannotations.annotations.EService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@EService +public class NotificationService extends Service { + + public static final String MISSED_CALLS_AMOUNT_CHANGED = "missedCallsAmountChanged"; + public static final String UNREAD_MESSAGES_AMOUNT_CHANGED = "unreadMessagesAmountChanged"; + public static final String UNREAD_EMAILS_AMOUNT_CHANGED = "unreadEmailsAmountChanged"; + public static final String VALUE = "value"; + + private static final String TAG = NotificationService.class.getSimpleName(); + private static final int UNREAD_EMAILS_COLUMN_NUMBER = 5; + + private final List contentObservers = new ArrayList<>(); + private final Map unreadEmailCounts = new HashMap<>(); + private int numberOfMissedCalls = -1; + private int numberOfUnreadMessages = -1; + + @Override + public void onDestroy() { + Log.i(TAG, "Shutting down. Unregistering all observers..."); + for (ContentObserver contentObserver : contentObservers) { + getContentResolver().unregisterContentObserver(contentObserver); + } + contentObservers.clear(); + super.onDestroy(); + } + + @AfterInject + void setMissedCallObserver() { + if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { + return; + } + + checkMissedCallsCount(); + final ContentObserver contentObserver = new ContentObserver(new Handler()) { + public void onChange(boolean selfChange) { + checkMissedCallsCount(); + } + }; + Log.i(TAG, "Observing missed calls."); + contentObservers.add(contentObserver); + getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, contentObserver); + } + + @Background + void checkMissedCallsCount() { + final Cursor cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, CallLog.Calls.TYPE + " = ? AND " + CallLog.Calls.NEW + " = ?", new String[]{Integer.toString(CallLog.Calls.MISSED_TYPE), "1"}, CallLog.Calls.DATE + " DESC "); + if (cursor != null) { + final int count = cursor.getCount(); + if (numberOfMissedCalls != count) { + numberOfMissedCalls = count; + Log.d(TAG, "Missed calls: " + count); + notifyValueChanged(MISSED_CALLS_AMOUNT_CHANGED, count); + } + cursor.close(); + } + } + + @AfterInject + void setUnreadMessageObserver() { + if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { + return; + } + + checkUnreadMessageCount(); + final ContentObserver contentObserver = new ContentObserver(new Handler()) { + public void onChange(boolean selfChange) { + checkUnreadMessageCount(); + } + }; + Log.i(TAG, "Observing unread messages."); + contentObservers.add(contentObserver); + getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, contentObserver); + } + + @Background + void checkUnreadMessageCount() { + final Cursor cursor = getContentResolver().query(Uri.parse("content://sms/"), null, "read = 0", null, null); + if (cursor != null) { + final int count = cursor.getCount(); + if (numberOfUnreadMessages != count) { + numberOfUnreadMessages = count; + Log.d(TAG, "Unread messages: " + count); + notifyValueChanged(UNREAD_MESSAGES_AMOUNT_CHANGED, count); + } + cursor.close(); + } + } + + @AfterInject + void setUnreadEmailsObserver() { + final Account[] accounts = AccountManager.get(this).getAccounts(); + for (final Account account : accounts) { + unreadEmailCounts.put(account.name, -1); + checkUnreadEmailCount(account); + final ContentObserver contentObserver = new ContentObserver(new Handler()) { + public void onChange(boolean selfChange) { + checkUnreadEmailCount(account); + } + }; + Log.i(TAG, "Observing unread emails for " + account.name); + contentObservers.add(contentObserver); + getContentResolver().registerContentObserver(getEmailQuery(account), true, contentObserver); + } + } + + @Background + void checkUnreadEmailCount(Account account) { + final Cursor cursor = getContentResolver().query(getEmailQuery(account), null, null, null, null); + if (cursor != null) { + if (cursor.moveToFirst()) { + final int count = cursor.getInt(UNREAD_EMAILS_COLUMN_NUMBER); + if (unreadEmailCounts.get(account.name) != count) { + unreadEmailCounts.put(account.name, cursor.getInt(5)); + Log.d(TAG, "Unread emails: " + count); + notifyValueChanged(UNREAD_EMAILS_AMOUNT_CHANGED, count); + } + } + cursor.close(); + } + } + + private Uri getEmailQuery(final Account account) { + return Uri.parse("content://com.google.android.gm/" + account.name + "/labels"); + } + + private void notifyValueChanged(final String type, final int newValue) { + final Intent valueChanged = new Intent(type); + valueChanged.putExtra(VALUE, newValue); + LocalBroadcastManager.getInstance(this).sendBroadcast(valueChanged); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/util/ByteInputStream.java b/android/app/src/main/java/com/wolkabout/hexiwear/util/ByteInputStream.java new file mode 100644 index 0000000..0718087 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/util/ByteInputStream.java @@ -0,0 +1,85 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.util; + + +public class ByteInputStream { + + private static final String NUMBER_ARRAY_DELIMITER = "."; + + private final byte[] bytes; + + private int position = 0; + + public ByteInputStream(final byte[] bytes) { + this.bytes = bytes; + } + + public ByteInputStream(final byte[] bytes, final int offset) { + this.bytes = bytes; + position = offset; + } + + public long nextLong(final int length) { + final byte[] bytes = nextBytes(length); + return ByteUtils.parseLong(bytes); + } + + public int nextInt(final int length) { + if (length > 4) { + throw new IllegalArgumentException("Integer value can be changed during conversion."); + } + + final byte[] bytes = nextBytes(length); + return (int) ByteUtils.parseLong(bytes); + } + + public String nextString(final int length) { + final byte[] bytes = nextBytes(length); + return ByteUtils.parseString(bytes); + } + + public String nextNumberArray(final int arrayLength, final int numberLength) { + final StringBuilder numberArray = new StringBuilder(); + for (int i = 0; i < arrayLength; i++) { + numberArray.append(nextInt(numberLength)); + if (i != arrayLength - 1) { + numberArray.append(NUMBER_ARRAY_DELIMITER); + } + } + return numberArray.toString(); + } + + public byte[] nextBytes(final int length) { + final byte[] subArray = new byte[length]; + System.arraycopy(bytes, position, subArray, 0, length); + position += length; + return subArray; + } + + public byte[] remainingBytes() { + final byte[] remainingBytes = new byte[bytes.length - position]; + System.arraycopy(bytes, position, remainingBytes, 0, remainingBytes.length); + return remainingBytes; + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/util/ByteUtils.java b/android/app/src/main/java/com/wolkabout/hexiwear/util/ByteUtils.java new file mode 100644 index 0000000..b41c2c4 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/util/ByteUtils.java @@ -0,0 +1,99 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.util; + +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; + +public class ByteUtils { + + private static final String TAG = ByteUtils.class.getSimpleName(); + private static final String CHARSET_NAME = "ISO646-US"; // ASCII + + private ByteUtils() { + // Not meant to be instantiated. + } + + public static int parseInt(final byte[] bytes) { + if (bytes.length > 4) { + throw new IllegalArgumentException("The integer value might change during conversion."); + } + + return (int) parseLong(bytes); + } + + public static long parseLong(final byte[] bytes) { + long value = 0; + for (int i = bytes.length - 1; i >= 0; i--) { + final byte aByte = bytes[i]; + value = (value << 8) + (aByte & 0xff); + } + return value; + } + + public static String parseString(final byte[] bytes) { + try { + return new String(bytes, CHARSET_NAME); + } catch (UnsupportedEncodingException e) { + Log.e(TAG, "Unsupported charset " + CHARSET_NAME, e); + return null; + } + } + + public static byte[] readBytes(final File file) { + final byte[] data = new byte[(int) file.length()]; + try { + final FileInputStream fileInputStream = new FileInputStream(file); + fileInputStream.read(data); + } catch (Exception e) { + Log.e(TAG, "Error reading file: " + file.getName(), e); + } + return data; + } + + public static byte[] readBytes(final InputStream inputStream) { + final ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); + + final byte[] buffer = new byte[1024]; + + try { + int length; + while ((length = inputStream.read(buffer)) != -1) { + byteBuffer.write(buffer, 0, length); + } + } catch (Exception e) { + Log.e(TAG, "Couldn't convert input stream to bytes.", e); + } + + return byteBuffer.toByteArray(); + } + + public static byte intToByte(final int value){ + return ByteBuffer.allocate(4).putInt(value).array()[3]; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/util/DataConverter.java b/android/app/src/main/java/com/wolkabout/hexiwear/util/DataConverter.java new file mode 100644 index 0000000..f5fceac --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/util/DataConverter.java @@ -0,0 +1,140 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.util; + +import com.wolkabout.hexiwear.model.Characteristic; + +import java.util.Locale; + +public class DataConverter { + + private static final String INTEGER = "%d"; + private static final String FLOAT = "%.0f"; + private static final String TRIPLE_VALUE = "%+.0f%+.0f%+.0f"; + + private DataConverter() { + // Not meant to be instantiated. + } + + public static String parseBluetoothData(final Characteristic characteristic, final byte[] data) { + if (data == null || data.length == 0) return ""; + + float floatVal; + float xfloatVal; + float yfloatVal; + float zfloatVal; + + final String unit = characteristic.getUnit(); + + switch (characteristic) { + case HEARTRATE: + case BATTERY: + case LIGHT: + case CALORIES: + case STEPS: + floatVal = (data[0] & 0xff); + return String.format("%.0f %s", floatVal, unit); + case TEMPERATURE: + case HUMIDITY: + case PRESSURE: + final int intVal = (data[1] << 8) & 0xff00 | (data[0] & 0xff); + floatVal = (float) intVal / 100; + return String.format("%.2f %s", floatVal, unit); + case ACCELERATION: + case MAGNET: + final int xintVal = ((int) data[1] << 8) | (data[0] & 0xff); + xfloatVal = (float) xintVal / 100; + + final int yintVal = ((int) data[3] << 8) | (data[2] & 0xff); + yfloatVal = (float) yintVal / 100; + + final int zintVal = ((int) data[5] << 8) | (data[4] & 0xff); + zfloatVal = (float) zintVal / 100; + + return String.format("%.2f %s;%.2f %s;%.2f %s", xfloatVal, unit, yfloatVal, unit, zfloatVal, unit); + case GYRO: + final int gyroXintVal = ((int) data[1] << 8) | (data[0] & 0xff); + xfloatVal = (float) gyroXintVal; + + final int gyroYintVal = ((int) data[3] << 8) | (data[2] & 0xff); + yfloatVal = (float) gyroYintVal; + + final int gyroZintVal = ((int) data[5] << 8) | (data[4] & 0xff); + zfloatVal = (float) gyroZintVal; + + return String.format("%.2f %s;%.2f %s;%.2f %s", xfloatVal, unit, yfloatVal, unit, zfloatVal, unit); + default: + return "Unknown"; + } + } + + public static String formatForPublushing(final Characteristic characteristic, final byte[] data) { + if (data == null || data.length == 0) return ""; + + switch (characteristic) { + case HEARTRATE: + case LIGHT: + case BATTERY: + case CALORIES: + final int heartRate = (data[0] & 0xff); + return format(INTEGER, heartRate); + case STEPS: + case TEMPERATURE: + case HUMIDITY: + final int intVal = (data[1] << 8) & 0xff00 | (data[0] & 0xff); + final float floatVal = (float) intVal / 10; + return format(FLOAT, floatVal); + case PRESSURE: + final int pressureVal = (data[1] << 8) & 0xff00 | (data[0] & 0xff); + return format(INTEGER, pressureVal); + case ACCELERATION: + case MAGNET: + final int xintVal = ((int) data[1] << 8) | (data[0] & 0xff); + final float xfloatVal = (float) xintVal / 10; + + final int yintVal = ((int) data[3] << 8) | (data[2] & 0xff); + final float yfloatVal = (float) yintVal / 10; + + final int zintVal = ((int) data[5] << 8) | (data[4] & 0xff); + final float zfloatVal = (float) zintVal / 10; + return format(TRIPLE_VALUE, xfloatVal, yfloatVal, zfloatVal); + case GYRO: + final int gyroXintVal = ((int) data[1] << 8) | (data[0] & 0xff); + final float gyroXfloatVal = (float) gyroXintVal * 10; + + final int gyroYintVal = ((int) data[3] << 8) | (data[2] & 0xff); + final float gyroYfloatVal = (float) gyroYintVal * 10; + + final int gyroZintVal = ((int) data[5] << 8) | (data[4] & 0xff); + + final float gyroZfloatVal = (float) gyroZintVal * 10; + return format(TRIPLE_VALUE, gyroXfloatVal, gyroYfloatVal, gyroZfloatVal); + default: + return "Unknown"; + } + } + + private static String format(final String type, final Object... values) { + return String.format(Locale.ENGLISH, type, values); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/util/Dialog.java b/android/app/src/main/java/com/wolkabout/hexiwear/util/Dialog.java new file mode 100644 index 0000000..d065f60 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/util/Dialog.java @@ -0,0 +1,69 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.util; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.view.Input; + +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.RootContext; +import org.androidannotations.annotations.UiThread; + + +@EBean +public class Dialog { + + @RootContext + Activity activity; + + @UiThread + public void showWarning(final int stringResource){ + final AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setPositiveButton(activity.getString(R.string.dismiss), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + } + }); + builder.setMessage(activity.getString(stringResource)); + builder.show(); + } + + @UiThread + public void showInfo(final int stringResource, final boolean finishActivity){ + final AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setPositiveButton(activity.getString(R.string.ok), new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int which) { + if (finishActivity) { + activity.finish(); + } + } + }); + builder.setMessage(activity.getString(stringResource)); + builder.show(); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/util/HexiwearDevices.java b/android/app/src/main/java/com/wolkabout/hexiwear/util/HexiwearDevices.java new file mode 100644 index 0000000..a7bc7ac --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/util/HexiwearDevices.java @@ -0,0 +1,191 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.util; + +import android.bluetooth.BluetoothDevice; +import android.content.Context; +import android.content.SharedPreferences; + +import com.wolkabout.hexiwear.model.Characteristic; +import com.wolkabout.hexiwear.model.HexiwearDevice; +import com.wolkabout.wolkrestandroid.Credentials_; +import com.wolkabout.wolkrestandroid.dto.PointWithFeedsResponse; + +import org.androidannotations.annotations.AfterInject; +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.RootContext; +import org.androidannotations.annotations.sharedpreferences.Pref; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@EBean(scope = EBean.Scope.Singleton) +public class HexiwearDevices { + + private static final String NAME_SUFFIX = "_deviceName"; + private static final String SERIAL_SUFFIX = "_deviceSerial"; + private static final String PASSWORD_SUFFIX = "_devicePassword"; + private static final String WOLK_NAME_SUFFIX = "_wolkName"; + private static final String SHOULD_TRANSMIT_SUFFIX = "_shouldTransmit"; + private static final String PUBLISH_INTERVAL_SUFFIX = "_publishInterval"; + private static final String KEEP_ALIVE_SUFFIX = "_keepAlive"; + + private SharedPreferences preferences; + private String account; + + @Pref + Credentials_ credentials; + + @RootContext + Context context; + + @AfterInject + public void init() { + account = credentials.username().get(); + preferences = context.getSharedPreferences("HEX_" + account, Context.MODE_PRIVATE); + } + + public Set getDevices() { + final Set devices = new HashSet<>(); + final Set addresses = preferences.getStringSet(account, new HashSet()); + for (String address : addresses) { + final String name = preferences.getString(address + NAME_SUFFIX, ""); + final String serial = preferences.getString(address + SERIAL_SUFFIX, ""); + final String password = preferences.getString(address + PASSWORD_SUFFIX, ""); + final String wolkName = preferences.getString(address + WOLK_NAME_SUFFIX, ""); + + final HexiwearDevice device = new HexiwearDevice(name, serial, address, password, wolkName); + devices.add(device); + } + return devices; + } + + public HexiwearDevice getDevice(String address) { + final Set hexiwearDevices = getDevices(); + for (HexiwearDevice device : hexiwearDevices) { + if (device.getDeviceAddress().equalsIgnoreCase(address)) { + return device; + } + } + return null; + } + + public boolean isRegistered(BluetoothDevice device) { + return getDevice(device.getAddress()) != null; + } + + public void storeDevice(HexiwearDevice hexiwearDevice) { + final SharedPreferences.Editor editor = preferences.edit(); + final Set addresses = preferences.getStringSet(account, new HashSet()); + final String address = hexiwearDevice.getDeviceAddress(); + addresses.add(address); + editor.putStringSet(account, addresses); + editor.putString(address + NAME_SUFFIX, hexiwearDevice.getDeviceName()); + editor.putString(address + SERIAL_SUFFIX, hexiwearDevice.getDeviceSerial()); + editor.putString(address + PASSWORD_SUFFIX, hexiwearDevice.getDevicePassword()); + editor.putString(address + WOLK_NAME_SUFFIX, hexiwearDevice.getWolkName()); + editor.apply(); + } + + public Map getDisplayPreferences(String deviceAddress) { + final Map displayPrefs = new HashMap<>(); + + final List readings = Characteristic.getReadings(); + for (Characteristic reading : readings) { + displayPrefs.put(reading.name(), preferences.getBoolean(deviceAddress + reading.name(), true)); + } + + return displayPrefs; + } + + public List getEnabledPreferences(String deviceAddress) { + final List enabledPrefs = new ArrayList<>(); + + final Map displayPreferences = getDisplayPreferences(deviceAddress); + for (Map.Entry entry : displayPreferences.entrySet()) { + if (entry.getValue()) { + enabledPrefs.add(entry.getKey()); + } + } + + return enabledPrefs; + } + + public void setDisplayPreferences(String deviceAddress, Map displayPrefs) { + final SharedPreferences.Editor editor = preferences.edit(); + for (Map.Entry entry : displayPrefs.entrySet()) { + editor.putBoolean(deviceAddress + entry.getKey(), entry.getValue()); + } + editor.apply(); + } + + public static List getDevices(List response) { + final List devices = new ArrayList<>(); + + for (PointWithFeedsResponse pwf : response) { + if (pwf.getDeviceSerial().length() > 8 && "HX".equalsIgnoreCase(pwf.getDeviceSerial().substring(4, 6))) { + devices.add(new HexiwearDevice(pwf.getName(), pwf.getDeviceSerial(), "", "", pwf.getName())); + } + } + + return devices; + } + + public void setPublishInterval(final HexiwearDevice device, final int interval) { + preferences.edit().putInt(device.getDeviceAddress() + PUBLISH_INTERVAL_SUFFIX, interval).apply(); + } + + public int getPublishInterval(final HexiwearDevice device) { + return preferences.getInt(device.getDeviceAddress() + PUBLISH_INTERVAL_SUFFIX, 10); + } + + public void toggleTracking(final BluetoothDevice device) { + final boolean isTracking = shouldTransmit(device); + preferences.edit().putBoolean(device.getAddress() + SHOULD_TRANSMIT_SUFFIX, !isTracking).apply(); + } + + public void toggleTracking(final HexiwearDevice device) { + final boolean isTracking = shouldTransmit(device); + preferences.edit().putBoolean(device.getDeviceAddress() + SHOULD_TRANSMIT_SUFFIX, !isTracking).apply(); + } + + public boolean shouldTransmit(final BluetoothDevice device) { + return preferences.getBoolean(device.getAddress() + SHOULD_TRANSMIT_SUFFIX, false); + } + + public boolean shouldTransmit(final HexiwearDevice device) { + return preferences.getBoolean(device.getDeviceAddress() + SHOULD_TRANSMIT_SUFFIX, false); + } + + public void setKeepAlive(final HexiwearDevice device, final boolean keepAlive) { + preferences.edit().putBoolean(device.getDeviceAddress() + KEEP_ALIVE_SUFFIX, keepAlive).apply(); + } + + public boolean shouldKeepAlive(final HexiwearDevice device) { + return preferences.getBoolean(device.getDeviceAddress() + KEEP_ALIVE_SUFFIX, true); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/view/DeviceActivation.java b/android/app/src/main/java/com/wolkabout/hexiwear/view/DeviceActivation.java new file mode 100644 index 0000000..e1c97ca --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/view/DeviceActivation.java @@ -0,0 +1,94 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.view; + +import android.content.Context; +import android.text.TextUtils; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.TextView; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.adapter.HexiwearListAdapter; +import com.wolkabout.hexiwear.model.HexiwearDevice; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EViewGroup; +import org.androidannotations.annotations.ItemClick; +import org.androidannotations.annotations.ViewById; + +import java.util.List; + +@EViewGroup(R.layout.view_register_device) +public class DeviceActivation extends LinearLayout { + + @ViewById + TextView serialField; + + @ViewById + Input deviceName; + + @ViewById + ListView hexiwearDevices; + + @Bean + HexiwearListAdapter adapter; + + public DeviceActivation(Context context) { + super(context); + } + + @AfterViews + void setDeviceList() { + hexiwearDevices.setChoiceMode(ListView.CHOICE_MODE_SINGLE); + hexiwearDevices.setAdapter(adapter); + hexiwearDevices.setItemChecked(0, true); + } + + public void setDevices(List devices) { + adapter.update(devices); + } + + public boolean isNewDeviceSelected() { + return deviceName.isEnabled(); + } + + public String getDeviceSerial() { + return serialField.getText().toString(); + } + + public String getWolkName() { + return deviceName.getValue(); + } + + @ItemClick(R.id.hexiwearDevices) + void onDeviceSelected(HexiwearDevice device) { + final String wolkName = device.getWolkName(); + final String deviceSerial = device.getDeviceSerial(); + + deviceName.setText(TextUtils.isEmpty(wolkName) ? getContext().getString(R.string.activation_dialog_default_name) : wolkName); + deviceName.setEnabled(TextUtils.isEmpty(deviceSerial)); + serialField.setText(deviceSerial); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/view/Input.java b/android/app/src/main/java/com/wolkabout/hexiwear/view/Input.java new file mode 100644 index 0000000..2a652a8 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/view/Input.java @@ -0,0 +1,160 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.support.design.widget.TextInputLayout; +import android.support.v4.content.ContextCompat; +import android.text.InputFilter; +import android.text.InputType; +import android.text.TextUtils; +import android.text.method.PasswordTransformationMethod; +import android.util.AttributeSet; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; + +import com.wolkabout.hexiwear.R; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.EViewGroup; +import org.androidannotations.annotations.UiThread; +import org.androidannotations.annotations.ViewById; + +@EViewGroup(R.layout.view_input) +public class Input extends TextInputLayout { + + @ViewById + TextView text; + + private String defaultText; + private String hint; + private int drawable; + private int maxLength; + private int textColor; + private String actionLabel; + private Type type; + + public Input(final Context context, final AttributeSet attrs) { + super(context, attrs); + final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Input); + defaultText = typedArray.getString(R.styleable.Input_text); + hint = typedArray.getString(R.styleable.Input_hint); + drawable = typedArray.getResourceId(R.styleable.Input_drawable, 0); + maxLength = typedArray.getResourceId(R.styleable.Input_maxLength, 100); + actionLabel = typedArray.getString(R.styleable.Input_actionLabel); + textColor = typedArray.getColor(R.styleable.Input_textColor, ContextCompat.getColor(getContext(), R.color.primary_text)); + + final int typeOrdinal = typedArray.getInt(R.styleable.Input_type, InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + type = Type.byOrdinal(typeOrdinal); + + typedArray.recycle(); + } + + @AfterViews + void init() { + setHint(hint); + text.setCompoundDrawablesWithIntrinsicBounds(drawable, 0, 0, 0); + text.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)}); + text.setInputType(type.flag); + text.setTextColor(textColor); + + if (!TextUtils.isEmpty(defaultText)) { + text.setText(defaultText); + } + + if (type == Type.PASSWORD) { + text.setTransformationMethod(PasswordTransformationMethod.getInstance()); + } + + if (!TextUtils.isEmpty(actionLabel)) { + text.setImeActionLabel(actionLabel, EditorInfo.IME_ACTION_UNSPECIFIED); + } + } + + public void setText(String value) { + text.setText(value); + } + + public void setText(int stringResource) { + text.setText(getContext().getString(stringResource)); + } + + public String getValue() { + return text.getText().toString(); + } + + public boolean isEmpty() { + return text.getText().toString().isEmpty(); + } + + @UiThread + public void clear() { + text.setText(""); + } + + @UiThread + public void setError(String error) { + text.setError(error); + text.requestFocus(); + } + + @UiThread + public void setError(int errorResource) { + text.setError(getContext().getString(errorResource)); + text.requestFocus(); + } + + public void setPasswordVisibility(boolean visible) { + text.setTransformationMethod(visible ? null : PasswordTransformationMethod.getInstance()); + } + + public void setOnEditorActionListener(TextView.OnEditorActionListener listener) { + text.setOnEditorActionListener(listener); + } + + @Override + public void setEnabled(boolean enabled) { + text.setEnabled(enabled); + super.setEnabled(enabled); + } + + private enum Type { + NAME(InputType.TYPE_TEXT_VARIATION_PERSON_NAME | InputType.TYPE_TEXT_FLAG_CAP_WORDS), + TEXT(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS), + EMAIL(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS), + PASSWORD(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD), + NUMBER(InputType.TYPE_CLASS_NUMBER); + + private int flag; + + Type(int flag) { + this.flag = flag; + } + + static Type byOrdinal(int ordinal) { + return Type.values()[ordinal]; + } + } + +} \ No newline at end of file diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/view/Reading.java b/android/app/src/main/java/com/wolkabout/hexiwear/view/Reading.java new file mode 100644 index 0000000..c49ac16 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/view/Reading.java @@ -0,0 +1,63 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import com.wolkabout.hexiwear.R; +import com.wolkabout.hexiwear.model.Characteristic; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.EViewGroup; +import org.androidannotations.annotations.ViewById; + +@EViewGroup +public class Reading extends LinearLayout { + + @ViewById + ImageView image; + + private Characteristic characteristic; + private int drawable; + + public Reading(final Context context, final AttributeSet attrs) { + super(context, attrs); + final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Reading); + drawable = typedArray.getResourceId(R.styleable.Reading_image, 0); + final int readingTypeOrdinal = typedArray.getInt(R.styleable.Reading_readingType, 0); + characteristic = Characteristic.byOrdinal(readingTypeOrdinal); + typedArray.recycle(); + } + + @AfterViews + void init() { + image.setImageResource(drawable); + } + + public Characteristic getReadingType() { + return characteristic; + } +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/view/SingleReading.java b/android/app/src/main/java/com/wolkabout/hexiwear/view/SingleReading.java new file mode 100644 index 0000000..9021387 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/view/SingleReading.java @@ -0,0 +1,50 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.wolkabout.hexiwear.R; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.EViewGroup; +import org.androidannotations.annotations.ViewById; + +@EViewGroup(R.layout.view_reading_single) +public class SingleReading extends Reading { + + @ViewById + TextView text; + + public SingleReading(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setValue(String value) { + text.setText(value); + } + +} diff --git a/android/app/src/main/java/com/wolkabout/hexiwear/view/TripleReading.java b/android/app/src/main/java/com/wolkabout/hexiwear/view/TripleReading.java new file mode 100644 index 0000000..9097312 --- /dev/null +++ b/android/app/src/main/java/com/wolkabout/hexiwear/view/TripleReading.java @@ -0,0 +1,63 @@ +/** + * Hexiwear application is used to pair with Hexiwear BLE devices + * and send sensor readings to WolkSense sensor data cloud + * + * Copyright (C) 2016 WolkAbout Technology s.r.o. + * + * Hexiwear is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hexiwear is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.wolkabout.hexiwear.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.wolkabout.hexiwear.R; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.EViewGroup; +import org.androidannotations.annotations.ViewById; + +@EViewGroup(R.layout.view_reading_tripple) +public class TripleReading extends Reading { + + @ViewById + TextView firstValue; + + @ViewById + TextView secondValue; + + @ViewById + TextView thirdValue; + + public TripleReading(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setFirstValue(String value) { + firstValue.setText(value); + } + + public void setSecondValue(String value) { + secondValue.setText(value); + } + + public void setThirdValue(String value) { + thirdValue.setText(value); + } +} diff --git a/android/app/src/main/res/drawable-hdpi/ic_arrow_forward_black_24dp.png b/android/app/src/main/res/drawable-hdpi/ic_arrow_forward_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..252342d3d7ee47e6eb72f1c652f1a135190b3d13 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8l&6bhNCo5D3)Wn%2|O+jnZqxn z_J`%2IDY9((!#y}k7}ws@%iuQbZM1fVun)3_bdIa9|HDHj@lf2n|)>D-rh@()B41; w{>}O`;lIi6&D|#tmaskZlY6$v<FVdQ&MBb@08joqcmMzZ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-hdpi/ic_clear_white_24dp.png b/android/app/src/main/res/drawable-hdpi/ic_clear_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..ceb1a1eebf2b2cc9a008f42010e144f4dab968de GIT binary patch literal 221 zcmV<303!d1P)og+*{ z>6z1@lfD*AYSPav7=4>kIV21T<&3Kg>clSSXlU}7 zNsTbZb7CDT8exhj%*e(#KY#)6xy}u?uzckjH(4PAzEPEh1-w0q?BPAtVVvU+$MuUd zim^-?Z*&k19JY)eT?W{4>I$)hC8bSG`$%Zf$FisplYAzY(o}#3ePW-OP>dHiLTyE8 z5z6Vv#(lhunj$1*cz0EVJ9s@A*ucB3BFy1+WndHUmWuEIZ$P35H8Q+=vQXg_LqaV@ zm?z|TsTk9IA=am%09Qzftuv(%OIZ4}NVJa{^Q2f76=H@QTgC>PWY~7OsDpS*8Lt)N zEWbIfpG@m8p5YBC;_%wCP~|(2vdmRx>0#;8WR`dQ1-2NIjXDoGtr048h%M+pCV0dp z9SxU>omUy0Vn}G0s>)%9(6-8A4Tr6%Lb0000Bx14mcwEU48mzn9ZOh$WB?6e N@O1TaS?83{1OQ_wCgcDB literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-mdpi/ic_clear_white_24dp.png b/android/app/src/main/res/drawable-mdpi/ic_clear_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..af7f8288da6854204dcc4e6678b9053cd72032c4 GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iGEW!B5R21KC-3Avpdi4K$<+1X zay^SH!@6{thMdKZi+L1hS^BMZUAdKCT}(HRw{NeWg~AlBHtr3jj>2B5kK^|J))MUC zlz7ydwCsb8xn}W?^r?}5wtsjdmvX{3=JbT!J9sKPrYmk={m|7^>A|Z*7j^D$`>}ry Zqi^Z9GQN4ct^!@a;OXk;vd$@?2>?I&LQeny literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png b/android/app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..8909c3553600d7e8148df21f8ef8a8ca655ade7b GIT binary patch literal 326 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_bluetooth_connected_white_48dp.png b/android/app/src/main/res/drawable-xhdpi/ic_bluetooth_connected_white_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..570ea492fdfdb8eb2967c0979223439c6d282ab8 GIT binary patch literal 652 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 Lce_g4AkO~)v5!2+ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_clear_white_24dp.png b/android/app/src/main/res/drawable-xhdpi/ic_clear_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..b7c7ffd0e795ba76ed3a062566c9016448795f7a GIT binary patch literal 257 zcmV+c0sj7pP) zOA5m<3jYBNi%A&<@ZO?$P9};P4Y5CjG5$M&YXI45J{s}~# zf|&?x1_gn4B7+hS@X!l}&!voFhmZP^sujifL@~PKMMM~{6xH}^g$q7WOzwCQ5vHTU z6`v~H@rlA8e;CUh_(b84zg=+ih`wG<)HiJjzSlQx5#CnjMR;A)R^jtaTa9;7rSy)7O%~`cm?ZjXImW?6TYRT<;U^@VKiSj`soFk00000NkvXX Hu0mjfhD&W| literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_cloud_off_black_24dp.png b/android/app/src/main/res/drawable-xhdpi/ic_cloud_off_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..da269d7bfca5e69542ba82cc6d5c547f7690269d GIT binary patch literal 582 zcmV-M0=fN(P)Nqy;*n0cyyO@es4#6QHc-Q?m~mE< zn(YaSIc{)(E>=-u69=g>hbnlOO)+ID*3nKg9h_%T6*tMiHa=L2<=M#_RU9P)TT?5_ zs`$cMQm~mbJZ73-n6z)93w81Dli%StMw3=?LEoXs3Jmd0idhvM%u8=SiJX#(n_^sA zVsCr!JDG0 zn+)8S!4LL%QuOI(It0+ecU6QQ7OJ1ma{nDg0631(OmdQ50%t{m37zXO%4v*iEJY{J z7#Y@W2Iz_}r{xfp^0ByZM Uv$!(4x&QzG07*qoM6N<$f{>v7wg3PC literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_cloud_off_white_48dp.png b/android/app/src/main/res/drawable-xhdpi/ic_cloud_off_white_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..2d78efc84e7a418c3fc6b95a73546a87914624b1 GIT binary patch literal 1126 zcmV-s1eyDZP)b&$Hw9eA`br@6X+?elOTL{LYxf z#l^+N#l^+N#l^*?imkMfKq7B38+d~*j`BN`cwFKiPV)opyv|w{A(@?!ep~T?k0KGO zXy6b@(v{>}UZKhwppQ=k!fL)`il`;|oHe!pef;!RAH5x%C#0w8=i3&J=(G_js#6p|p15|*=(MtT_| zb;l^P00c3O*yeK5{Go!k&nP=vzZS zVYS)-gqDmG3TY>-$87*YbH)im6T!|>ZUYeBHz3p#Y`+yic+Y^agJ5@O7H}h*c!wT- z<_|C+wBzqkrT`16;~SEw3?AnJ{M|cuKnc4zhsunw7JuDy17z{4I=nrh8(or$*#mCj zM|Adtm3Zi0m@QxfBLuT297NYQJHS&U0p@{FgYE(a*A93F4`5yh1&pJ+?^*#5a+&Z( z>7bTsN_}5W3HD`>@D;i<^s$dxZjA<5#wcN(WD5%rH5RI1VEyU?#h!3GGd0Bh;eblU@b?o-5H)K;88hdxlSB}(2Y>y6v)$_g!j-D zz)kquf*{6(=*wa=!vy=2;%UGW=+3bKaf%=m(n+x9X+SHw4g_(IAhh7`0u@N`22zVS zNl4IzznzHiE4pgLQNkilqdP@H7(rKxI7@gEe|HL((B&b{60#XW*Juf_AnZohE&PqH z3~`w70J;;xpvgmQMYtK=UpB8%J3>CXi$W{9PQ+nCF1pLYW^|+6;4q;I-ALGF?pefH z!g_SS2*MF`1LV3%2!D+VFXL|;;v^xPVRTJ`P|5_lNme*Xcp87zsXpolDR+)g%x~z1 zNC<+klyUqWcZ`t57x;S%5vJEjut8QjL&)Y6{GF%rKR_`^2(Mo zMp%Q?vT$ArMGO<{48T$kRV{1FopYs z{bZ#A2#+x8IH5!TaW}ZzIOZ&2g17b0Q{B3^G43RxEc(A1RMO0ZdxV()dZoO`VLX=! z!ptkDh8B7m;4BwiBMA00z2*tmIYGES2yONNOM=Jq_5eGAM?GQ>up)Rohu8zG2p)Ba sJ-~|aF?EPNz3E5Cg3CFS3=@q;0ueEC2ui07*qoM6N<$g8p*>-~a#s literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_cloud_queue_white_48dp.png b/android/app/src/main/res/drawable-xhdpi/ic_cloud_queue_white_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..6f0210dcc0db4f8b2e48dc7b4195267ef4fff378 GIT binary patch literal 1035 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 Zv$b*O0P0u#5C2wrDXkz?CSmCJ{{Wi=B#r<8 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_light.png b/android/app/src/main/res/drawable-xhdpi/ic_light.png new file mode 100644 index 0000000000000000000000000000000000000000..58f4fb5b54e3a83b0e684b3ad29a04fbdb68381e GIT binary patch literal 8383 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_magnet.png b/android/app/src/main/res/drawable-xhdpi/ic_magnet.png new file mode 100644 index 0000000000000000000000000000000000000000..44e11d1f1254f34e674db37d54d9567b7cf70f2d GIT binary patch literal 4843 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_pressure.png b/android/app/src/main/res/drawable-xhdpi/ic_pressure.png new file mode 100644 index 0000000000000000000000000000000000000000..1a92b933c058fc1112a6dab27c1312b2bff11265 GIT binary patch literal 10395 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

>NT^S`3!!6Y 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 TIGmUd{}@!1RRvc{o4xu!R4BPs literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png b/android/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..5caedc8e57497ba9d32c3a1798f7394bd8ca7cff GIT binary patch literal 562 zcmV-20?qx2P)lpy;7r2s24Mgk2IZK^^iBh`hXFsLp$Hi^-XdC|o$nN|w}JYolv9aiaA3)AHJ#jL^+Vnw!iASI;~WiKXmD0RMEHO!?-j&6;kHOKLX;?@ zWGE7DPJUcs54$WqYC|tM?Dm*a5EB$J%My_f5ptOQ;JnO8utv}pJu;w=5<;?v>&>8 zhF?Y&EaUf-F4>V}ouDGUG9XTwpfwUQW0DePIU@2QLIJZP6AEI68g@DQ)P^_(>}pKO zkE?_$vBVfLVvMs)nQ&JW#5%6Ll?i8P;6j~onehS_p38;=e>tq*49Si(?RM$JF6|Z- zhLe1y=@Yj&%{<$LDKkeuxA{!dCfy3hWwyzZQVXYeKoyfe+#{|QF7lc(Gdc+Jm}KP& zE12AuD=c7gL#~j*pF literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_signal_strength_1.png b/android/app/src/main/res/drawable-xhdpi/ic_signal_strength_1.png new file mode 100644 index 0000000000000000000000000000000000000000..6b947fd9627425cf0de5e83a55e42af1d96714be GIT binary patch literal 1122 zcmaJ=T}TvB6rRX_RHTy1Qi5p|GHT~JVe?rk7Qd-5qR1JCOpInsisf^?$=F# zbEL~5F${xOx=DtsarF@19}L=bR`AV z2!&Q1YgVREsAN=1G$@9oDOI)eN?Thn0@i4(Yi&il3_wMIrFWPT>PM_J3r4luIFN0K z*zkfbb*MmtLBT^H4Jj)!?+bX{bxzJz=cBz06X3j6E^ola`hC923c*FQS!__Vpr}b8 zi&fUJ+=f`*ZvqkOW>nYPv)yZm>rl7ix`F%s>2BfWAyHB^TY1DS4A+}l%;U5e}bn|(`jC+5G>S8{UM>KywbC%3SyzW@Dk ze)!sonAWlR}(AFxr)ME+SdGYroumacD8YO=0Qo|M!Zg3%d>SK;T%Npn;rBiJ N)dvG%;jyo!=Pzn>at#0g literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_signal_strength_2.png b/android/app/src/main/res/drawable-xhdpi/ic_signal_strength_2.png new file mode 100644 index 0000000000000000000000000000000000000000..e45b939078d47ebbce84e9f9f5844a944103ad4c GIT binary patch literal 1207 zcmeAS@N?(olHy`uVBq!ia0vp^Agss11|)Z%@lym+k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m^Cs(B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuk&``nLQqR!T z!q~`EN5ROz&{W^RQs2-(*TB%q(7?*bKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD#PU%0_}#n6BP2AO_EVu8M)o`HUDF34YC)x{-2sR(CaRb3oXS&*t9 zlvF!Z*KYW9dwX5Rv7G*^QPsLq9*?l*QfXOKRAnycyfK)yzbkTKkbf%0ncCY?Rw60b#1N9C&f0$g;vS-c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuk&``nLQqR!T z!q~`EN5ROz&{W^RQs2-(*TB%q(7?*bKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD#PU%0_}#n6BP2AO_EVu8M)o`HUDF34YC)x{-2sR(CaRb3oXS&*t9 zlvkypiPUw5;@=4R`gtnE)LA7*ZvocKAVd|$rVk%(;LAbV*I2NfkjPk~Mk z7o|xGLK8bwI$Tn^40C@7Xxbcn)a8PZTr+v?k#p$^d0leRI?T!2?z%mS^to~K$IGtp zjnRdFW?P6^TF<_3*)bs^CH~Duw`n;uHO*KicH|WPE>_CBJ6$*{w(QPEbwk%B^ZO*a z4|hFYe?)Wpw)u-WI%mHAZ`F|#`PyltXF>0qPVbFB-4~uX+C5|8Iq^z$x4gTnCS?~k zTK&If*F7O(N&mKI*F2hcrMY~XFSN=`NwD)o!9qjR?*7ab4Kt^>)Vb_S4-Lw>HuLf3 zCtGhcZTEV)%I5sO`ia_pIePb)b?(ggeZZ#wT}51CUt+Iik@>TS$5(9qe{MPhGsEfF VRj-@oc-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuk&``nLQqR!T z!q~`EN5ROz&{W^RQs2-(*TB%q(7?*bKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD#PU%0_}#n6BP2AO_EVu8M)o`HUDF34YC)x{-2sR(CaRb3oXS&*t9 zlv~#qv^|OrEzxq)Yr*w}Gl;*Xlok zNujgMwk~%)y}9;~l%yKl#E@K&8K2^pgl_(r(`6g&$=+wyc~}2lhr5fIvG%*8J}1BJ zPI6u1^Y(q@hY2&%vLJub#+2W( z7gMvuH$PD{-1K`tpOW;p(uFs!6!gZ3-M;wZ;_oF+6Yuxk?Fzpl>MGYEygP5|-s5+j zVhgj@S9_e<+_tSCJEdorfznTZ&QR%z9WG0DUpOM#?Ju*Up;e=*P-Ei!dCz%{i_E_N zWnypT+3gSh+Ngh)@iu$NcEnox;tT1WH3{z@oprpw?WN_fog0o{7OIsAf1$iJ_nb_v o%+1Gtg&tdo-WAyI_FE`{;YHKwsPe}w7eR%Wr>mdKI;Vst03mhS{Qv*} literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_signal_strength_5.png b/android/app/src/main/res/drawable-xhdpi/ic_signal_strength_5.png new file mode 100644 index 0000000000000000000000000000000000000000..58e4d7bc8e28a971e7dd9a85bdc684cc28f1a573 GIT binary patch literal 1408 zcmeAS@N?(olHy`uVBq!ia0vp^Agss11|)Z%@lym+k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m^Cs(B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuk&``nLQqR!T z!q~`EN5ROz&{W^RQs2-(*TB%q(7?*bKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7I$IMft0d=ry1 z^FV@{U|qhxR-SpqC5d^-sh%#jN= zAx`t4dQ)(_#R#WfeV}9XLD7p8-7q0w8Uiuli5JL$C;!wuV45!iCT{(^mmV-MFuwD2 zaSW-r^=9^NFJ?!HR&}?6)CF{! z!p!U%rz&(zZcV&)Ltx=Gf_cTV&?0Obik7reQb#gx42(|)VUD$U4>>u=2triLz5zreKYz~Z`3ovRf288=ORw`Wz` zm&vBHPgeMQriX|`vgm$os TaNJ%4Dib|j{an^LB{Ts5W@!GP literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_steps.png b/android/app/src/main/res/drawable-xhdpi/ic_steps.png new file mode 100644 index 0000000000000000000000000000000000000000..d470efacda9b3ff9ca09b0f4dec01f4f23d55e1b GIT binary patch literal 8496 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_temperature.png b/android/app/src/main/res/drawable-xhdpi/ic_temperature.png new file mode 100644 index 0000000000000000000000000000000000000000..20d4414c825b3351b997356963721623649838cf GIT binary patch literal 4647 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_arrow_forward_black_24dp.png b/android/app/src/main/res/drawable-xxhdpi/ic_arrow_forward_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..a124259898f2cbaa970223e6b3e995bcf35f4bba GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw8a-VcLn;{G-aO0M;K1YZuw;Sg ziluIAFVFW|^kmcb28&bGmk+R?o|hykC@A>Tc3~Pfx9p`!GLn~OiAV;e&u$gVY+&IO zQt_Ce;P^{ZQ*QR^#;zp-ikuAbP0l+XkKNEt)L literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_clear_white_24dp.png b/android/app/src/main/res/drawable-xxhdpi/ic_clear_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..6b717e0dda8649aa3b5f1d6851ba0dd20cc4ea66 GIT binary patch literal 347 zcmV-h0i^zkP)vMkH8EXyh{JTRaptiwcq@D(P;=ehLbl?EMKm*m7(@7_siS}}k zNFtnck{HL4mc!ypcyUoqJV~4rM^fS3C#iAnkyJU3biCmDy`VZLOv=LXld^HVqRPWZAHfP!)RVB2S(!`lt|Um(uYf2_cGfFjG~?QJ_SKM>Hu7Qz_%` zC^KY0j^p?%F-hrI#t?oEkx>e=^x$WZC9-20$8bAJMiyi_f!j|s$&C!#uq!e{4&*3d z*U4D<;$4cQ>yQUJNq3uf6oz@6$E?Ckd0-Y5%+4`a;aG`TuRL)UvsTrDjhJ=G6Wy3? zP%Zcjv%EY}z-*IhK|5x7d7^;XCe?zCn03h$-I#4qEm(P<#_c#+Sul>1xE*7f>{!k} z_~{|56pZ6*{0y;7>1g5}{!WmS0WF-w-(4mv4bw>oQKFMsszM7}DHGx$QauHt_cw57G zmNrf?VwFPCz(EGt%|eYrmJb-fVG|Z VF?y~eTbBR;002ovPDHLkV1i=jh>-vQ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_arrow_forward_black_24dp.png b/android/app/src/main/res/drawable-xxxhdpi/ic_arrow_forward_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5a68183db0af5ae96767121f57a6a5f4290587 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcgmU_B4hEy=Vz2(SvFhHdB;daKH zNwqO=cz5sOQOQqHa4mlH`yJc4`6h3dFf%Yb@P1Wzuy3*ZbG12c_Un_L1L@~Kj znKyHTq&TOLipK;6$0imSqouWK>FO^H{i-EZPRrFeK5$IE{(?Wpc>mF7v-AI5{qucB z{=T2j?*A(SlJC!$->>-`zQKR4edwz{D}$c32ETvhYyB39D^lU%DgQgv&#U%8l^-CA%qY@2qA=!B5=cm zUgehujQG*l{{`@rPr!f|fEk^>KI9WteE@ilV6HEl&_rJ@p_zU*;T}RirIc{5NocNLm*7JGdV(AM zYYDFOvk5~8{Z*t_>U=!XvoehUSEh=adIga45oe)B9kGgT}7UT3Cirmr(oHPv^YQ1-p=Hlh5u;xggf zX{&yw+El-OrrKQJRl@b7x{HLmNkj95`a#LLnW{Veb2C+!`ppt#r)=g4@?c8RY{yJj~W@W|h^mU4q`i)2y~Rw@J`jIh$1%|In!~{Tb{nMqaxlgb+dq eA%qY@zJ@mriVM?qfwL0;0000+t)}?IPi4`?n-BcG{I5ur- z(S>O`4876<#~6}k=`>Up4hWM~CUltm-)|Ri1Ni>m=Xw7B>2vXZK2lazR#sM4OxVB` zGWm@sMM^ z-;l({UGfbz*r=0l*o=*rbn~#1)BM5?7AY+r;d^YHV6D>PUbfT6IjR&Lx6#YE6o*+) zuBKoO-MHxHK}|s}>p4WgxIShmD&AzWe%_@-6DZ+pqS#BZCQ!mV^fOt5qM?`(rW@k` zYsq0Fe-hOnJV_2~IlvgxjZ&g0_?+}E6PL@R*DQCeAjPd$B{wAK#0SSo$OW75#b()K zHUs$LSLVnT+wsWmw*M;;$z=L|Dth}oRO&PU|Q78@DG)EG-;f#n348sTZV zVF~9kvs0GXg_$1ilRM_pLS`uz%MxXz$ZS8iD;g5KO+dIKazGp50^T5@IM7A7EpotC z!W~mwxJ0;WIiQwsy^0H?ge#H*l7zdexR6PK98gHOKye|H0y&_NaDn2&2;t_-0ZGDL zRb044xEeWN72z%_E_4yDUJlqsxMPX~IW&?Y+)+88op1pSBoqyIaEQ!Ol*$riq{ys= zxpK!+dNI=^OYFwX1(wJSoA?`3V^qijl?0d?Wut77&!^Zq%PbjU4n5fUgnXH!m=5f< zk}m_~a~ON=BxQz5hH%r$Y-PY44&!E!3Yp*}?#{7XA*iGWcbzi9S)vHoMVW4ZGIkRX z#g8(<%S4r;jjhy@q>w_AtYRDOq=;&>OpwD#d~}?I%ut7qs$`Bm_@-GlSja#4WRw!w z;XQoPAY06$A7At_L-u$UUpyrjB^DU#RVFRX2UE@R5j!x|C?D|xrk<0JScR#T@)5nxBvhE literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable/button_text.xml b/android/app/src/main/res/drawable/button_text.xml new file mode 100644 index 0000000..0aeb900 --- /dev/null +++ b/android/app/src/main/res/drawable/button_text.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/layout/activity_firmware_select.xml b/android/app/src/main/res/layout/activity_firmware_select.xml new file mode 100644 index 0000000..8e4bba6 --- /dev/null +++ b/android/app/src/main/res/layout/activity_firmware_select.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + diff --git a/android/app/src/main/res/layout/activity_login.xml b/android/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..6cd4163 --- /dev/null +++ b/android/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + +