mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-01 06:22:55 +01:00
Merge branch 'master' of https://github.com/Freeyourgadget/Gadgetbridge into zetime
This commit is contained in:
commit
6a04c78b0e
3
.gitignore
vendored
3
.gitignore
vendored
@ -31,3 +31,6 @@ proguard/
|
||||
MPChartLib
|
||||
|
||||
fw.dirs
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.classpath
|
||||
|
2
.settings/org.eclipse.buildship.core.prefs
Normal file
2
.settings/org.eclipse.buildship.core.prefs
Normal file
@ -0,0 +1,2 @@
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
@ -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
|
||||
|
53
CHANGELOG.md
53
CHANGELOG.md
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
38
README.md
38
README.md
@ -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
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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>
|
@ -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>
|
@ -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
|
@ -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">
|
||||
|
@ -9,7 +9,7 @@ navigator.geolocation.getCurrentPosition = function(success, failure, options) {
|
||||
reportedPositionFailures = 0;
|
||||
success(geoposition);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (window.Storage){
|
||||
var prefix = GBjs.getAppLocalstoragePrefix();
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2018 Carsten Pfeiffer
|
||||
/* Copyright (C) 2015-2019 Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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());
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2018 Carsten Pfeiffer
|
||||
/* Copyright (C) 2016-2019 Carsten Pfeiffer, Dikay900
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2018 Andreas Shimokawa
|
||||
/* Copyright (C) 2016-2019 Andreas Shimokawa
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2018 Andreas Shimokawa
|
||||
/* Copyright (C) 2016-2019 Andreas Shimokawa
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2018 Carsten Pfeiffer
|
||||
/* Copyright (C) 2016-2019 Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2018 Carsten Pfeiffer
|
||||
/* Copyright (C) 2015-2019 Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2018 Carsten Pfeiffer
|
||||
/* Copyright (C) 2016-2019 Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2018 Carsten Pfeiffer
|
||||
/* Copyright (C) 2016-2019 Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2018 Andreas Shimokawa
|
||||
/* Copyright (C) 2016-2019 Andreas Shimokawa
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2018 Andreas Shimokawa
|
||||
/* Copyright (C) 2016-2019 Andreas Shimokawa
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017-2018 protomors
|
||||
/* Copyright (C) 2017-2019 protomors
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2018 Andreas Shimokawa
|
||||
/* Copyright (C) 2015-2019 Andreas Shimokawa
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2018 Andreas Shimokawa
|
||||
/* Copyright (C) 2015-2019 Andreas Shimokawa
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2018 Andreas Shimokawa
|
||||
/* Copyright (C) 2015-2019 Andreas Shimokawa
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2018 José Rebelo
|
||||
/* Copyright (C) 2015-2019 Andreas Shimokawa, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2018 José Rebelo
|
||||
/* Copyright (C) 2015-2019 Andreas Shimokawa, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2018 Andreas Shimokawa
|
||||
/* Copyright (C) 2015-2019 Andreas Shimokawa
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user