1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-01 06:22:55 +01:00
This commit is contained in:
Sebastian Kranz 2019-02-20 14:24:59 +01:00
commit 6a04c78b0e
522 changed files with 8158 additions and 3585 deletions

3
.gitignore vendored
View File

@ -31,3 +31,6 @@ proguard/
MPChartLib
fw.dirs
**/.project
**/.settings
**/.classpath

View File

@ -0,0 +1,2 @@
connection.project.dir=
eclipse.preferences.version=1

View File

@ -16,10 +16,10 @@ android:
- tools
# The BuildTools version used by your project
- build-tools-28.0.2
- build-tools-28.0.3
# The SDK version used to compile your project
- android-27
- android-28
# Additional components
- extra-android-m2repository
@ -31,7 +31,7 @@ android:
#- sys-img-x86-android-17
before_install:
- yes | sdkmanager "platforms;android-27"
- yes | sdkmanager "platforms;android-28"
script:
- ./gradlew build connectedCheck --stacktrace

View File

@ -1,5 +1,58 @@
### Changelog
#### Version 0.32.3
* Fix a crash in charts due to a broken German translation
* Fix a crash when transliterating emoji
* Amazfit Bip/Cor: Support disconnect notification (must be configured in Bip settings for Cor also for now)
#### Version 0.32.2
* Fix setting alarms under some circumstances
* Support calls notifications for some VoIP apps
* Mi Band 3: Enable fetching sports activities (currently only useful for flushing activities)
* Casio: Improve stability
* Casio: Add explicit support for GB-6900B, GB-X6900B and GB-5600B
#### Version 0.32.1
* Fix db deadlock on alarm migration
#### Version 0.32.0
* Initial support for Casio GB-6900B
* Increase number of alarms and store them per-device
* Support factory reset in debug activity (Mi Band 1/2/3, Bip, Cor)
* Filter out unicode control sequences (fixes problems with Telegram and probably others)
* Fix endless loop resulting in OOM when RTL support is enabled
* Recoginize p≡p as an email app
* No longer display Android paired devices in that were not a paired with Gadgetbridge
* Amazfit Bip: Allow flashing latest GPS firmware
* Pebble: Native support for M7S watch face
* No1 F1: Support for a Chinese clone
#### Version 0.31.3
* Pebble: Fix crash with DISMISS and OPEN actions
#### Version 0.31.2
* Pebble: Fix a regression that caused non-working mute, open and dismiss actions
* Fix setting language to Czech manually
* Ignore summary notification from K-9 Mail (caused notification spamming)
#### Version 0.31.1
* Pebble: Fix crash when no canned replies have been set
* Pebble: Let the firmware show localized default canned replies if none have been set
* Amazfit Bip: Fix importing GPS tracks that have been recorded with Firmware 1.1.5.02
* Display measured hr value in debug screen
#### Version 0.31.0
* Pebble: Send all wearable notification actions (not only reply)
* Pebble: Always allow reply action even if untested features are turned off
* Pebble: Temporarily disable broken autoremove notification feature
* Amazfit Bip: Allow flashing latest gps firmware (Mili_dth.gps)
* Mi Band 3/Amazfit Bip/Amazfit Cor: Send Fahrenheit if units are set to imperial
* Roidmi 3: Fix and enable support
* Mi Band 3/Amazfit Bip: fix find phone crash
* Prevent re-sending old notifications to the wearable
* Enhancement and Fixes for Bengali Transliteration
* Disable excessive logging in RTL support
#### Version 0.30.0
* Amazfit Bip + Mi Band 3: Support for right to left display (configurable) (#976)
* Add Arabic, Bengali Farsi, Persian, Scandinavian transliteration

View File

@ -27,68 +27,90 @@
* Daniele Gobbetti <daniele+github@gobbetti.name>
* João Paulo Barraca <jpbarraca@gmail.com>
* Yaron Shahrabani <sh.yaron@gmail.com>
* Jonas <jonasdcdm@posteo.net>
* Allan Nordhøy <epost@anotheragency.no>
* postsorino <postsorino@krutt.org>
* Jonas <jonasdcdm@posteo.net>
* Roi Greenberg <roigreenberg@gmail.com>
* Sebastian Kranz <tklightforce@googlemail.com>
* Vadim Kaushan <admin@disasm.info>
* Allan Nordhøy <epost@anotheragency.no>
* protomors <protomors@gmail.com>
* José Rebelo <joserebelo@outlook.com>
* mesnevi <shams@airpost.net>
* naofum <naofum@gmail.com>
* youzhiran <2668760098@qq.com>
* TaaviE <taavi.eomae+weblate@gmail.com>
* mueller-ma <mueller-ma@users.noreply.github.com>
* ivanovlev <ivanovlev@mail.ru>
* naofum <naofum@gmail.com>
* youzhiran <2668760098@qq.com>
* Tijl Schepens <tijl.schepens@hotmail.com>
* mesnevi <shams@airpost.net>
* Hadrián Candela <hadrian.candela@gmail.com>
* Julien Pivotto <roidelapluie@inuits.eu>
* Andreas Böhler <dev@aboehler.at>
* 陈少举 <oshirisu.red@gmail.com>
* Taavi Eomäe <taavi.eomae+github@gmail.com>
* Steffen Liebergeld <perl@gmx.org>
* Lem Dulfo <lemuel.dulfo@gmail.com>
* Hadrián Candela <hadrian.candela@gmail.com>
* Felix Konstantin Maurer <maufl@maufl.de>
* Sergey Trofimov <sarg@sarg.org.ru>
* Robert Barat <rbarat07@gmail.com>
* Pavel Elagin <pelagin@techcd.ru>
* Lem Dulfo <lemuel.dulfo@gmail.com>
* Matthieu Baerts <matttbe@gmail.com>
* Felix Konstantin Maurer <maufl@maufl.de>
* Utsob Roy <uroybd@gmail.com>
* Sergey Trofimov <sarg@sarg.org.ru>
* Full Name <petr+weblate@linuks.cz>
* Robert Barat <rbarat07@gmail.com>
* JohnnySun <bmy001@gmail.com>
* Uwe Hermann <uwe@hermann-uwe.de>
* Kranz <Kranz>
* Gilles Émilien MOREL <contact@gilles-morel.fr>
* Edoardo Rosa <edoardo.rosa90@gmail.com>
* Bożydar <trening302@o2.pl>
* Alberto <albertsal83@gmail.com>
* Vladislav Serkov <vladserkoff@protonmail.com>
* Vebryn <vebryn@gmail.com>
* Gilles Émilien MOREL <contact@gilles-morel.fr>
* M. Hadi <hhhadddi@yahoo.com>
* Giuseppe Caliendo <giuseppe.caliendo@gmail.com>
* Gergely Peidl <gergely@peidl.net>
* Emre <wenigerpluesch@mailbox.org>
* Bożydar <trening302@o2.pl>
* Elwood <elwood21@gmail.com>
* AndrewBedscastle <1462953+AndrewBedscastle@users.noreply.github.com>
* abettenburg <a.bettenburg@gmail.com>
* 0nse <0nse@users.noreply.github.com>
* Максим Якимчук <xpinovo@gmail.com>
* Rimas Raguliūnas <rarimas@gmail.com>
* nautilusx <mail.ka@mailbox.org>
* Minori Hiraoka (미노리) <minori@mnetwork.co.kr>
* masakoodaa <masakoodaa@protonmail.com>
* Marius Cornescu <marius_cornescu@yahoo.com>
* Lukas Veneziano <fs@venezilu.de>
* LL <lu.lecocq@free.fr>
* Kompact <joaorafael123@hotmail.com>
* K0L0B0G <github@gorobav.ru>
* Johann C. Rode <jcrode@ece.ucsb.edu>
* Jasper <jespiex456@hotmail.com>
* Dikay900 <dark900@xyz.de>
* Christian Fischer <sw-dev@computerlyrik.de>
* c4ndel4 <hadrian.candela@gmail.com>
* 6arms1leg <m.brnsfld@googlemail.com>
* Zhong Jianxin <azuwis@gmail.com>
* walkjivefly <mark@walkjivefly.com>
* WaldiS <admin@sto.ugu.pl>
* Thomas <tutonis@gmail.com>
* Ted Stein <me@tedstein.net>
* ssantos <ssantos@web.de>
* Sebastian Obrusiewicz <sobrus2@o2.pl>
* Ranved Sticon <the7bulk@gmail.com>
* petronovak <petro.novak@gmail.com>
* Petr Kadlec <mormegil@centrum.cz>
* Pascal <pascal.tannich@gmail.com>
* NotAFIle <nota@notafile.com>
* Normano64 <per.bergqwist@gmail.com>
* NicoBuntu <nicolas__du95@hotmail.fr>
* Minori Hiraoka (미노리) <minori@mnetwork.co.kr>
* Moarc <aldwulf@gmail.com>
* Michal Novotny <mignov@gmail.com>
* Martin <ritualz@users.noreply.github.com>
* LL <lu.lecocq@free.fr>
* Louis-Marie Croisez <louis.croisez@gmail.com>
* Jesús <zaagur@gmail.com>
* Irul <wedesignthing@gmail.com>
* HenRy <helge1o1o1@gmail.com>
* exit-failure <hakrala@web.de>
* Dreamwalker <aristojeff@gmail.com>
* Denis <korden@sky-play.ru>
* Avamander <Avamander@users.noreply.github.com>
* AnthonyDiGirolamo <anthony.digirolamo@gmail.com>
@ -98,26 +120,32 @@
* Yar <yaroslav.isakov@gmail.com>
* xzovy <caleb@caleb-cooper.net>
* xphnx <xphnx@users.noreply.github.com>
* Xavier RENE-CORAIL <xavier.renecorail@gmail.com>
* Vitaliy Shuruta <vshuruta@gmail.com>
* Vincèn PUJOL <vincen@vincen.org>
* veecue <veecue@ventos.tk>
* Tomer Rosenfeld <tomerosenfeld007@gmail.com>
* Tomas Radej <tradej@redhat.com>
* tiparega <11555126+tiparega@users.noreply.github.com>
* Tarik Sekmen <tarik@ilixi.org>
* Szymon Tomasz Stefanek <s.stefanek@gmail.com>
* szilardx <15869670+szilardx@users.noreply.github.com>
* Stan Gomin <stan@gomin.me>
* SinMan <emilio.galvan@gmail.com>
* Sergio Lopez <slp@sinrega.org>
* S Dantas <dantasosteney@gmail.com>
* Sami Alaoui <4ndroidgeek@gmail.com>
* Roman Plevka <rplevka@redhat.com>
* rober <rober@prtl.nodomain.net>
* redking <redking974@gmail.com>
* Quallenauge <Hamsi2k@freenet.de>
* Pavel Motyrev <legioner.r@gmail.com>
* Pavel <elagin.pasha@gmail.com>
* Olexandr Nesterenko <olexn@ukr.net>
* Nicolò Balzarotti <anothersms@gmail.com>
* Natanael Arndt <arndtn@gmail.com>
* Nabil BENDAFI <nabil@bendafi.fr>
* Molnár Barnabás <nsd4rkn3ss@gmail.com>
* Moarc <aldwulf@gmail.com>
* Mike van Rossum <mike@vanrossum.net>
* Michal Novak <michal.novak@post.cz>
* michaelneu <git@michaeln.eu>
@ -142,9 +170,14 @@
* kalaee <alex.kalaee@gmail.com>
* Joseph Kim <official.jkim@gmail.com>
* jonnsoft <>
* Johannes Tysiak <vinyl@users.sf.net>
* jcrode <46062294+jcrode@users.noreply.github.com>
* Jan Lolek <janlolek@seznam.cz>
* Jakub Jelínek <jakub.jelinek@gmail.com>
* Ivan <ivan_tizhanin@mail.ru>
* Hüseyin Aslan <ha098784@gmail.com>
* hr-sales <hericsonregis@hotmail.com>
* Hirnchirurg <anonymous11@posteo.net>
* Hasan Ammar <ammarh@gmail.com>
* Grzegorz Dznsk <grantmlody96@gmail.com>
* Gilles MOREL <contact@gilles-morel.fr>
@ -152,7 +185,8 @@
* Gabe Schrecker <gabe@pbrb.co.uk>
* freezed-or-frozen <freezed.or.frozen@gmail.com>
* Frank Slezak <KazWolfe@users.noreply.github.com>
* Dreamwalker <aristojeff@gmail.com>
* Francesco Franchina <cescus92@gmail.com>
* Edoardo Tronconi <edoardo.tronconi@gmail.com>
* Dougal19 <4662351+Dougal19@users.noreply.github.com>
* Davis Mosenkovs <davikovs@gmail.com>
* Daniel Hauck <maill@dhauck.eu>
@ -164,14 +198,18 @@
* Carlos Ferreira <calbertoferreira@gmail.com>
* bucala <marcel.bucala@gmail.com>
* boun <boun@gmx.de>
* Benjamin Kahlau <nyhkkbjyek@roanapur.de>
* batataspt@gmail.com <batataspt@gmail.com>
* atkyritsis <at.kyritsis@gmail.com>
* apre <adrienpre+github@gmail.com>
* Aniruddha Adhikary <aniruddha@adhikary.net>
* andrewlytvyn <indusfreelancer@gmail.com>
* AndrewH <36428679+andrewheadricke@users.noreply.github.com>
* andre <andre.buesgen@yahoo.de>
* Allen B <28495335+Allen-B1@users.noreply.github.com>
* Alfeu Lucas Guedes dos Santos <alfeugds@gmail.com>
* Alexey Afanasev <avafanasiev@gmail.com>
* Alexandra Sevostyanova <asevostyanova@gmail.com>
And all the Transifex translators, which I cannot automatically list, at the moment.

View File

@ -1,5 +1,5 @@
apply plugin: 'java'
//apply plugin: 'maven'
apply plugin: 'maven'
apply plugin:'application'
archivesBaseName = 'gadgetbridge-daogenerator'
@ -8,7 +8,7 @@ archivesBaseName = 'gadgetbridge-daogenerator'
dependencies {
// compile 'org.greenrobot:greendao-generator:2.2.0'
// compile project(":DaoGenerator")
compile 'com.github.freeyourgadget:greendao:1998d7cd2d21f662c6044f6ccf3b3a251bbad341'
compile 'com.github.Freeyourgadget:greendao:1998d7cd2d21f662c6044f6ccf3b3a251bbad341'
}
sourceSets {

View File

@ -45,7 +45,7 @@ public class GBDaoGenerator {
public static void main(String[] args) throws Exception {
Schema schema = new Schema(18, MAIN_PACKAGE + ".entities");
Schema schema = new Schema(20, MAIN_PACKAGE + ".entities");
Entity userAttributes = addUserAttributes(schema);
Entity user = addUserInfo(schema, userAttributes);
@ -73,6 +73,11 @@ public class GBDaoGenerator {
addID115ActivitySample(schema, user, device);
addCalendarSyncState(schema, device);
addAlarms(schema, user, device);
Entity notificationFilter = addNotificationFilters(schema);
addNotificationFilterEntry(schema, notificationFilter);
addBipActivitySummary(schema, user, device);
@ -342,6 +347,54 @@ public class GBDaoGenerator {
calendarSyncState.addIntProperty("hash").notNull();
}
private static void addAlarms(Schema schema, Entity user, Entity device) {
Entity alarm = addEntity(schema, "Alarm");
alarm.implementsInterface("nodomain.freeyourgadget.gadgetbridge.model.Alarm");
Property deviceId = alarm.addLongProperty("deviceId").notNull().getProperty();
Property userId = alarm.addLongProperty("userId").notNull().getProperty();
Property position = alarm.addIntProperty("position").notNull().getProperty();
Index indexUnique = new Index();
indexUnique.addProperty(deviceId);
indexUnique.addProperty(userId);
indexUnique.addProperty(position);
indexUnique.makeUnique();
alarm.addIndex(indexUnique);
alarm.addBooleanProperty("enabled").notNull();
alarm.addBooleanProperty("smartWakeup").notNull();
alarm.addIntProperty("repetition").notNull().codeBeforeGetter(
"public boolean isRepetitive() { return getRepetition() != ALARM_ONCE; } " +
"public boolean getRepetition(int dow) { return (this.repetition & dow) > 0; }"
);
alarm.addIntProperty("hour").notNull();
alarm.addIntProperty("minute").notNull();
alarm.addToOne(user, userId);
alarm.addToOne(device, deviceId);
}
private static void addNotificationFilterEntry(Schema schema, Entity notificationFilterEntity) {
Entity notificatonFilterEntry = addEntity(schema, "NotificationFilterEntry");
notificatonFilterEntry.addIdProperty().autoincrement();
Property notificationFilterId = notificatonFilterEntry.addLongProperty("notificationFilterId").notNull().getProperty();
notificatonFilterEntry.addStringProperty("notificationFilterContent").notNull().getProperty();
notificatonFilterEntry.addToOne(notificationFilterEntity, notificationFilterId);
}
private static Entity addNotificationFilters(Schema schema) {
Entity notificatonFilter = addEntity(schema, "NotificationFilter");
Property appIdentifier = notificatonFilter.addStringProperty("appIdentifier").notNull().getProperty();
notificatonFilter.addIdProperty().autoincrement();
Index indexUnique = new Index();
indexUnique.addProperty(appIdentifier);
indexUnique.makeUnique();
notificatonFilter.addIndex(indexUnique);
Property notificationFilterMode = notificatonFilter.addIntProperty("notificationFilterMode").notNull().getProperty();
Property notificationFilterSubMode = notificatonFilter.addIntProperty("notificationFilterSubMode").notNull().getProperty();
return notificatonFilter;
}
private static void addBipActivitySummary(Schema schema, Entity user, Entity device) {
Entity summary = addEntity(schema, "BaseActivitySummary");
summary.implementsInterface(ACTIVITY_SUMMARY);

View File

@ -22,43 +22,39 @@ vendor's servers.
[<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="80">](https://f-droid.org/app/nodomain.freeyourgadget.gadgetbridge)
[List of changes](https://github.com/Freeyourgadget/Gadgetbridge/blob/master/CHANGELOG.md)
[List of changes](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/CHANGELOG.md)
## Supported Devices
* Amazfit Bip [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip)
* Amazfit Cor (no maintainer) [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor)
* HPlus Devices (e.g. ZeBand) [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/HPlus)
* Amazfit Bip [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip)
* Amazfit Cor [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor)
* Casio GB-6900B (WIP)
* HPlus Devices (e.g. ZeBand) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/HPlus)
* ID115 (WIP)
* Lenovo Watch 9 (WIP)
* Liveview (WIP)
* Mi Band, Mi Band 1A, Mi Band 1S [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band)
* Mi Band 2 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2)
* Mi Band 3 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-3)
* Mi Band, Mi Band 1A, Mi Band 1S [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band)
* Mi Band 2 [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2)
* Mi Band 3 [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-3)
* NO.1 F1 (WIP)
* Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble)
* Pebble 2 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble)
* Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Pebble)
* Pebble 2 [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Pebble)
* Teclast H10, H30 (WIP)
* XWatch (Affordable Chinese Casio-like smartwatches)
* Vibratissimo (experimental)
* ZeTime (WIP)
## Features
Please see [FEATURES.md](https://github.com/Freeyourgadget/Gadgetbridge/blob/master/FEATURES.md)
Please see [FEATURES.md](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/FEATURES.md)
## Getting Started (Pebble)
1. Pair your Pebble through the Android's Bluetooth Settings or Gadgetbridge. Pebble 2 MUST be paired though Gadgetbridge (tap on the + in Control Center)
2. Start Gadgetbridge, tap on the device you want to connect to
3. To test, choose "Debug" from the menu and play around
For more information read [this wiki article](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble-Getting-Started)
Please [this wiki article](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Pebble-Getting-Started)
## How to use (Mi Band 1+2)
* When starting Gadgetbridge the first time, it will automatically
attempt to discover and pair your Mi Band. Alternatively you can invoke discovery
manually via the "+" button. It will ask you for some personal info that appears
* Invoke the discovery activity manually via the "+" button. It will ask you for some personal info that appears
to be needed for proper steps calculation on the band. If you do not provide these,
some hardcoded default "dummy" values will be used instead.
@ -78,9 +74,9 @@ For more information read [this wiki article](https://github.com/Freeyourgadget/
* If you use other apps like Mi Fit, and "bonding" with Gadgetbridge does not work, please
try to unpair the band in the other app and try again with Gadgetbridge.
* While all Mi Band devices are supported, some firmware versions might work better than others.
You can consult the [projects wiki pages](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band)
You can consult the [projects wiki pages](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band)
to check if your firmware version is fully supported or if an upgrade/downgrade might be beneficial.
* In order to display text notifications on the Mi Band 2, you have to [install a font on the band](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2).
* In order to display text notifications on the Mi Band 2, you have to [install a font on the band](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2).
## Features (Liveview)
@ -95,7 +91,6 @@ For more information read [this wiki article](https://github.com/Freeyourgadget/
* Daniele Gobbetti
### Additional device support
* João Paulo Barraca (HPlus)
* Vitaly Svyastyn (NO.1 F1)
* Sami Alaoui (Teclast H30)
@ -103,6 +98,7 @@ For more information read [this wiki article](https://github.com/Freeyourgadget/
* Sebastian Kranz (ZeTime)
* Vadim Kaushan (ID115)
* "maxirnilian" (Lenovo Watch 9)
* Andreas Böhler (Casio GB-6900B)
## Contribute

View File

@ -16,8 +16,8 @@ android {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
compileSdkVersion 27
buildToolsVersion "28.0.2"
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "nodomain.freeyourgadget.gadgetbridge"
@ -25,8 +25,8 @@ android {
targetSdkVersion 27
// Note: always bump BOTH versionCode and versionName!
versionName "0.30.0"
versionCode 138
versionName "0.32.3"
versionCode 146
vectorDrawables.useSupportLibrary = true
}
buildTypes {
@ -60,18 +60,19 @@ pmd {
dependencies {
// testImplementation "ch.qos.logback:logback-classic:1.1.3"
// testImplementation "ch.qos.logback:logback-core:1.1.3"
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation "junit:junit:4.12"
testImplementation "org.mockito:mockito-core:1.10.19"
testImplementation "org.robolectric:robolectric:3.6.1"
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.android.support:appcompat-v7:27.1.1"
implementation "com.android.support:cardview-v7:27.1.1"
implementation "com.android.support:recyclerview-v7:27.1.1"
implementation "com.android.support:support-v4:27.1.1"
implementation "com.android.support:gridlayout-v7:27.1.1"
implementation "com.android.support:design:27.1.1"
implementation "com.android.support:palette-v7:27.1.1"
implementation "androidx.appcompat:appcompat:1.0.2"
implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.recyclerview:recyclerview:1.0.0"
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "com.google.android.material:material:1.0.0"
implementation "androidx.palette:palette:1.0.0"
implementation("com.github.tony19:logback-android-classic:1.1.1-6") {
exclude group: "com.google.android", module: "android"
}
@ -87,6 +88,7 @@ dependencies {
implementation "org.cyanogenmod:platform.sdk:6.0"
implementation 'com.jaredrummler:colorpicker:1.0.2'
// implementation project(":DaoCore")
implementation 'com.github.wax911:android-emojify:0.1.7'
}
preBuild.dependsOn(":GBDaoGenerator:genSources")

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="src" path="java"/>
<classpathentry kind="src" path="aidl"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Gadgetbridge</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -1,12 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7

View File

@ -409,12 +409,17 @@
<activity
android:name=".activities.AlarmDetails"
android:label="@string/title_activity_alarm_details"
android:screenOrientation="portrait"
android:parentActivityName=".activities.ConfigureAlarms" />
android:parentActivityName=".activities.ConfigureAlarms"
android:screenOrientation="portrait" />
<activity
android:name=".activities.VibrationActivity"
android:label="@string/title_activity_vibration"
android:parentActivityName=".activities.ControlCenterv2" />
<activity
android:name=".activities.NotificationFilterActivity"
android:label="@string/title_activity_notification_filter"
android:windowSoftInputMode="stateHidden|adjustPan"
android:parentActivityName=".activities.AppBlacklistActivity" />
<activity
android:name=".activities.FindPhoneActivity"
android:label="Find Phone" />
@ -425,7 +430,7 @@
android:exported="true" />
<provider
android:name="android.support.v4.content.FileProvider"
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.screenshot_provider"
android:exported="false"
android:grantUriPermissions="true">

View File

@ -9,7 +9,7 @@ navigator.geolocation.getCurrentPosition = function(success, failure, options) {
reportedPositionFailures = 0;
success(geoposition);
}
}
};
if (window.Storage){
var prefix = GBjs.getAppLocalstoragePrefix();

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Martin, Normano64, Pavel Elagin, Taavi Eomäe
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Martin, Matthieu Baerts, Normano64, Pavel Elagin, Taavi Eomäe
This file is part of Gadgetbridge.
@ -39,7 +39,6 @@ import android.os.Build;
import android.os.Build.VERSION;
import android.preference.PreferenceManager;
import android.provider.ContactsContract.PhoneLookup;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.util.TypedValue;
@ -53,6 +52,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.database.DBOpenHelper;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin
/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Carsten Pfeiffer
/* Copyright (C) 2015-2019 Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 0nse, Carsten Pfeiffer
/* Copyright (C) 2016-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.
@ -27,12 +27,15 @@ import android.os.Build;
import android.widget.RemoteViews;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
/**
@ -55,7 +58,8 @@ public class SleepAlarmWidget extends AppWidgetProvider {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.sleep_alarm_widget);
// Add our own click intent
Intent intent = new Intent(ACTION);
Intent intent = new Intent(context, SleepAlarmWidget.class);
intent.setAction(ACTION);
PendingIntent clickPI = PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.sleepalarmwidget_text, clickPI);
@ -90,23 +94,41 @@ public class SleepAlarmWidget extends AppWidgetProvider {
// current timestamp
GregorianCalendar calendar = new GregorianCalendar();
// add preferred sleep duration
calendar.add(Calendar.HOUR_OF_DAY, userSleepDuration);
if (userSleepDuration > 0) {
calendar.add(Calendar.HOUR_OF_DAY, userSleepDuration);
} else { // probably testing
calendar.add(Calendar.MINUTE, 1);
}
// overwrite the first alarm and activate it, without
// overwrite the first alarm and activate it
GBAlarm alarm = GBAlarm.createSingleShot(0, true, calendar);
alarm.store();
if (GBApplication.isRunningLollipopOrLater()) {
setAlarmViaAlarmManager(context, calendar.getTimeInMillis());
Context appContext = context.getApplicationContext();
if (appContext instanceof GBApplication) {
GBApplication gbApp = (GBApplication) appContext;
GBDevice selectedDevice = gbApp.getDeviceManager().getSelectedDevice();
if (selectedDevice == null || !selectedDevice.isInitialized()) {
GB.toast(context,
context.getString(R.string.appwidget_not_connected),
Toast.LENGTH_LONG, GB.WARN);
return;
}
}
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
GB.toast(context,
String.format(context.getString(R.string.appwidget_alarms_set), hours, minutes),
context.getString(R.string.appwidget_setting_alarm, hours, minutes),
Toast.LENGTH_SHORT, GB.INFO);
Alarm alarm = AlarmUtils.createSingleShot(0,true, calendar);
ArrayList<Alarm> alarms = new ArrayList<>(1);
alarms.add(alarm);
GBApplication.deviceService().onSetAlarms(alarms);
// if (GBApplication.isRunningLollipopOrLater()) {
// setAlarmViaAlarmManager(context, calendar.getTimeInMillis());
// }
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Carsten Pfeiffer
/* Copyright (C) 2015-2019 Carsten Pfeiffer, Daniele Gobbetti
This file is part of Gadgetbridge.
@ -16,13 +16,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.ViewGroup;
import java.util.HashSet;
import java.util.Set;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
public abstract class AbstractFragmentPagerAdapter extends FragmentStatePagerAdapter {
private final Set<AbstractGBFragment> fragments = new HashSet<>();
private Object primaryFragment;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo
This file is part of Gadgetbridge.
@ -22,11 +23,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import java.util.Locale;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, walkjivefly
This file is part of Gadgetbridge.
@ -17,8 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
/**
* Abstract base class for fragments. Provides hooks that are called when

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -17,8 +18,11 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.PagerAdapter;
/**
* A base activity that supports paging through fragments by swiping.
@ -35,12 +39,12 @@ import android.support.v4.app.FragmentPagerAdapter;
*/
public abstract class AbstractGBFragmentActivity extends AbstractGBActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* The {@link PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
* {@link FragmentStatePagerAdapter}.
*/
private AbstractFragmentPagerAdapter mSectionsPagerAdapter;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Christian
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Christian
Fischer, Daniele Gobbetti, Lem Dulfo
This file is part of Gadgetbridge.
@ -26,8 +26,6 @@ import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.support.v4.content.LocalBroadcastManager;
import android.text.InputType;
import android.view.MenuItem;
@ -36,6 +34,8 @@ import org.slf4j.LoggerFactory;
import java.util.Locale;
import androidx.core.app.NavUtils;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -25,10 +25,6 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.FileProvider;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
@ -40,6 +36,8 @@ import android.widget.DatePicker;
import android.widget.ListView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@ -47,6 +45,9 @@ import java.util.Calendar;
import java.util.List;
import java.util.Objects;
import androidx.core.content.FileProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.ActivitySummariesAdapter;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo
This file is part of Gadgetbridge.
@ -26,14 +26,16 @@ import android.widget.TimePicker;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
public class AlarmDetails extends AbstractGBActivity {
private GBAlarm alarm;
private Alarm alarm;
private TimePicker timePicker;
private CheckedTextView cbSmartWakeup;
private CheckedTextView cbMonday;
@ -50,7 +52,7 @@ public class AlarmDetails extends AbstractGBActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_details);
alarm = getIntent().getParcelableExtra("alarm");
alarm = (Alarm) getIntent().getSerializableExtra(nodomain.freeyourgadget.gadgetbridge.model.Alarm.EXTRA_ALARM);
device = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
timePicker = findViewById(R.id.alarm_time_picker);
@ -109,17 +111,17 @@ public class AlarmDetails extends AbstractGBActivity {
timePicker.setCurrentHour(alarm.getHour());
timePicker.setCurrentMinute(alarm.getMinute());
cbSmartWakeup.setChecked(alarm.isSmartWakeup());
cbSmartWakeup.setChecked(alarm.getSmartWakeup());
int smartAlarmVisibility = supportsSmartWakeup() ? View.VISIBLE : View.GONE;
cbSmartWakeup.setVisibility(smartAlarmVisibility);
cbMonday.setChecked(alarm.getRepetition(GBAlarm.ALARM_MON));
cbTuesday.setChecked(alarm.getRepetition(GBAlarm.ALARM_TUE));
cbWednesday.setChecked(alarm.getRepetition(GBAlarm.ALARM_WED));
cbThursday.setChecked(alarm.getRepetition(GBAlarm.ALARM_THU));
cbFriday.setChecked(alarm.getRepetition(GBAlarm.ALARM_FRI));
cbSaturday.setChecked(alarm.getRepetition(GBAlarm.ALARM_SAT));
cbSunday.setChecked(alarm.getRepetition(GBAlarm.ALARM_SUN));
cbMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON));
cbTuesday.setChecked(alarm.getRepetition(Alarm.ALARM_TUE));
cbWednesday.setChecked(alarm.getRepetition(Alarm.ALARM_WED));
cbThursday.setChecked(alarm.getRepetition(Alarm.ALARM_THU));
cbFriday.setChecked(alarm.getRepetition(Alarm.ALARM_FRI));
cbSaturday.setChecked(alarm.getRepetition(Alarm.ALARM_SAT));
cbSunday.setChecked(alarm.getRepetition(Alarm.ALARM_SUN));
}
@ -144,10 +146,11 @@ public class AlarmDetails extends AbstractGBActivity {
private void updateAlarm() {
alarm.setSmartWakeup(supportsSmartWakeup() && cbSmartWakeup.isChecked());
alarm.setRepetition(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked());
int repetitionMask = AlarmUtils.createRepetitionMassk(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked());
alarm.setRepetition(repetitionMask);
alarm.setHour(timePicker.getCurrentHour());
alarm.setMinute(timePicker.getCurrentMinute());
alarm.store();
DBHelper.store(alarm);
}
@Override

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
This file is part of Gadgetbridge.

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo
/* Copyright (C) 2015-2019 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Lem Dulfo
This file is part of Gadgetbridge.
@ -18,10 +18,6 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@ -29,6 +25,10 @@ import android.view.MenuItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import androidx.appcompat.widget.SearchView;
import androidx.core.app.NavUtils;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.AppBlacklistAdapter;

View File

@ -19,15 +19,16 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
/**
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2018 Carsten Pfeiffer, Daniele Gobbetti
/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti
This file is part of Gadgetbridge.
@ -24,10 +24,6 @@ import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NavUtils;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@ -42,6 +38,10 @@ import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NavUtils;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.GB;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo
This file is part of Gadgetbridge.
@ -19,33 +19,39 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.MenuItem;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.GBAlarmListAdapter;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ALARMS;
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
public class ConfigureAlarms extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(ConfigureAlarms.class);
private static final int REQ_CONFIGURE_ALARM = 1;
private GBAlarmListAdapter mGBAlarmListAdapter;
private Set<String> preferencesAlarmListSet;
private boolean avoidSendAlarmsToDevice;
private GBDevice device;
private GBDevice gbDevice;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -53,28 +59,20 @@ public class ConfigureAlarms extends AbstractGBActivity {
setContentView(R.layout.activity_configure_alarms);
device = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
gbDevice = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
Prefs prefs = GBApplication.getPrefs();
preferencesAlarmListSet = prefs.getStringSet(PREF_MIBAND_ALARMS, new HashSet<String>());
if (preferencesAlarmListSet.isEmpty()) {
//initialize the preferences
preferencesAlarmListSet = new HashSet<>(Arrays.asList(GBAlarm.DEFAULT_ALARMS));
prefs.getPreferences().edit().putStringSet(PREF_MIBAND_ALARMS, preferencesAlarmListSet).apply();
}
mGBAlarmListAdapter = new GBAlarmListAdapter(this);
mGBAlarmListAdapter = new GBAlarmListAdapter(this, preferencesAlarmListSet);
RecyclerView alarmsRecyclerView = (RecyclerView) findViewById(R.id.alarm_list);
RecyclerView alarmsRecyclerView = findViewById(R.id.alarm_list);
alarmsRecyclerView.setHasFixedSize(true);
alarmsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
alarmsRecyclerView.setAdapter(mGBAlarmListAdapter);
updateAlarmsFromPrefs();
updateAlarmsFromDB();
}
@Override
protected void onPause() {
if (!avoidSendAlarmsToDevice) {
if (!avoidSendAlarmsToDevice && gbDevice.isInitialized()) {
sendAlarmsToDevice();
}
super.onPause();
@ -84,19 +82,62 @@ public class ConfigureAlarms extends AbstractGBActivity {
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQ_CONFIGURE_ALARM) {
avoidSendAlarmsToDevice = false;
updateAlarmsFromPrefs();
updateAlarmsFromDB();
}
}
private void updateAlarmsFromPrefs() {
Prefs prefs = GBApplication.getPrefs();
preferencesAlarmListSet = prefs.getStringSet(PREF_MIBAND_ALARMS, new HashSet<String>());
int reservedSlots = prefs.getInt(MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR, 0);
/**
* Reads the available alarms from the database and updates the view afterwards.
*/
private void updateAlarmsFromDB() {
List<Alarm> alarms = DBHelper.getAlarms(getGbDevice());
if (alarms.isEmpty()) {
alarms = AlarmUtils.readAlarmsFromPrefs(getGbDevice());
storeMigratedAlarms(alarms);
}
addMissingAlarms(alarms);
mGBAlarmListAdapter.setAlarmList(preferencesAlarmListSet, reservedSlots);
mGBAlarmListAdapter.setAlarmList(alarms);
mGBAlarmListAdapter.notifyDataSetChanged();
}
private void storeMigratedAlarms(List<Alarm> alarms) {
for (Alarm alarm : alarms) {
DBHelper.store(alarm);
}
}
private void addMissingAlarms(List<Alarm> alarms) {
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(getGbDevice());
int supportedNumAlarms = coordinator.getAlarmSlotCount();
if (supportedNumAlarms > alarms.size()) {
try (DBHandler db = GBApplication.acquireDB()) {
DaoSession daoSession = db.getDaoSession();
Device device = DBHelper.getDevice(getGbDevice(), daoSession);
User user = DBHelper.getUser(daoSession);
for (int position = 0; position < supportedNumAlarms; position++) {
boolean found = false;
for (Alarm alarm : alarms) {
if (alarm.getPosition() == position) {
found = true;
break;
}
}
if (!found) {
LOG.info("adding missing alarm at position " + position);
alarms.add(position, createDefaultAlarm(device, user, position));
}
}
} catch (Exception e) {
LOG.error("Error accessing database", e);
}
}
}
private Alarm createDefaultAlarm(@NonNull Device device, @NonNull User user, int position) {
return new Alarm(device.getId(), user.getId(), position, false, false,0, 6, 30);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@ -108,16 +149,16 @@ public class ConfigureAlarms extends AbstractGBActivity {
return super.onOptionsItemSelected(item);
}
public void configureAlarm(GBAlarm alarm) {
public void configureAlarm(Alarm alarm) {
avoidSendAlarmsToDevice = true;
Intent startIntent = new Intent(getApplicationContext(), AlarmDetails.class);
startIntent.putExtra("alarm", alarm);
startIntent.putExtra(GBDevice.EXTRA_DEVICE, getDevice());
startIntent.putExtra(Alarm.EXTRA_ALARM, alarm);
startIntent.putExtra(GBDevice.EXTRA_DEVICE, getGbDevice());
startActivityForResult(startIntent, REQ_CONFIGURE_ALARM);
}
private GBDevice getDevice() {
return device;
private GBDevice getGbDevice() {
return gbDevice;
}
private void sendAlarmsToDevice() {

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Taavi Eomäe
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Johannes Tysiak, Taavi Eomäe
This file is part of Gadgetbridge.
@ -27,28 +27,29 @@ import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import de.cketti.library.changelog.ChangeLog;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Alberto, Andreas Shimokawa, Carsten Pfeiffer,
/* Copyright (C) 2016-2019 Alberto, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti
This file is part of Gadgetbridge.
@ -23,7 +23,6 @@ import android.content.SharedPreferences;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
@ -36,6 +35,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import androidx.core.app.NavUtils;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Frank Slezak, ivanovlev, Kasha, Lem Dulfo, Pavel Elagin, Steffen
Liebergeld
@ -28,10 +28,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.RemoteInput;
import android.support.v4.content.LocalBroadcastManager;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
@ -44,11 +40,17 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Objects;
import androidx.core.app.NavUtils;
import androidx.core.app.NotificationCompat;
import androidx.core.app.RemoteInput;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
@ -56,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import static android.content.Intent.EXTRA_SUBJECT;
@ -82,6 +85,9 @@ public class DebugActivity extends AbstractGBActivity {
GB.toast(context, "got wearable reply: " + reply, Toast.LENGTH_SHORT, GB.INFO);
break;
}
case DeviceService.ACTION_REALTIME_SAMPLES:
handleRealtimeSample(intent.getSerializableExtra(DeviceService.EXTRA_REALTIME_SAMPLE));
break;
default:
LOG.info("ignoring intent action " + intent.getAction());
break;
@ -89,6 +95,13 @@ public class DebugActivity extends AbstractGBActivity {
}
};
private void handleRealtimeSample(Serializable extra) {
if (extra instanceof ActivitySample) {
ActivitySample sample = (ActivitySample) extra;
GB.toast(this, "Heart Rate measured: " + sample.getHeartRate(), Toast.LENGTH_LONG, GB.INFO);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -96,7 +109,7 @@ public class DebugActivity extends AbstractGBActivity {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_REPLY);
filter.addAction(DeviceService.ACTION_HEARTRATE_MEASUREMENT);
filter.addAction(DeviceService.ACTION_REALTIME_SAMPLES);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter);
registerReceiver(mReceiver, filter); // for ACTION_REPLY
@ -122,7 +135,6 @@ public class DebugActivity extends AbstractGBActivity {
notificationSpec.subject = testString;
notificationSpec.type = NotificationType.values()[sendTypeSpinner.getSelectedItemPosition()];
notificationSpec.pebbleColor = notificationSpec.type.color;
notificationSpec.id = -1;
GBApplication.deviceService().onNotification(notificationSpec);
}
});
@ -171,9 +183,33 @@ public class DebugActivity extends AbstractGBActivity {
rebootButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GBApplication.deviceService().onReboot();
GBApplication.deviceService().onReset(GBDeviceProtocol.RESET_FLAGS_REBOOT);
}
});
Button factoryResetButton = findViewById(R.id.factoryResetButton);
factoryResetButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(DebugActivity.this)
.setCancelable(true)
.setTitle(R.string.debugactivity_really_factoryreset_title)
.setMessage(R.string.debugactivity_really_factoryreset)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
GBApplication.deviceService().onReset(GBDeviceProtocol.RESET_FLAGS_FACTORY_RESET);
}
})
.setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
}
});
Button heartRateButton = findViewById(R.id.HeartRateButton);
heartRateButton.setOnClickListener(new View.OnClickListener() {
@Override
@ -225,6 +261,14 @@ public class DebugActivity extends AbstractGBActivity {
}
});
Button testPebbleKitNotificationButton = findViewById(R.id.testPebbleKitNotificationButton);
testPebbleKitNotificationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testPebbleKitNotification();
}
});
Button fetchDebugLogsButton = findViewById(R.id.fetchDebugLogsButton);
fetchDebugLogsButton.setOnClickListener(new View.OnClickListener() {
@Override
@ -258,14 +302,7 @@ public class DebugActivity extends AbstractGBActivity {
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String fileName = GBApplication.getLogPath();
if (fileName != null && fileName.length() > 0) {
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("*/*");
emailIntent.putExtra(EXTRA_SUBJECT, "Gadgetbridge log file");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(fileName)));
startActivity(Intent.createChooser(emailIntent, "Share File"));
}
shareLog();
}
})
.setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
@ -329,6 +366,13 @@ public class DebugActivity extends AbstractGBActivity {
}
}
private void testPebbleKitNotification() {
Intent pebbleKitIntent = new Intent("com.getpebble.action.SEND_NOTIFICATION");
pebbleKitIntent.putExtra("messageType", "PEBBLE_ALERT");
pebbleKitIntent.putExtra("notificationData", "[{\"title\":\"PebbleKitTest\",\"body\":\"sent from Gadgetbridge\"}]");
getApplicationContext().sendBroadcast(pebbleKitIntent);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, boun, Carsten Pfeiffer,
/* Copyright (C) 2015-2019 Andreas Shimokawa, boun, Carsten Pfeiffer,
Daniele Gobbetti, JohnnySun, jonnsoft, Lem Dulfo, Taavi Eomäe, Uwe Hermann
This file is part of Gadgetbridge.
@ -42,7 +42,6 @@ import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.Parcelable;
import android.support.v4.app.ActivityCompat;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
@ -57,6 +56,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import androidx.core.app.ActivityCompat;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.DeviceCandidateAdapter;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo, Uwe Hermann
This file is part of Gadgetbridge.
@ -20,8 +20,6 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@ -38,6 +36,8 @@ import java.util.List;
import java.util.Objects;
import java.util.UUID;
import androidx.annotation.NonNull;
import androidx.core.app.NavUtils;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2018 Andreas Shimokawa
/* Copyright (C) 2018-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -25,8 +26,6 @@ import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.RemoteInput;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.widget.Button;
@ -35,9 +34,8 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class FindPhoneActivity extends AbstractGBActivity {
@ -71,7 +69,6 @@ public class FindPhoneActivity extends AbstractGBActivity {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_FOUND);
filter.addAction(DeviceService.ACTION_HEARTRATE_MEASUREMENT);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter);
registerReceiver(mReceiver, filter); // for ACTION_FOUND
@ -101,9 +98,13 @@ public class FindPhoneActivity extends AbstractGBActivity {
mp.prepare();
mp.start();
} catch (IOException ignore) {
LOG.warn("problem playing ringtone");
}
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM), AudioManager.FLAG_PLAY_SOUND);
if (mAudioManager != null) {
userVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM), AudioManager.FLAG_PLAY_SOUND);
}
}
public void stopSound() {

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo
This file is part of Gadgetbridge.
@ -23,8 +23,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v4.content.LocalBroadcastManager;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
@ -39,6 +37,8 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import androidx.core.app.NavUtils;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.ItemWithDetailsAdapter;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Carsten Pfeiffer
/* Copyright (C) 2016-2019 Carsten Pfeiffer, Dikay900
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -0,0 +1,232 @@
/* Copyright (C) 2018-2019 abettenburg, AndrewBedscastle, Daniele Gobbetti
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import de.greenrobot.dao.query.Query;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.AppBlacklistAdapter;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilter;
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterDao;
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntry;
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntryDao;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class NotificationFilterActivity extends AbstractGBActivity {
public static final int NOTIFICATION_FILTER_MODE_NONE = 0;
public static final int NOTIFICATION_FILTER_MODE_WHITELIST = 1;
public static final int NOTIFICATION_FILTER_MODE_BLACKLIST = 2;
public static final int NOTIFICATION_FILTER_SUBMODE_ANY = 0;
public static final int NOTIFICATION_FILTER_SUBMODE_ALL = 1;
private Button mButtonSave;
private Spinner mSpinnerFilterMode;
private Spinner mSpinnerFilterSubMode;
private NotificationFilter mNotificationFilter;
private EditText mEditTextWords;
private List<String> mWordsList = new ArrayList<>();
private List<Long> mFilterEntryIds = new ArrayList<>();
private static final Logger LOG = LoggerFactory.getLogger(NotificationFilterActivity.class);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification_filter);
String packageName = getIntent().getStringExtra(AppBlacklistAdapter.STRING_EXTRA_PACKAGE_NAME);
if (StringUtils.isBlank(packageName)) {
this.finish();
}
packageName = packageName.toLowerCase();
try (DBHandler db = GBApplication.acquireDB()) {
NotificationFilterDao notificationFilterDao = db.getDaoSession().getNotificationFilterDao();
NotificationFilterEntryDao notificationFilterEntryDao = db.getDaoSession().getNotificationFilterEntryDao();
Query<NotificationFilter> query = notificationFilterDao.queryBuilder().where(NotificationFilterDao.Properties.AppIdentifier.eq(packageName)).build();
mNotificationFilter = query.unique();
if (mNotificationFilter == null) {
mNotificationFilter = new NotificationFilter();
mNotificationFilter.setAppIdentifier(packageName);
LOG.debug("New Notification Filter");
} else {
LOG.debug("Loaded existing notification filter");
Query<NotificationFilterEntry> queryEntries = notificationFilterEntryDao.queryBuilder().where(NotificationFilterEntryDao.Properties.NotificationFilterId.eq(mNotificationFilter.getId())).build();
List<NotificationFilterEntry> filterEntries = queryEntries.list();
for (NotificationFilterEntry temp : filterEntries) {
mWordsList.add(temp.getNotificationFilterContent());
mFilterEntryIds.add(temp.getId());
LOG.debug("Loaded filter word: " + temp.getNotificationFilterContent());
}
}
setupView(db);
} catch (Exception e) {
GB.toast(this, "Error accessing the database: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR);
this.finish();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private void setupView(DBHandler db) {
mSpinnerFilterMode = findViewById(R.id.spinnerFilterMode);
mSpinnerFilterMode.setSelection(mNotificationFilter.getNotificationFilterMode());
mSpinnerFilterSubMode = findViewById(R.id.spinnerSubMode);
mSpinnerFilterMode.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long id) {
switch (pos) {
case NOTIFICATION_FILTER_MODE_NONE:
mEditTextWords.setEnabled(false);
mSpinnerFilterSubMode.setEnabled(false);
break;
case NOTIFICATION_FILTER_MODE_BLACKLIST:
case NOTIFICATION_FILTER_MODE_WHITELIST:
mEditTextWords.setEnabled(true);
mSpinnerFilterSubMode.setEnabled(true);
break;
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
mSpinnerFilterSubMode.setSelection(mNotificationFilter.getNotificationFilterSubMode());
mEditTextWords = findViewById(R.id.editTextWords);
if (!mWordsList.isEmpty()) {
StringBuilder builder = new StringBuilder();
for (String temp : mWordsList) {
builder.append(temp);
builder.append("\n");
}
mEditTextWords.setText(builder.toString());
}
mEditTextWords.setEnabled(mSpinnerFilterMode.getSelectedItemPosition() == NOTIFICATION_FILTER_MODE_NONE);
mButtonSave = findViewById(R.id.buttonSaveFilter);
mButtonSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
saveFilter();
}
});
}
private void saveFilter() {
// TODO: check for modifications, only save if something changed
String words = mEditTextWords.getText().toString();
if (StringUtils.isBlank(words) && mSpinnerFilterMode.getSelectedItemPosition() != NOTIFICATION_FILTER_MODE_NONE) {
Toast.makeText(NotificationFilterActivity.this, R.string.toast_notification_filter_words_empty_hint, Toast.LENGTH_SHORT).show();
return;
}
try (DBHandler db = GBApplication.acquireDB()) {
NotificationFilterDao notificationFilterDao = db.getDaoSession().getNotificationFilterDao();
NotificationFilterEntryDao notificationFilterEntryDao = db.getDaoSession().getNotificationFilterEntryDao();
debugOutput(notificationFilterDao);
mNotificationFilter.setNotificationFilterMode(mSpinnerFilterMode.getSelectedItemPosition());
mNotificationFilter.setNotificationFilterSubMode(mSpinnerFilterSubMode.getSelectedItemPosition());
notificationFilterEntryDao.deleteByKeyInTx(mFilterEntryIds);
Long filterId = notificationFilterDao.insertOrReplace(mNotificationFilter);
// only save words if filter mode != none
if (mNotificationFilter.getNotificationFilterMode() != NOTIFICATION_FILTER_MODE_NONE) {
String[] wordsSplitted = words.split("\n");
for (String temp : wordsSplitted) {
if (StringUtils.isBlank(temp)) {
continue;
}
temp = temp.trim();
NotificationFilterEntry notificationFilterEntry = new NotificationFilterEntry();
notificationFilterEntry.setNotificationFilterContent(temp);
notificationFilterEntry.setNotificationFilterId(filterId);
notificationFilterEntryDao.insert(notificationFilterEntry);
}
}
Toast.makeText(NotificationFilterActivity.this, R.string.toast_notification_filter_saved_successfully, Toast.LENGTH_SHORT).show();
NotificationFilterActivity.this.finish();
} catch (Exception e) {
GB.toast(NotificationFilterActivity.this, "Error accessing the database: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR);
}
}
/**
* Only used for debugging purposes
*
* @param notificationFilterDao {@link NotificationFilterDao}
*/
private void debugOutput(NotificationFilterDao notificationFilterDao) {
if (BuildConfig.DEBUG) {
List<NotificationFilter> filters = notificationFilterDao.loadAll();
LOG.info("Saved filters");
for (NotificationFilter temp : filters) {
LOG.info("Filter: " + temp.getId() + " " + temp.getAppIdentifier());
}
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 0nse, Andreas Shimokawa, Carsten Pfeiffer,
/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Felix Konstantin Maurer, José Rebelo, Martin, Normano64,
Pavel Elagin
@ -36,8 +36,6 @@ import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.widget.Toast;
import org.slf4j.Logger;
@ -48,6 +46,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import androidx.core.app.ActivityCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
@ -63,8 +63,16 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION_END;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION_START;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ON_LIFT_END;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ON_LIFT_START;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DISPLAY_ITEMS;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_OFF;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_SCHEDULED;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ENABLE_TEXT_NOTIFICATIONS;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI3_BAND_SCREEN_UNLOCK;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI3_NIGHT_MODE;
@ -506,6 +514,59 @@ public class SettingsActivity extends AbstractSettingsActivity {
}
});
String disconnectNotificationState = prefs.getString(PREF_DISCONNECT_NOTIFICATION, PREF_MI2_DO_NOT_DISTURB_OFF);
boolean disconnectNotificationScheduled = disconnectNotificationState.equals(PREF_MI2_DO_NOT_DISTURB_SCHEDULED);
final Preference disconnectNotificationStart = findPreference(PREF_DISCONNECT_NOTIFICATION_START);
disconnectNotificationStart.setEnabled(disconnectNotificationScheduled);
disconnectNotificationStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_START);
}
});
return true;
}
});
final Preference disconnectNotificationEnd = findPreference(PREF_DISCONNECT_NOTIFICATION_END);
disconnectNotificationStart.setEnabled(disconnectNotificationScheduled);
disconnectNotificationStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_END);
}
});
return true;
}
});
final Preference disconnectNotification = findPreference(PREF_DISCONNECT_NOTIFICATION);
disconnectNotification.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
final boolean scheduled = PREF_MI2_DO_NOT_DISTURB_SCHEDULED.equals(newVal.toString());
disconnectNotificationStart.setEnabled(scheduled);
disconnectNotificationEnd.setEnabled(scheduled);
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION);
}
});
return true;
}
});
// Get all receivers of Media Buttons
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Konrad Iturbe, Lem Dulfo
This file is part of Gadgetbridge.
@ -24,12 +24,6 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@ -37,6 +31,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupMenu;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -47,6 +43,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.ExternalPebbleJSActivity;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -20,14 +20,11 @@ package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.view.MenuItem;
import android.view.View;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -40,6 +37,10 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import androidx.core.app.NavUtils;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractFragmentPagerAdapter;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBFragmentActivity;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa
/* Copyright (C) 2016-2019 Andreas Shimokawa
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Daniele Gobbetti
/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa
/* Copyright (C) 2016-2019 Andreas Shimokawa
This file is part of Gadgetbridge.

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2018 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, walkjivefly
/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Dikay900, Pavel Elagin, walkjivefly
This file is part of Gadgetbridge.
@ -23,10 +23,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.TypedValue;
import android.view.View;
@ -55,6 +51,10 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBFragment;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2018 0nse, Alberto, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti
/* Copyright (C) 2015-2019 0nse, Alberto, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Pavel Elagin
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Pavel Elagin, Vebryn
This file is part of Gadgetbridge.
@ -17,12 +17,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import java.util.HashMap;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmount;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Pavel Elagin
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, Pavel Elagin
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Vebryn
This file is part of Gadgetbridge.
@ -23,12 +23,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
@ -43,6 +37,12 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewpager.widget.ViewPager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractFragmentPagerAdapter;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Carsten Pfeiffer
/* Copyright (C) 2016-2019 Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, Pavel, Pavel Elagin
This file is part of Gadgetbridge.
@ -22,9 +23,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -55,6 +53,9 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
@ -63,7 +64,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.Measurement;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class LiveActivityFragment extends AbstractChartFragment {

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Carsten Pfeiffer
/* Copyright (C) 2015-2019 Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2018 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Pavel Elagin
/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Dikay900, Pavel Elagin
This file is part of Gadgetbridge.
@ -20,7 +20,6 @@ package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -49,6 +48,7 @@ import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import androidx.annotation.Nullable;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 0nse, Andreas Shimokawa, Carsten Pfeiffer,
/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Vebryn
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Carsten Pfeiffer
/* Copyright (C) 2016-2019 Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Carsten Pfeiffer
/* Copyright (C) 2016-2019 Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2018 Andreas Shimokawa, Carsten Pfeiffer, Pavel Elagin
/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Pavel Elagin
This file is part of Gadgetbridge.
@ -74,7 +74,7 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
@Override
protected String getBalanceMessage(long balance, int targetValue) {
if (balance > 0) {
final long totalBalance = balance - (targetValue * TOTAL_DAYS);
final long totalBalance = balance - ((long)targetValue * TOTAL_DAYS);
if (totalBalance > 0)
return getString(R.string.overslept, getHM(totalBalance));
else

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2018 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti
/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Pavel Elagin
This file is part of Gadgetbridge.
@ -105,7 +105,7 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment {
@Override
protected String getBalanceMessage(long balance, int targetValue) {
if (balance > 0) {
final long totalBalance = balance - (targetValue * TOTAL_DAYS);
final long totalBalance = balance - ((long)targetValue * TOTAL_DAYS);
if (totalBalance > 0)
return getString(R.string.overstep, Math.abs(totalBalance));
else

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -17,7 +18,6 @@
package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.content.Context;
import android.support.annotation.DrawableRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -28,6 +28,7 @@ import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.DrawableRes;
import nodomain.freeyourgadget.gadgetbridge.R;
/**

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2018 Carsten Pfeiffer, Daniele Gobbetti
/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti
This file is part of Gadgetbridge.

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2017-2018 Carsten Pfeiffer, Daniele Gobbetti
/* Copyright (C) 2017-2019 abettenburg, AndrewBedscastle, Carsten Pfeiffer,
Daniele Gobbetti
This file is part of Gadgetbridge.
@ -17,9 +18,9 @@
package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -28,6 +29,7 @@ import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
@ -37,13 +39,18 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set;
import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.NotificationFilterActivity;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.packageNameToPebbleMsgSender;
public class AppBlacklistAdapter extends RecyclerView.Adapter<AppBlacklistAdapter.AppBLViewHolder> implements Filterable {
public static final String STRING_EXTRA_PACKAGE_NAME = "packageName";
private List<ApplicationInfo> applicationInfoList;
private final int mLayoutId;
private final Context mContext;
@ -91,7 +98,7 @@ public class AppBlacklistAdapter extends RecyclerView.Adapter<AppBlacklistAdapte
}
@Override
public void onBindViewHolder(AppBlacklistAdapter.AppBLViewHolder holder, int position) {
public void onBindViewHolder(final AppBlacklistAdapter.AppBLViewHolder holder, int position) {
final ApplicationInfo appInfo = applicationInfoList.get(position);
holder.deviceAppVersionAuthorLabel.setText(appInfo.packageName);
@ -105,7 +112,7 @@ public class AppBlacklistAdapter extends RecyclerView.Adapter<AppBlacklistAdapte
@Override
public void onClick(View view) {
((CheckedTextView) view).toggle();
if ( ((CheckedTextView)view).isChecked() ) {
if (((CheckedTextView) view).isChecked()) {
GBApplication.addAppToPebbleBlacklist(appInfo.packageName);
} else {
GBApplication.removeFromAppsPebbleBlacklist(appInfo.packageName);
@ -116,7 +123,7 @@ public class AppBlacklistAdapter extends RecyclerView.Adapter<AppBlacklistAdapte
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckedTextView checkBox = ((CheckedTextView) v.findViewById(R.id.item_checkbox));
CheckedTextView checkBox = (v.findViewById(R.id.item_checkbox));
checkBox.toggle();
if (checkBox.isChecked()) {
GBApplication.addAppToNotifBlacklist(appInfo.packageName);
@ -126,6 +133,19 @@ public class AppBlacklistAdapter extends RecyclerView.Adapter<AppBlacklistAdapte
}
});
holder.btnConfigureApp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (holder.blacklist_checkbox.isChecked()) {
GB.toast(mContext, mContext.getString(R.string.toast_app_must_not_be_blacklisted), Toast.LENGTH_SHORT, GB.INFO);
} else {
Intent intentStartNotificationFilterActivity = new Intent(mContext, NotificationFilterActivity.class);
intentStartNotificationFilterActivity.putExtra(STRING_EXTRA_PACKAGE_NAME, appInfo.packageName);
mContext.startActivity(intentStartNotificationFilterActivity);
}
}
});
}
public void blacklistAllNotif() {
@ -163,15 +183,17 @@ public class AppBlacklistAdapter extends RecyclerView.Adapter<AppBlacklistAdapte
final ImageView deviceImageView;
final TextView deviceAppVersionAuthorLabel;
final TextView deviceAppNameLabel;
final ImageView btnConfigureApp;
AppBLViewHolder(View itemView) {
super(itemView);
blacklist_checkbox = (CheckedTextView) itemView.findViewById(R.id.item_checkbox);
blacklist_pebble_checkbox = (CheckedTextView) itemView.findViewById(R.id.item_pebble_checkbox);
deviceImageView = (ImageView) itemView.findViewById(R.id.item_image);
deviceAppVersionAuthorLabel = (TextView) itemView.findViewById(R.id.item_details);
deviceAppNameLabel = (TextView) itemView.findViewById(R.id.item_name);
blacklist_checkbox = itemView.findViewById(R.id.item_checkbox);
blacklist_pebble_checkbox = itemView.findViewById(R.id.item_pebble_checkbox);
deviceImageView = itemView.findViewById(R.id.item_image);
deviceAppVersionAuthorLabel = itemView.findViewById(R.id.item_details);
deviceAppNameLabel = itemView.findViewById(R.id.item_name);
btnConfigureApp = itemView.findViewById(R.id.btn_configureApp);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -19,8 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -30,78 +28,52 @@ import android.widget.Switch;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
/**
* Adapter for displaying GBAlarm instances.
*/
public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.ViewHolder> {
private final Context mContext;
private List<GBAlarm> alarmList;
private ArrayList<Alarm> alarmList;
public GBAlarmListAdapter(Context context, List<GBAlarm> alarmList) {
public GBAlarmListAdapter(Context context) {
this.mContext = context;
this.alarmList = alarmList;
}
public GBAlarmListAdapter(Context context, Set<String> preferencesAlarmListSet) {
this.mContext = context;
alarmList = new ArrayList<>();
for (String alarmString : preferencesAlarmListSet) {
alarmList.add(new GBAlarm(alarmString));
}
Collections.sort(alarmList);
public void setAlarmList(List<Alarm> alarms) {
this.alarmList = new ArrayList<>(alarms);
}
public void setAlarmList(Set<String> preferencesAlarmListSet, int reservedSlots) {
alarmList = new ArrayList<>();
for (String alarmString : preferencesAlarmListSet) {
alarmList.add(new GBAlarm(alarmString));
}
Collections.sort(alarmList);
//cannot do this earlier because the Set is not guaranteed to be in order by ID
alarmList.subList(alarmList.size() - reservedSlots, alarmList.size()).clear();
public ArrayList<Alarm> getAlarmList() {
return alarmList;
}
public ArrayList<? extends Alarm> getAlarmList() {
return (ArrayList) alarmList;
}
public void update(GBAlarm alarm) {
for (GBAlarm a : alarmList) {
if (alarm.equals(a)) {
a = alarm;
}
}
alarm.store();
private void updateInDB(Alarm alarm) {
DBHelper.store(alarm);
}
@NonNull
@Override
public GBAlarmListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
public GBAlarmListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_alarm, parent, false);
ViewHolder vh = new ViewHolder(view);
return vh;
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
final GBAlarm alarm = alarmList.get(position);
final Alarm alarm = alarmList.get(position);
holder.alarmDayMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON));
holder.alarmDayTuesday.setChecked(alarm.getRepetition(Alarm.ALARM_TUE));
@ -115,7 +87,7 @@ public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
alarm.setEnabled(isChecked);
update(alarm);
updateInDB(alarm);
}
});
@ -125,16 +97,15 @@ public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.
((ConfigureAlarms) mContext).configureAlarm(alarm);
}
});
holder.alarmTime.setText(alarm.getTime());
holder.isEnabled.setChecked(alarm.isEnabled());
if (alarm.isSmartWakeup()) {
holder.alarmTime.setText(DateTimeUtils.formatTime(alarm.getHour(), alarm.getMinute()));
holder.isEnabled.setChecked(alarm.getEnabled());
if (alarm.getSmartWakeup()) {
holder.isSmartWakeup.setVisibility(TextView.VISIBLE);
} else {
holder.isSmartWakeup.setVisibility(TextView.GONE);
}
}
@Override
public int getItemCount() {
return alarmList.size();
@ -159,21 +130,19 @@ public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.
ViewHolder(View view) {
super(view);
container = (CardView) view.findViewById(R.id.card_view);
alarmTime = (TextView) view.findViewById(R.id.alarm_item_time);
isEnabled = (Switch) view.findViewById(R.id.alarm_item_toggle);
isSmartWakeup = (TextView) view.findViewById(R.id.alarm_smart_wakeup);
alarmDayMonday = (CheckedTextView) view.findViewById(R.id.alarm_item_monday);
alarmDayTuesday = (CheckedTextView) view.findViewById(R.id.alarm_item_tuesday);
alarmDayWednesday = (CheckedTextView) view.findViewById(R.id.alarm_item_wednesday);
alarmDayThursday = (CheckedTextView) view.findViewById(R.id.alarm_item_thursday);
alarmDayFriday = (CheckedTextView) view.findViewById(R.id.alarm_item_friday);
alarmDaySaturday = (CheckedTextView) view.findViewById(R.id.alarm_item_saturday);
alarmDaySunday = (CheckedTextView) view.findViewById(R.id.alarm_item_sunday);
container = view.findViewById(R.id.card_view);
alarmTime = view.findViewById(R.id.alarm_item_time);
isEnabled = view.findViewById(R.id.alarm_item_toggle);
isSmartWakeup = view.findViewById(R.id.alarm_smart_wakeup);
alarmDayMonday = view.findViewById(R.id.alarm_item_monday);
alarmDayTuesday = view.findViewById(R.id.alarm_item_tuesday);
alarmDayWednesday = view.findViewById(R.id.alarm_item_wednesday);
alarmDayThursday = view.findViewById(R.id.alarm_item_thursday);
alarmDayFriday = view.findViewById(R.id.alarm_item_friday);
alarmDaySaturday = view.findViewById(R.id.alarm_item_saturday);
alarmDaySunday = view.findViewById(R.id.alarm_item_sunday);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, José Rebelo, Lem Dulfo, maxirnilian
This file is part of Gadgetbridge.
@ -23,11 +23,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.GradientDrawable;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.text.InputType;
import android.transition.TransitionManager;
import android.view.LayoutInflater;
@ -43,12 +38,17 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import com.jaredrummler.android.colorpicker.ColorPickerDialog;
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.ActivitySummariesActivity;
@ -196,7 +196,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
);
//set alarms
holder.setAlarmsView.setVisibility(coordinator.supportsAlarmConfiguration() ? View.VISIBLE : View.GONE);
holder.setAlarmsView.setVisibility(coordinator.getAlarmSlotCount() > 0 ? View.VISIBLE : View.GONE);
holder.setAlarmsView.setOnClickListener(new View.OnClickListener()
{

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -17,7 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@ -29,6 +28,7 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AbstractAppManagerFragment;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -25,9 +26,9 @@ import android.content.IntentFilter;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import androidx.annotation.NonNull;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, JohnnySun
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Felix Konstantin Maurer, JohnnySun
This file is part of Gadgetbridge.
@ -21,9 +21,6 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -33,19 +30,25 @@ import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.greenrobot.dao.Property;
import de.greenrobot.dao.query.Query;
import de.greenrobot.dao.query.QueryBuilder;
import de.greenrobot.dao.query.WhereCondition;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.entities.ActivityDescription;
import nodomain.freeyourgadget.gadgetbridge.entities.ActivityDescriptionDao;
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributes;
@ -62,6 +65,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ValidByDate;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
/**
@ -362,6 +366,13 @@ public class DBHelper {
return true;
}
/**
* Finds the corresponding Device entity for the given GBDevice.
* @param gbDevice
* @param session
* @return the corresponding Device entity, or null if none
*/
@Nullable
public static Device findDevice(GBDevice gbDevice, DaoSession session) {
DeviceDao deviceDao = session.getDeviceDao();
Query<Device> query = deviceDao.queryBuilder().where(DeviceDao.Properties.Identifier.eq(gbDevice.getAddress())).build();
@ -561,6 +572,49 @@ public class DBHelper {
return tag;
}
/**
* Returns all user-configurable alarms for the given user and device. The list is sorted by
* {@link Alarm#position}. Calendar events that may also be modeled as alarms are not stored
* in the database and hence not returned by this method.
* @param gbDevice the device for which the alarms shall be loaded
* @return the list of alarms for the given device
*/
@NonNull
public static List<Alarm> getAlarms(@NonNull GBDevice gbDevice) {
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
Prefs prefs = GBApplication.getPrefs();
// TODO: this alarm reservation is a device dependent detail
int reservedSlots = prefs.getInt(MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR, 0);
int alarmSlots = coordinator.getAlarmSlotCount();
try (DBHandler db = GBApplication.acquireDB()) {
DaoSession daoSession = db.getDaoSession();
User user = getUser(daoSession);
Device dbDevice = DBHelper.findDevice(gbDevice, daoSession);
if (dbDevice != null) {
AlarmDao alarmDao = daoSession.getAlarmDao();
Long deviceId = dbDevice.getId();
QueryBuilder<Alarm> qb = alarmDao.queryBuilder();
qb.where(
AlarmDao.Properties.UserId.eq(user.getId()),
AlarmDao.Properties.DeviceId.eq(deviceId)).orderAsc(AlarmDao.Properties.Position).limit(alarmSlots - reservedSlots);
return qb.build().list();
}
} catch (Exception e) {
LOG.warn("Error reading alarms from db", e);
}
return Collections.emptyList();
}
public static void store(Alarm alarm) {
try (DBHandler db = GBApplication.acquireDB()) {
DaoSession daoSession = db.getDaoSession();
daoSession.insertOrReplace(alarm);
} catch (Exception e) {
LOG.error("Error acquiring database", e);
}
}
public static void clearSession() {
try (DBHandler dbHandler = GBApplication.acquireDB()) {
DaoSession session = dbHandler.getDaoSession();

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2018 Carsten Pfeiffer, Felix Konstantin Maurer
/* Copyright (C) 2018-2019 Carsten Pfeiffer, Felix Konstantin Maurer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa
/* Copyright (C) 2016-2019 Andreas Shimokawa
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa
/* Copyright (C) 2016-2019 Andreas Shimokawa
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2018 protomors
/* Copyright (C) 2017-2019 protomors
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa
/* Copyright (C) 2015-2019 Andreas Shimokawa
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa, Daniele Gobbetti
/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti, José Rebelo
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa
/* Copyright (C) 2015-2019 Andreas Shimokawa
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa
/* Copyright (C) 2015-2019 Andreas Shimokawa
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2018 José Rebelo
/* Copyright (C) 2015-2019 Andreas Shimokawa, José Rebelo
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2018 José Rebelo
/* Copyright (C) 2015-2019 Andreas Shimokawa, José Rebelo
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa
/* Copyright (C) 2015-2019 Andreas Shimokawa
This file is part of Gadgetbridge.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2018 Andreas Shimokawa
/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti
This file is part of Gadgetbridge.
@ -17,9 +17,10 @@
package nodomain.freeyourgadget.gadgetbridge.deviceevents;
public class GBDeviceEventNotificationControl extends GBDeviceEvent {
public int handle;
public long handle;
public String phoneNumber;
public String reply;
public String title;
public Event event = Event.UNKNOWN;
public enum Event {

Some files were not shown because too many files have changed in this diff Show More