Merge branch 'master' of codeberg.org:Freeyourgadget/Gadgetbridge into ble-scan-before-reconnect

This commit is contained in:
Daniel Dakhno 2024-02-12 22:10:51 +01:00
commit 4385b1bd97
2105 changed files with 62436 additions and 11903 deletions

View File

@ -1,49 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
---
You can use the `Preview` tab ^ above to see final rendering of your report. Use `x` in brackets ([x]) to "check" a checkbox.
If you just have a question, please ask first in the user chatroom in Matrix: [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
#### Before reporting a bug, please confirm the following:
- [ ] I have read the [wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki), and I didn't find a solution to my problem / an answer to my question.
- [ ] I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
- [ ] If you upload an image or other content, please make sure you have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md)
### Where did you get Gadgetbridge from:
* [ ] F-Droid
* [ ] Gadgetbridge Nightly F-Droid repository
* [ ] Bangle.js Gadgetbridge from the Play Store
* [ ] I built it myself from source code (specify tag / commit)
* [ ] I previously used Gadgetbridge from other sources and then updated to F-Droid version
### Your Gadgetbridge version is:
(This can be found in Gadgetbridge - Menu - About: Version and Commit)
#### Your issue is:
*If possible, please attach [logs](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Log-Files)! that might help identifying the problem.*
*Long logs can be also included but make sure to tuck them into the `details` tag:*
<details>
<summary>Click to see my log under this fold</summary>
```
Here go lines of your log.
```
</details>
#### Your wearable device is:
*Please specify model and firmware version if possible*
#### Your Android version/manufacturer flavor is:
*New issues about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
Please use `Preview` tab above to see final rendering of your report before submitting.

View File

@ -1,49 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
---
You can use the `Preview` tab ^ above to see final rendering of your report. Use `x` in brackets ([x]) to "check" a checkbox.
If you just have a question, please ask first in the user chatroom in Matrix: [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
#### Before reporting a bug, please confirm the following:
- [ ] I have read the [wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki), and I didn't find a solution to my problem / an answer to my question.
- [ ] I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
- [ ] If you upload an image or other content, please make sure you have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md)
### Where did you get Gadgetbridge from:
* [ ] F-Droid
* [ ] Gadgetbridge Nightly F-Droid repository
* [ ] Bangle.js Gadgetbridge from the Play Store
* [ ] I built it myself from source code (specify tag / commit)
* [ ] I previously used Gadgetbridge from other sources and then updated to F-Droid version
### Your Gadgetbridge version is:
(This can be found in Gadgetbridge - Menu - About: Version and Commit)
#### Your issue is:
*If possible, please attach [logs](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Log-Files)! that might help identifying the problem.*
*Long logs can be also included but make sure to tuck them into the `details` tag:*
<details>
<summary>Click to see my log under this fold</summary>
```
Here go lines of your log.
```
</details>
#### Your wearable device is:
*Please specify model and firmware version if possible*
#### Your Android version/manufacturer flavor is:
*New issues about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
Please use `Preview` tab above to see final rendering of your report before submitting.

View File

@ -1,51 +0,0 @@
---
name: Device request
about: Request for a new device
labels:
- device request
---
You are trying to submit a request for a device implementation into Gadgetbridge. We cannot make any promise that the device will be implemented, as adding an implementation for a new device requires either an experienced or a willing to learn developer, ideally with the device at hand. Without that, you may try to submit a device request and see if anyone steps up and implements it and you are basically indicating that you have the device and are willing to help with testing, should anyone try to add this device to Gadgetbridge.
You can use the `Preview` tab ^ above to see final rendering of your report. Use `x` in brackets ([x]) to "check" a checkbox.
#### Before proceeding further, please confirm the following:
- [ ] I have read the [wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki), and I didn't find this device mentioned there
- [ ] I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find this device mentioned there
- [ ] Please make sure you have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md)
#### Device information
- Provide device name, manufacturer and similarity to other devices:
- Ideally, use an Android Bluetooth scanner app like nRF Connect or BLExplorer and provide screenshots of the scanned device from that app. This provides a name and some available UUIDs, which are needed for implementation. You may want to blur a MAC address for privacy reasons.
- Specify model and firmware version if possible:
- Please let us know if you have the device and if you are able to provide logs and testing:
- If you want to help getting this device supported (and thus speed up the process), please take a look at:
- what you can do as a user: [Support for a new Device](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Support-for-a-new-Device)
- if you are a developer and could maybe even help getting the code ready: [New Device Tutorial](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/New-Device-Tutorial)
- If possible, please attach [logs](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Log-Files)! which might help to implement the device support into Gadgetbridge.
*Long logs can be also included in the text but make sure to tuck them into the `details` tag below:*
<details>
<summary>Click to see my log under this fold</summary>
```
Here go lines of your log.
```
</details>
*New issues about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
Please use `Preview` tab above to see final rendering of your report before submitting.

View File

@ -1,40 +0,0 @@
---
name: Feature request
about: Suggest a feature or an idea
---
You can use the `Preview` tab ^ above to see final rendering of your report. Use `x` in brackets ([x]) to "check" a checkbox.
If you just have a question, please ask first in the user chatroom in Matrix: [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
#### Before requesting a new feature, please confirm the following:
- [ ] I have read the [wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki), and I didn't find a solution to my problem / an answer to my question.
- [ ] I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
- [ ] If you upload an image or other content, please make sure you have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md)
#### Log files
*If applicable, please attach [logs](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Log-Files)*
*Long logs can be also included in the text but make sure to tuck them into the `details` tag below:*
<details>
<summary>Click to see my log under this fold</summary>
```
Here go lines of your log.
```
</details>
#### Your wearable device is:
*Please specify model and firmware version if possible*
#### Your Android version/manufacturer flavor is:
#### Your Gadgetbridge version is:
*New requests about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
Please use `Preview` tab above to see final rendering of your report before submitting.

View File

@ -1,14 +0,0 @@
Thank you for your contribution! 🎉
Please make sure that you:
- Use `git rebase` to bring your branch up to date, do not use a merge commit
for that
- Do not add translations by editing the language variants of strings.xml as
that creates merge conflicts between Codeberg git repo and Weblate git repo,
use Weblate https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/
- do not use `e.printStacktrace()`, use slf4j logger or `GB.toast` for logging
as per https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Developer-Documentation#logging
- Please erase these hints from this PR :), thank you!
---

View File

@ -0,0 +1,77 @@
name: Bug report
about: Create a report to help us improve.
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to make Gadgetbridge better!
If you just have a question, please ask first in the user chatroom in Matrix at [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
- type: checkboxes
attributes:
label: Please confirm that;
options:
- label: I have checked the [website](https://gadgetbridge.org), and I didn't find a solution to my problem / an answer to my question.
required: true
- label: I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
required: true
- label: I have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md) for images or other type of content that I included here.
required: true
- type: dropdown
id: source
attributes:
label: Where did you get Gadgetbridge from?
options:
- F-Droid
- Gadgetbridge Nightly F-Droid repository
- Bangle.js Gadgetbridge from the Play Store
- I built it myself from source code
- I previously used Gadgetbridge from other sources and then updated to F-Droid version
validations:
required: true
- type: input
id: version
attributes:
label: What is your Gadgetbridge version?
description: |
This can be found in "Menu > About > Version" in Gadgetbridge.
Also include tag / commit SHA if you built Gadgetbridge from the source.
placeholder: e.g. "0.77.0" or "0.77.0-2618adac1" to include commit
validations:
required: true
- type: textarea
id: content
attributes:
label: What happened?
description: >
Please note that new issues about already solved/documented topics
**could be closed without further comments.** Same for too generic or incomplete reports.
placeholder: If you want to include logs, don't include it here. Use the next text field for that.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Do you have logs?
description: >
If possible, please attach [logs](https://gadgetbridge.org/internals/topics/logs/)
that might help identifying the problem. This will be automatically formatted into
code, so no need for backticks.
render: shell
- type: input
id: gadget
attributes:
label: What gadget do you use?
description: >
Please specify model and firmware version if possible. Leave blank if you believe the
issue is not specific to the gadget that you currently use with Gadgetbridge.
placeholder: e.g. ExampleWatch A1 with 0.1 firmware
- type: input
id: android
attributes:
label: What is your Android version/manufacturer flavor?
description: >
Android phone manufacturers may customise the Android source code as they wish, so
if you are using a phone that running a vendor-exclusive system (like MIUI) or if
you use a custom ROM, make sure to also include the name of the OS/ROM.
placeholder: e.g. LineageOS 20 based on Android 13

View File

@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Ask a question
url: https://matrix.to/#/#gadgetbridge:matrix.org
about: If you just have a question, please ask in the user chatroom in Matrix.
- name: Website
url: https://gadgetbridge.org
about: Visit Gadgetbridge website for FAQ, getting started and common troubleshooting.
- name: See supported gadgets
url: https://gadgetbridge.org/gadgets/
about: List of all supported gadget vendors and models in Gadgetbridge.

View File

@ -0,0 +1,77 @@
name: Device request
about: Request for a new device/gadget.
labels:
- device request
body:
- type: markdown
attributes:
value: >
You are trying to submit a request for a device implementation into Gadgetbridge.
**We cannot make any promise that the device will be implemented**, as adding an implementation
for a new device requires either an experienced or a willing to learn developer,
ideally with the device at hand. Without that, you may try to submit a device request
and see if anyone steps up and implements it and you are basically indicating that you
have the device and are willing to help with testing, should anyone try to add
this device to Gadgetbridge.
- type: markdown
attributes:
value: |
Thanks for taking the time to make Gadgetbridge better!
If you just have a question, please ask first in the user chatroom in Matrix at [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
- type: checkboxes
attributes:
label: Please confirm that;
options:
- label: I have checked the [website](https://gadgetbridge.org) and [gadget list](https://gadgetbridge.org/gadgets/), and I didn't find this device mentioned there.
required: true
- label: I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find this device mentioned there.
required: true
- label: I have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md) for images or other type of content that I included here.
required: true
- type: input
id: gadget
attributes:
label: Which gadget are you requesting support for?
description: Please specify name, manufacturer, model and firmware version if possible.
placeholder: e.g. ExampleWatch A1 with 0.1 firmware
validations:
required: true
- type: input
id: version
attributes:
label: Does this gadget have similarities to other gadgets?
description: >
If the gadget you request support for has similarities to other gadgets that we currently support,
it is more likely for us (still, not guaranteed) to add support for your gadget too.
- type: textarea
id: info
attributes:
label: Device information
description: >
Include all details about the gadget that will be useful to us when implementing a support for this gadget.
Ideally, use an Android Bluetooth scanner app like nRF Connect or BLExplorer and provide screenshots
of the scanned gadget from that app. This provides a name and some available UUIDs, which are needed
for implementation. You may want to blur MAC addresses for privacy reasons.
placeholder: If you want to include logs, don't include it here. Use the next text field for that.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Do you have logs?
description: >
If possible, please attach [logs](https://gadgetbridge.org/internals/topics/logs/)
which might help to implement the device support into Gadgetbridge. This will be automatically
formatted into code, so no need for backticks.
render: shell
- type: dropdown
id: source
attributes:
label: Do you have the gadget and are you able to help us for testing?
options:
- Yes, I have the gadget and I'm willing to provide further feedback and help testing.
- No, I don't have the gadget or/and I'm not able to help during the development.
validations:
required: true

View File

@ -0,0 +1,76 @@
name: Feature request
about: Suggest a feature or an idea.
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to make Gadgetbridge better!
If you just have a question, please ask first in the user chatroom in Matrix at [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
- type: checkboxes
attributes:
label: Please confirm that;
options:
- label: I have checked the [website](https://gadgetbridge.org), and I didn't find a solution to my problem / an answer to my question.
required: true
- label: I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
required: true
- label: I have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md) for images or other type of content that I included here.
required: true
- type: dropdown
id: source
attributes:
label: Where did you get Gadgetbridge from?
options:
- F-Droid
- Gadgetbridge Nightly F-Droid repository
- Bangle.js Gadgetbridge from the Play Store
- I built it myself from source code
- I previously used Gadgetbridge from other sources and then updated to F-Droid version
validations:
required: true
- type: input
id: version
attributes:
label: What is your Gadgetbridge version?
description: |
This can be found in "Menu > About > Version" in Gadgetbridge.
Also include tag / commit SHA if you built Gadgetbridge from the source.
placeholder: e.g. "0.77.0" or "0.77.0-2618adac1" to include commit
validations:
required: true
- type: textarea
id: content
attributes:
label: What is your suggestion/idea?
description: >
Please note that new requests about already solved/documented topics
**could be closed without further comments.** Same for too generic or incomplete reports.
placeholder: If you want to include logs, don't include it here. Use the next text field for that.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Do you have logs?
description: >
If possible, please attach [logs.](https://gadgetbridge.org/internals/topics/logs/)
This will be automatically formatted into code, so no need for backticks.
render: shell
- type: input
id: gadget
attributes:
label: What gadget do you use?
description: >
Please specify model and firmware version if possible. Leave blank if you believe the
issue is not specific to the gadget that you currently use with Gadgetbridge.
placeholder: e.g. ExampleWatch A1 with 0.1 firmware
- type: input
id: android
attributes:
label: What is your Android version/manufacturer flavor?
description: >
Android phone manufacturers may customise the Android source code as they wish, so
if you are using a phone that running a vendor-exclusive system (like MIUI) or if
you use a custom ROM, make sure to also include the name of the OS/ROM.
placeholder: e.g. LineageOS 20 based on Android 13

View File

@ -0,0 +1,16 @@
<!--
Thank you for your contribution! 🎉
Please make sure that you:
- Use `git rebase` to bring your branch up to date, do not use a merge commit for that.
- Do not add translations by editing the language variants of strings.xml as that
creates merge conflicts between Codeberg git repo and Weblate git repo,
use Weblate https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/
- Do not use `e.printStacktrace()`, use slf4j logger or `GB.toast` for logging
as per https://gadgetbridge.org/internals/development/project-overview/#logging
You can erase this comment from PR description, thank you!
-->

View File

@ -12,5 +12,8 @@ steps:
#https://github.com/woodpecker-ci/woodpecker/issues/687
when:
event:
exclude: ['cron', 'deployment']
# Everything except cron (nightly) and deployment
- event: push
- event: pull_request
- event: tag
- event: manual

View File

@ -26,8 +26,8 @@ steps:
- if [ -f .do_not_build ]; then return 0; fi
# build the apks
- echo "$${SIGNING_KEY}" | base64 -d > app/keystore.p12
- ./gradlew assembleMainNightly -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
- ./gradlew assembleMainNopebble -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
- ./gradlew assembleMainlineNightly -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
- ./gradlew assembleMainlineNopebble -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
- ./gradlew assembleBanglejsNightly -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
secrets: [ signing_key, keystorepass, keypass ]

View File

@ -12,5 +12,8 @@ steps:
#https://github.com/woodpecker-ci/woodpecker/issues/687
when:
event:
exclude: ['cron', 'deployment']
# Everything except cron (nightly) and deployment
- event: push
- event: pull_request
- event: tag
- event: manual

View File

@ -12,5 +12,8 @@ steps:
#https://github.com/woodpecker-ci/woodpecker/issues/687
when:
event:
exclude: ['cron', 'deployment']
# Everything except cron (nightly) and deployment
- event: push
- event: pull_request
- event: tag
- event: manual

View File

@ -1,35 +1,136 @@
### Changelog
#### Next release (WIP)
#### 0.79.0
* Initial support for Honor Magic Watch 2
* Initial support for Mijia MHO-C303
* Initial support for Nothing CMF Watch Pro
* Initial support for Sony WI-SP600N
* Experimental support for Redmi Watch 2
* Experimental support for Xiaomi Smart Band 8 Pro
* Experimental support for Xiaomi Watch S1 Pro
* Experimental support for Xiaomi Watch S1
* Experimental support for Xiaomi Watch S3
* Galaxy Buds2 Pro: Fix recognition of some versions
* Huawei Watch GT 2: Fix pairing
* Redmi Smart Band Pro: Fix password digits
* Pebble: Fix app configuration page
* Pebble 2: Fix pairing issue
* PineTime: Fix weather forecast on InfiniTime's new simple weather
* Xiaomi: Fix sleep sometimes extending past the wakeup time
* Xiaomi: Request battery level and charging state periodically
* Xiaomi: Fix sleep stage parsing for some devices
* Zepp OS: Improve device discovery
* Zepp OS: Fix weather not working on some devices
* Zepp OS: Prevent crash when installing large firmware updates
* Fix sport activity summary group order
* Fix reconnection to devices failing occasionally
#### 0.78.0
* Initial support for Honor Band 3,4,5,6
* Initial support for Huawei Band 4, 4 Pro, 6, 7, 3e, 4e
* Initial support for Huawei Talk Band B6
* Initial support for Huawei Watch GT, GT 2
* Initial support for Mijia LYWSD03MMC
* Initial support for Nothing Ear (2)
* Initial support for Nothing Ear (Stick)
* Experimental support for Honor Band 7
* Experimental support for Redmi Watch 2 Lite
* Experimental support for Redmi Smart Band Pro
* Casio GBX100: Add support for snooze alarm
* Fossil/Skagen Hybrids: Update navigationApp to 1.1
* Huami: Fetch SpO2 on devices that support it
* Pebble: Attempt to fix app configuration webview
* PineTime: Add support for InfiniTime's new simple weather
* PineTime: Fix freeze and reboot when upgrading firmware
* Pixoo: Enable sending images (non-persistent)
* Pixoo: Get and send alarms
* Pixoo: Set custom device name
* Pixoo: support "clap hands to turn off screen" and "sleep after silence" settings
* Xiaomi: Improve activity and workout parsing
* Xiaomi: Improve stability and fix some crashes
* Xiaomi: Improve weather
* Xiaomi: Parse sleep stages
* Add a notifications channel for connection status notifications
* Improve automatic connection to all or previous devices
* Fix devices sometimes staying stuck in a "Connecting" state
* Map some missing Google Maps navigation actions
#### 0.77.0
* Initial support for Amazfit Balance
* Initial support for Amazfit Active
* Initial support for ColaCao 2021
* Initial support for ColaCao 2023
* Initial support for Femometer Vinca II
* Initial support for Mijia LYWSD02MMC variant
* Initial support for Sony Wena 3
* Experimental support for Divoom Pixoo
* Experimental support for Sony WF-1000XM5
* Experimental support for Amazfit Active Edge
* Experimental support for Mi Band 7 Pro (Xiaomi Smart Band 7 Pro)
* Experimental support for Mi Band 8 (Xiaomi Smart Band 8)
* Experimental support for Mi Watch Lite
* Experimental support for Mi Watch Color Sport
* Experimental support for Redmi Smart Band 2
* Experimental support for Redmi Watch 3 Active
* Experimental support for Xiaomi Watch S1 Active
* Amazfit Band 7: Add alexa menu entries
* Amazfit GTR 3 Pro: Fix firmware and watchface upload
* Amazfit T-Rex: Fix activity summary parsing
* Amazfit T-Rex Pro: Add activate display on lift sensitivity
* AsteroidOS: Add more supported watch models
* AsteroidOS: Fix media info
* AsteroidOS: Fix notification dismissal
* Bangle.js: Add loyalty cards integration with Catima
* Bangle.js: Ensure SMS messages have src field set to "SMS Message"
* Bangle.js: Fix GPS speed
* Bangle.js: Improve handling of chinese characters
* Bangle.js: Lower threshold for low battery warning
* Bangle.js: Recover from device initialization failure
* Casio GBX100/GBD-200: Fix first connect
* Casio GB5600/6900/STB-1000: Fix pairing
* Casio GDB-200: Fix notification timestamp
* Casio GDB-200: Fixed notification categories and default category
* Casio GDB-200: Allow preview of notification message alongside title
* Casio GDB-200: Fixed find my phone feature
* Intent API: Add debug action for test new function
* Fossil/Skagen Hybrids: Add new navigation app
* Fossil/Skagen Hybrids: Allow configuring call rejection method
* Fossil/Skagen Hybrids: Fix some preference crashes on the nightly
* Fossil/Skagen Hybrids: Reduce toasts on release builds
* Fossil/Skagen Hybrids: Show device specific settings in more logical order
* Huami: Toggle phone silent mode from band
* Message privacy: Add mode Hide only body
* Mijia LYWSD02: Add battery
* Mijia LYWSD02: Add low battery notification
* Mijia LYWSD02: Set temperature unit
* Mijia LYWSD02: Fix battery drain while connected
* PineTime: Display app name for VoIP app calls
* PineTime: Honor Sync time setting on connect
* PineTime: Improve notification handling
* PineTime: Reduce weather memory usage
* Withings Steel HR: Fix crash when calibrating hands on the nightly
* Zepp OS: Add blood oxygen graph
* Zepp OS: Add workout codes for hiking and outdoor swimming
* Zepp OS: Allow disabling app notifications per device
* Zepp OS: Attempt to fix activity fetch operation getting stuck
* Zepp OS: Display swimming activity data
* Zepp OS: Fix health settings on older Zepp OS versions
* Zepp OS: Fix setting of unknown button press apps
* Zepp OS: Fix sunrise and moon dates being off by local time + UTC offset
* Zepp OS: Map hiking, outdoor swimming, climbing and table tennis activity types
* Add transliteration for Latvian and Common Symbols
* Zepp OS: Toggle phone silent mode from band
* Add transliteration for Latvian, Hungarian, Common Symbols
* Allow multiple device actions to be triggered for the same event
* Allow toggling DND through device actions
* Autodetect OsmAnd package name and make it configurable
* Improve ASCII transliterator
* Make GMaps navigation handler follow the "navigation forwarding" setting
* Support selecting enabled navigation apps
* Allow ignore notifications from work profile apps
* Display alias in low battery notification
* Fix crash when pairing current device as companion
* Fix emoji when a transliterator is enabled
* Fix UV Index and rain probability for some weather apps
* Improve device discovery stability and fix freezes
* Improve Telegram and COL Reminder notifications
* Replace old-style preference switch with Material 3 switch

View File

@ -24,89 +24,143 @@
* Andreas Shimokawa <shimokawa@fsfe.org>
* Carsten Pfeiffer <cpfeiffer@users.noreply.github.com>
* José Rebelo <joserebelo@outlook.com>
* Daniele Gobbetti <daniele+github@gobbetti.name>
* Daniel Dakhno <dakhnod@gmail.com>
* Petr Vaněk <petr@linuks.cz>
* Yaron Shahrabani <sh.yaron@gmail.com>
* Allan Nordhøy <epost@anotheragency.no>
* Taavi Eomäe <taavi.eomae+github@gmail.com>
* Daniel Dakhno <dakhnod@gmail.com>
* 陈少举 <oshirisu.red@gmail.com>
* Rafael Fontenelle <rafaelff@gnome.org>
* João Paulo Barraca <jpbarraca@gmail.com>
* Sebastian Kranz <tklightforce@googlemail.com>
* Arjan Schrijver <arjan5@noreply.codeberg.org>
* Vincèn PUJOL <vincen@vincen.org>
* Oğuz Ersen <oguzersen@protonmail.com>
* Allan Nordhøy <epost@anotheragency.no>
* Ihor Hordiichuk <igor_ck@outlook.com>
* nautilusx <mail.ka@mailbox.org>
* Taavi Eomäe <taavi.eomae+github@gmail.com>
* Gordon Williams <gw@pur3.co.uk>
* Rafael Fontenelle <rafaelff@gnome.org>
* Michal L <michalrmsmi@wp.pl>
* Sebastian Kranz <lightwars@web.de>
* João Paulo Barraca <jpbarraca@gmail.com>
* Linerly <linerly@protonmail.com>
* Rex_sa <rex.sa@pm.me>
* mamucho <mamut_killer@yahoo.com>
* postsorino <postsorino@krutt.org>
* Oğuz Ersen <oguzersen@protonmail.com>
* FransM <fransmeulenbroeks@yahoo.com>
* Manuel-Senpai <senpai99@hotmail.com>
* Andreas Böhler <dev@aboehler.at>
* FransM <fransmeulenbroeks@yahoo.com>
* Jonas <jonasdcdm@posteo.net>
* HenRy <helge1o1o1@gmail.com>
* Yukai Li <yukaili.geek@gmail.com>
* Roi Greenberg <roigreenberg@gmail.com>
* HenRy <helge1o1o1@gmail.com>
* gallegonovato <fran-carro@hotmail.es>
* Nikita Epifanov <nikgreens@protonmail.com>
* kirill blaze <kirillblaze2@gmail.com>
* Óscar Fernández Díaz <oscfdezdz@tuta.io>
* Jeannette L <j.lavoie@net-c.ca>
* Vadim Kaushan <admin@disasm.info>
* protomors <protomors@gmail.com>
* Cre3per <lukas96s@web.de>
* Michal L <michalrmsmi@wp.pl>
* José Rebelo <joserebelo@outlook.com>
* Vincèn PUJOL <vincen@vincen.org>
* Nikita Epifanov <nikgreens@protonmail.com>
* Davis Mosenkovs <davikovs@gmail.com>
* ssantos <ssantos@web.de>
* Michael <quelbs@gmail.com>
* glemco <glemco@codeberg>
* 115ek <e.blosz@hotmail.de>
* 0que <0que@users.noreply.hosted.weblate.org>
* Саша Петровић <salepetronije@gmail.com>
* naofum <naofum@gmail.com>
* Gordon Williams <gw@pur3.co.uk>
* My Random Thoughts <weblate@myrandomthoughts.co.uk>
* Damien 'Psolyca' Gaignon <damien.gaignon@gmail.com>
* 0eoc <0eoc@users.noreply.hosted.weblate.org>
* mesnevi <shams@airpost.net>
* Jeannette L <j.lavoie@net-c.ca>
* Kintu <kintukp@gmail.com>
* youzhiran <2668760098@qq.com>
* mueller-ma <mueller-ma@users.noreply.github.com>
* ivanovlev <ivanovlev@mail.ru>
* Tijl Schepens <tijl.schepens@hotmail.com>
* ssantos <ssantos@web.de>
* Sophanimus <sennamails@googlemail.com>
* Pavel Elagin <elagin.pasha@gmail.com>
* NekoBox <nekobox@noreply.codeberg.org>
* MPeter <>
* MrYoranimo <yvulker@gmail.com>
* mondstern <hello@mondstern.tk>
* Hadrián Candela <hadrian.candela@gmail.com>
* Ács Zoltán <acszoltan111@gmail.com>
* Zhong Jianxin <azuwis@gmail.com>
* Kintu <kintukp@gmail.com>
* Milo Ivir <mail@milotype.de>
* Gabriele Monaco <monaco@eit.uni-kl.de>
* foxstidious <foxstidious@gmail.com>
* Andy Yang <a962702@yahoo.com>
* Abdullah Manaz <manaz@noreply.codeberg.org>
* Richard de Boer <git@tubul.net>
* mkusnierz <>
* Julien Pivotto <roidelapluie@inuits.eu>
* tomechio <tomasz@salamon.fi>
* Steffen Liebergeld <perl@gmx.org>
* Skrripy <rozihrash.ya6w7@simplelogin.com>
* Petr Kadlec <mormegil@centrum.cz>
* Pavel <pavel.gorbanj@gmail.com>
* Lem Dulfo <lemuel.dulfo@gmail.com>
* Dmitriy Bogdanov <di72nn@gmail.com>
* Olexandr Nesterenko <olexn@ukr.net>
* Nevena Mircheva <nevena.mircheva@gmail.com>
* musover <meoberto@mthree.es>
* Matthieu Baerts <matttbe@gmail.com>
* J. Lavoie <j.lavoie@net-c.ca>
* Felix Konstantin Maurer <maufl@maufl.de>
* Andy Yang <a962702@yahoo.com>
* Axus Wizix <aw.ts@bk.ru>
* Xtremo3 <a.lewicki95@gmail.com>
* Utsob Roy <uroybd@gmail.com>
* taras3333 <taras3333@gmail.com>
* Sergey Trofimov <sarg@sarg.org.ru>
* Sebastian Krey <sebastian@skrey.net>
* Noodlez <contact@nathanielbarragan.xyz>
* M. Hadi <hhhadddi@yahoo.com>
* Martin Boonk <martin@boonk.info>
* Lukas <lukas.edi@gmx.net>
* Ganblejs <ganblejs@noreply.codeberg.org>
* Deixondit <jperals@protonmail.com>
* akasaka / Genjitsu Labs <vladkorotnev@gmail.com>
* Szylu <chipolade@gmail.com>
* Robert Barat <rbarat07@gmail.com>
* Pavel <pavel.gorbanj@gmail.com>
* Reza Almanda <rezaalmanda27@gmail.com>
* Mario <mariomobla@gmail.com>
* ksiwczynski <k.siwczynski@gmail.com>
* JohnnySun <bmy001@gmail.com>
* Gilles Émilien MOREL <contact@gilles-morel.fr>
* Deixondit <jperals@protonmail.com>
* firekonstantin <firekonstantin@mail.ru>
* bruh <quangtrung02hn16@gmail.com>
* Uwe Hermann <uwe@hermann-uwe.de>
* Patric Gruber <me@patric-gruber.at>
* opavlov <forpoststuff@gmail.com>
* Olexandr Nesterenko <olexn@ukr.net>
* Michalis <michalisntovas@yahoo.gr>
* Mario Rossi <kk1o2n+61euckrwqwqecz3pme3@sharklasers.com>
* ifurther <i.further.5.4@gmail.com>
* Edoardo Rosa <edoardo.rosa90@gmail.com>
* Dmitriy Bogdanov <di72nn@gmail.com>
* d <dmanye@gmail.com>
* Bożydar <trening302@o2.pl>
* Alberto <albertsal83@gmail.com>
* AiLab <vpuhoff92@gmail.com>
* zsolt3991 <zsolt_93@yahoo.com>
* winver <kirillstuzhuk@gmail.com>
* Vladislav Serkov <vladserkoff@protonmail.com>
* Vebryn <vebryn@gmail.com>
* uli <cybuzuma@vnxs.de>
* Ted Stein <me@tedstein.net>
* sinore <sinoren263@niekie.com>
* Shimon <simonfarm0@gmail.com>
* Reiner Herrmann <reiner@reiner-h.de>
* NicoBuntu <nicolas__du95@hotmail.fr>
* Nee Sorry <sven.fasterding@posteo.de>
* Marc Nause <marc.nause@audioattack.de>
* Louis-Marie Croisez <louis.croisez@gmail.com>
* Kryštof Černý <cleverline1mc@gmail.com>
* Johannes Krude <johannes@krude.de>
* Jean-François Greffier <jf.greffier@gmail.com>
* Hasan Ammar <ammarh@gmail.com>
* Giuseppe Caliendo <giuseppe.caliendo@gmail.com>
* Gergely Peidl <gergely@peidl.net>
* Fabio Parri <parrif_ibb@yahoo.com>
* Evo <weblate@verahawk.com>
* Emre <wenigerpluesch@mailbox.org>
* Elwood <elwood21@gmail.com>
* Dmitry Markin <dmitry@markin.tech>
@ -118,153 +172,236 @@
* 0nse <0nse@users.noreply.github.com>
* Максим Якимчук <xpinovo@gmail.com>
* Ye Wint Htut Kyaw <oxygen.2521998@gmail.com>
* xaos <xaos@noreply.codeberg.org>
* Thomas <tutonis@gmail.com>
* TheScientistPT <joao.ed.reis.gomes@gmail.com>
* SnowCat <kittythesnowcat@protonmail.com>
* Sergio Varela <sergitroll9@gmail.com>
* Sebastian Obrusiewicz <sobrus2@o2.pl>
* Sebastian Espinosa <hipypuff@gmail.com>
* Robbert Gurdeep Singh <git@beardhatcode.be>
* Rimas Raguliūnas <rarimas@gmail.com>
* mvn23 <schopdiedwaas@gmail.com>
* Minori Hiraoka (미노리) <minori@mnetwork.co.kr>
* MASVA <masva10@gmail.com>
* masakoodaa <masakoodaa@protonmail.com>
* Marius Cornescu <marius_cornescu@yahoo.com>
* Mario Rossi <kk1o2n+61euckrwqwqecz3pme3@sharklasers.com>
* mantas-p <megaliuz@gmail.com>
* Lukas Veneziano <fs@venezilu.de>
* LL <lu.lecocq@free.fr>
* LizardWithHat <martin.betcher@gmail.com>
* Lesur Frederic <contact@memiks.fr>
* leela <53352@protonmail.com>
* kukuruzka <anton.dan1657@gmail.com>
* Kompact <joaorafael123@hotmail.com>
* Kalle <hiwokey596@vip4e.com>
* K0L0B0G <github@gorobav.ru>
* Johann C. Rode <jcrode@ece.ucsb.edu>
* jimman2003 <jim41825@gmail.com>
* jfgreffier <jfgreffier@users.noreply.github.com>
* Jasper <jespiex456@hotmail.com>
* ITCactus <itcactus@noreply.codeberg.org>
* illis <illis@beyond8labs.com>
* Francesco Marinucci <francesco.marinucci@posteo.net>
* FintasticMan <finlay.neon.kid@gmail.com>
* Doma Gergő <domag02@gmail.com>
* Dikay900 <dark900@xyz.de>
* Denis <korden@sky-play.ru>
* Christian Fischer <sw-dev@computerlyrik.de>
* Benjamin Swartley <reep236@gmail.com>
* Asbesbopispa <c.alfano+github@outlook.it>
* AiLab <vpuhoff92@gmail.com>
* Adolfo Jayme Barrientos <fitojb@ubuntu.com>
* 6arms1leg <m.brnsfld@googlemail.com>
* Your Name <you@example.com>
* XqweX <xqwex@seznam.cz>
* walkjivefly <mark@walkjivefly.com>
* WaldiS <admin@sto.ugu.pl>
* Vytenis <slivinskasvytenis@gmail.com>
* Vladislav Glinsky <cl0ne@mithril.org.ua>
* vishnu <vishnu012@protonmail.com>
* Thomas <tutonis@gmail.com>
* Sebastian Espinosa <hipypuff@gmail.com>
* Vianney le Clément de Saint-Marcq <vianney@noreply.codeberg.org>
* Toby Murray <toby.murray+gitkraken@protonmail.com>
* thyttan <6uuxstm66@mozmail.com>
* Thorsten <js1_531b3pm29ng2@byom.de>
* Stephan Lachnit <stephanlachnit@protonmail.com>
* Sebastian Reichel <sre@ring0.de>
* Saul Nunez <saul.nunez99@gmail.com>
* Rui Mendes <xz9@protonmail.com>
* roolx <rbzikadze@gmail.com>
* rarder44 <rarder44@noreply.codeberg.org>
* rany <ranygh@riseup.net>
* Ranved Sticon <the7bulk@gmail.com>
* Rajesh Kumbhakar <sssraj.sssraj@gmail.com>
* Ptilopsis Leucotis <PtilopsisLeucotis@yandex.com>
* petronovak <petro.novak@gmail.com>
* Petr Kadlec <mormegil@centrum.cz>
* Pascal <pascal.tannich@gmail.com>
* odavo32nof <odavo32nof@noreply.codeberg.org>
* octospacc <octo@tutamail.com>
* NotAFIle <nota@notafile.com>
* Normano64 <per.bergqwist@gmail.com>
* Nikolay Korotkiy <sikmir@gmail.com>
* Nick Spacek <peter.spacek@siemens.com>
* Nee Sorry <sven.fasterding@posteo.de>
* Nekromanser <ari.taitto@protonmail.com>
* Nathan <bonnemainsnathan@gmail.com>
* narektor <narektor@noreply.codeberg.org>
* MyTimeKill <26295589+MyTimeKill@users.noreply.github.com>
* Molnár Barnabás <nsd4rkn3ss@gmail.com>
* Moarc <aldwulf@gmail.com>
* Michal Novotny <mignov@gmail.com>
* maxvel <maxvel@noreply.codeberg.org>
* Maxime Reyrolle <dev@reyrolle.fr>
* Mattias Münster <mattiasmun@gmail.com>
* Mattherix <mattherix@protonmail.com>
* Martin <ritualz@users.noreply.github.com>
* marco.altomonte <marco.altomonte@gmail.com>
* LizardWithHat <martin.betcher@gmail.com>
* Le Poisson Libre <services@spika.xyz>
* Krzysztof Marcinek <krzymar2002@gmail.com>
* krzys_h <krzys_h@interia.pl>
* Konrad Iturbe <KonradIT@users.noreply.github.com>
* Kamalei Zestri <38802353+KamaleiZestri@users.noreply.github.com>
* Joel Beckmeyer <joel@beckmeyer.us>
* Jesús <zaagur@gmail.com>
* Jesús F <jfmiguel@wanadoo.es>
* Irul <wedesignthing@gmail.com>
* ifurther <i.further.5.4@gmail.com>
* Igor Polyakov <igorpolyakov@protonmail.com>
* homocomputeris <homocomputeris+git@gmail.com>
* Grzegorz <grzesjam@duck.com>
* GeekosaurusR3x <skad@protonmail.com>
* Francesco Franchina <cescus92@gmail.com>
* fparri <fparri@noreply.codeberg.org>
* Fabien Brachere <fabien@brachere.net>
* exit-failure <hakrala@web.de>
* Ertu (Er2, Err) <er2official@outlook.com>
* Er2 <er2@dismail.de>
* Dreamwalker <aristojeff@gmail.com>
* DAWID <aggregate_diffused400@simplelogin.com>
* Dario Lopez-Kästen <cl2dlope@gmail.com>
* Da Pa <da.pa@noreply.codeberg.org>
* DanialHanif <danialhanif@outlook.com>
* Cristian Alfano <c.alfano@outlook.it>
* criogenic <criogenic@gmail.com>
* chabotsi <chabotsi+github@chabotsi.fr>
* bowornsin <bowornsin@gmail.com>
* Avamander <Avamander@users.noreply.github.com>
* Artem <KovalevArtem.ru@gmail.com>
* AnthonyDiGirolamo <anthony.digirolamo@gmail.com>
* Anonymous <noreply@weblate.org>
* Andreas Kromke <Andreas.Kromke@web.de>
* Alex <leha-bot@yandex.ru>
* Albert <albert@avdm043>
* Ainārs <ainars71@inbox.lv>
* عبدالرئوف عابدی <abdolraoofabedi@gmail.com>
* Егор Ермаков <eg.ermakov2016@yandex.ru>
* Ⲇⲁⲛⲓ Φi <daniphii@outlook.com>
* Your Name <you@example.com>
* Yusuf Cihan <yusufcihandemirbas@gmail.com>
* yk <bivol21883@cyadp.com>
* Yar <yaroslav.isakov@gmail.com>
* xzovy <caleb@caleb-cooper.net>
* xphnx <xphnx@users.noreply.github.com>
* Xosé M <xosem@disroot.org>
* Xeoy <arventh@pm.me>
* Xavier RENE-CORAIL <xavier.renecorail@gmail.com>
* xaos <xaos@noreply.codeberg.org>
* x29a <x29a@noreply.codeberg.org>
* w2q <w2q@noreply.codeberg.org>
* Vitaliy Shuruta <vshuruta@gmail.com>
* veecue <veecue@ventos.tk>
* Unixware <csynt@hotmail.com>
* TylerWilliamson <tyler.williamson51@gmail.com>
* Triet Pham <triet.phm@gmail.com>
* Traladarer <Traladarer@users.noreply.hosted.weblate.org>
* Tomer Rosenfeld <tomerosenfeld007@gmail.com>
* Tomas Radej <tradej@redhat.com>
* Toby Murray <toby.murray+gitkraken@protonmail.com>
* t-m-w <t-m-w-codeberg@galac.tk>
* tiparega <11555126+tiparega@users.noreply.github.com>
* TinfoilSubmarine <tinfoilsubmarine@noreply.codeberg.org>
* Tim <tim.w1995@gmail.com>
* thirschbuechler <thirschbuechler@github.com>
* Thiago Rodrigues <thiaguinho.the@gmail.com>
* thermatk <thermatk@noreply.codeberg.org>
* theghostofheathledger <theghostofheathledger@noreply.codeberg.org>
* Temuri Doghonadze <temuri.doghonadze@gmail.com>
* Tarik Sekmen <tarik@ilixi.org>
* Szymon Tomasz Stefanek <s.stefanek@gmail.com>
* szilardx <15869670+szilardx@users.noreply.github.com>
* Swann Martinet <swann.ranskassa@laposte.net>
* Stefan Bora <stefan.bora@outlook.de>
* Stan Gomin <stan@gomin.me>
* ssilverr <ssilverr@noreply.codeberg.org>
* Sky233ml <sky233@sky233.ml>
* SinMan <emilio.galvan@gmail.com>
* Simon Sievert <ssievert@protonmail.com>
* Sergio Lopez <slp@sinrega.org>
* Sergey Vasilyev <koniponi@gmail.com>
* sedy89 <sedy89@noreply.codeberg.org>
* Sebastian Nilsson <sebbe_kompis@hotmail.com>
* S Dantas <dantasosteney@gmail.com>
* Santiago Benalcázar <santiagosdbc@gmail.com>
* Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
* Sami Alaoui <4ndroidgeek@gmail.com>
* Saman rsh <sasan.r75@gmail.com>
* Salif Mehmed <mail@salif.eu>
* SalavatR <salavat.rakhmanov@gmail.com>
* Roxystar <roxystar@arcor.de>
* Roman Plevka <rplevka@redhat.com>
* rom4nik <codeberg@rom4nik.pl>
* Robin Davidsson <robindavidsson@outlook.com>
* Roberto P. Rubio <outtakes_handgun090@familiapm.com>
* rober <rober@prtl.nodomain.net>
* Rivo Zängov <rivozangov@gmail.com>
* rimasx <riks_12@hot.ee>
* rikka356 <rikka356@outlook.com>
* Richard Finegold <goldfndr+git@gmail.com>
* Retew <salau@tutanota.com>
* redking <redking974@gmail.com>
* Ray <RayL-er@outlook.com>
* RandomItalianGuy <donatoperruso@protonmail.com>
* Raghd Hamzeh <raghd@rhamzeh.com>
* Quang Ngô <ngoquang2708@gmail.com>
* Quallenauge <Hamsi2k@freenet.de>
* Q-er <9142398+Q-er@users.noreply.github.com>
* pommes <pommes@noreply.codeberg.org>
* pishite <pishite@meta.ua>
* Perflyst <mail@perflyst.de>
* Pavel Motyrev <legioner.r@gmail.com>
* Pauli Salmenrinne <susundberg@gmail.com>
* pangwalla <pangwalla@noreply.codeberg.org>
* Pander <pander@users.sourceforge.net>
* ozkanpakdil <ozkan.pakdil@gmail.com>
* opcode <luigi@sciolla.net>
* Ondřej Sedláček <ond.sedlacek@gmail.com>
* Olivier Bloch <blochjunior@gmail.com>
* Oleg Vasilev <oleg.vasilev@virtuozzo.com>
* Oleg <oleg.invisibleman@protonmail.com>
* Nur Aiman Fadel <nuraiman@gmail.com>
* Nikolai Sinyov <nikolay.sinyov@yandex.ru>
* Nicolò Balzarotti <anothersms@gmail.com>
* Nephiel <Nephiel@users.noreply.github.com>
* Nathan Philipp Bo Seddig <natpbs@gmail.com>
* Natanael Arndt <arndtn@gmail.com>
* Nabil BENDAFI <nabil@bendafi.fr>
* myxor <myxor@noreply.codeberg.org>
* Morten Rieger Hannemose <mohan@dtu.dk>
* Mirko Covizzi <mrkcvzz@gmail.com>
* Milo Ivir <mail@milotype.de>
* Milan Šalka <salka.milan@googlemail.com>
* Mike van Rossum <mike@vanrossum.net>
* mika laka <Mikhaila.Eaddy@easymailer.live>
* Michal Novak <michal.novak@post.cz>
* Michael Wiesinger <michw2014@gmail.com>
* michaelneu <git@michaeln.eu>
* Lesur Frederic <contact@memiks.fr>
* MedusasSphinx <medusassphinx@noreply.codeberg.org>
* McSym28 <McSym28@users.noreply.github.com>
* MaxL <z60loa8qw3umzu3@my10minutemail.com>
* maxirnilian <maxirnilian@users.noreply.github.com>
* Maxim Baz <git@maximbaz.com>
* Mave95 <mave95@noreply.codeberg.org>
* Matej Drobnič <matejdro@gmail.com>
* Marvin D <mave95@posteo.de>
* Martin Piatka <chachacha2323@gmail.com>
* Martin.JM <>
* Margreet <margreetkeelan@gmail.com>
* Marc Schlaich <marc.schlaich@googlemail.com>
* Marco Alberto Diosdado Nava <betoxxdiosnava@gmail.com>
* Marco A <35718078+TomasCartman@users.noreply.github.com>
* Marc Nause <marc.nause@audioattack.de>
* Marc Laporte <marc@laporte.name>
* Marcin <ml.cichy@gmail.com>
* Marcel pl (m4rcel) <marcel.garbarczyk@gmail.com>
@ -274,87 +411,142 @@
* magimel.francois <magimel.francois@gmail.com>
* Maciej Kuśnierz <>
* m4sk1n <me@m4sk.in>
* LukasEdl <lukasedl@noreply.codeberg.org>
* LuK1337 <priv.luk@gmail.com>
* Luiz Felipe das Neves Lopes <androidfelipe23@gmail.com>
* Luis zas <dalues@gmail.com>
* Ludovic Jozeau <unifai@protonmail.com>
* luca sain <luca.sain@outlook.com>
* lucanomax <lucano.valo@gmail.com>
* Liao junchao <liaojunchao@outlook.com>
* Leon Omelan <rozpierog@gmail.com>
* Leonardo Amaral <contato@leonardoamaral.com.br>
* Leo bonilla <leo_lf9@hotmail.com>
* LeJun <lejun@gmx.fr>
* Lejun <adrienzhang@hotmail.com>
* lazarosfs <lazarosfs@csd.auth.gr>
* Lars Vogdt <lars.vogdt@suse.com>
* ladbsoft <30509719+ladbsoft@users.noreply.github.com>
* Kyaw Min Khant <kyawmink@gmail.com>
* Krisztián Gáncs <990024@gmail.com>
* Kristjan Räts <kristjanrats@gmail.com>
* Kornél Schmidt <kornel.schmidt@clubspot.app>
* kirk1984 <kirk1984@noreply.codeberg.org>
* kieranc001 <kieranc001@noreply.codeberg.org>
* kevlarcade <kevlarcade@gmail.com>
* Kevin Richter <me@kevinrichter.nl>
* Kevin MacMartin <prurigro@gmail.com>
* keeshii <keeshii@ptcg.eu>
* Kaz Wolfe <root@kazwolfe.io>
* Kasha <kasha_malaga@hotmail.com>
* kalaee <alex.kalaee@gmail.com>
* Julien Winning <heijulien@web.de>
* Julian Lam <julian@nodebb.org>
* jugendhacker <jugendhacker@gmail.com>
* Joseph Kim <official.jkim@gmail.com>
* jonnsoft <>
* Johannes Tysiak <vinyl@users.sf.net>
* Joan Perals <jperals@protonmail.com>
* Jochen S <tsalin@noreply.codeberg.org>
* joaquim.org <joaquim.org@gmail.com>
* jhey <jhey@noreply.codeberg.org>
* JF <jf@codingfield.com>
* Jean-François Milants <jf@codingfield.com>
* jcrode <46062294+jcrode@users.noreply.github.com>
* Jan Lolek <janlolek@seznam.cz>
* Jakub Jelínek <jakub.jelinek@gmail.com>
* Jacque Fresco <aidter@use.startmail.com>
* Izzy <izzy@qumran.org>
* iwonder <hosted.weblate.org@heychris.eu>
* Ivan <ivan_tizhanin@mail.ru>
* Igor Polyakov <igorpolyakov@protonmail.com>
* InternalErrorX <internalerrorx@noreply.codeberg.org>
* Hüseyin Aslan <ha098784@gmail.com>
* Hugel <qihu@nfschina.com>
* hr-sales <hericsonregis@hotmail.com>
* Hirnchirurg <anonymous11@posteo.net>
* Hasan Ammar <ammarh@gmail.com>
* Hen Ry <nobo@go4more.de>
* HelloCodeberg <hellocodeberg@noreply.codeberg.org>
* HardLight <hardlightxda@gmail.com>
* Hanhan Husna <matcherapy@gmail.com>
* halemmerich <halemmerich@noreply.codeberg.org>
* hackoder <hackoder@noreply.codeberg.org>
* Gustavo Ramires <gustavo.nramires@gmail.com>
* gsbhat <>
* Grzegorz Dznsk <grantmlody96@gmail.com>
* Golbinex <2061409-Golbinex@users.noreply.gitlab.com>
* gnufella <gnufella@noreply.codeberg.org>
* gnu-ewm <gnu.ewm@protonmail.com>
* Gleb Chekushin <mail@glebchek.com>
* Giuseppe <giuseppe.parasilitipalumbo@studium.unict.it>
* Gideão Gomes Ferreira <trjctr@gmail.com>
* gfwilliams <gfwilliams@noreply.codeberg.org>
* GabO <gabosuelto@gmail.com>
* Gabe Schrecker <gabe@pbrb.co.uk>
* freezed-or-frozen <freezed.or.frozen@gmail.com>
* Frank Slezak <KazWolfe@users.noreply.github.com>
* Frank Ertl <hrglpfrmpf@noreply.codeberg.org>
* Florian Beuscher <florianbeuscher@gmail.com>
* Fabian Hof <weblate@fabian-hof.de>
* Étienne Deparis <etienne@depar.is>
* Estébastien Robespi <estebastien@mailbox.org>
* Ernst <ernst@seebens.de>
* Enrico Brambilla <enricobilla@noreply.codeberg.org>
* Edoardo Tronconi <edoardo.tronconi@gmail.com>
* Dougal19 <4662351+Dougal19@users.noreply.github.com>
* Donato <pread.xa4mx@simplelogin.com>
* Dmytro Bielik <mitrandir.hex@gmail.com>
* djurik <dirceu.semighini@protonmail.com>
* DerFetzer <kontakt@der-fetzer.de>
* Dean <3114661520@qq.com>
* Deactivated Account <diastasis@gmail.com>
* Davis Mosenkovs <davikovs@gmail.com>
* David Girón <contacto@duhowpi.net>
* Davide Corradini <updates+weblate.org@corradinidavi.de>
* Daniel Thompson <daniel@redfelineninja.org.uk>
* Daniel Hauck <maill@dhauck.eu>
* Dam BOND <dambond2001@gmail.com>
* 이정희 <daemul72@gmail.com>
* Dachi G <duchy007@yahoo.com>
* C <weblate@wolki.de>
* cokecodecock <lights1140977891@163.com>
* CodeSpoof <nao.s_l_t_e_e_l@protonmail.com>
* C O <cosmin.oprisan@gmail.com>
* clach04 <Chris.Clark@actian.com>
* Chris Perelstein <chris.perelstein@gmail.com>
* chklump <chklump@noreply.codeberg.org>
* Cédric Bellegarde <cedric.bellegarde@adishatz.org>
* Carlos Ferreira <calbertoferreira@gmail.com>
* C0rn3j <spleefer90@gmail.com>
* ButterflyOfFire <ButterflyOfFire@protonmail.com>
* bucala <marcel.bucala@gmail.com>
* boun <boun@gmx.de>
* BobIsMyManager <bobismymanager@noreply.codeberg.org>
* Bilel MEDIMEGH <bilel.medimegh@gmail.com>
* Benjamin Kahlau <nyhkkbjyek@roanapur.de>
* Ben <ben.david.wallner@gmail.com>
* beardhatcode <beardhatcode@noreply.codeberg.org>
* batataspt@gmail.com <batataspt@gmail.com>
* atkyritsis <at.kyritsis@gmail.com>
* Artem <KovalevArtem.ru@gmail.com>
* Ascense <ascense@noreply.codeberg.org>
* Aprilhoomie <Aprilhoomie@gmail.com>
* apre <adrienpre+github@gmail.com>
* Ann Test <testkimochiaz@gmail.com>
* Aniruddha Adhikary <aniruddha@adhikary.net>
* angelpup <angelpup@noreply.codeberg.org>
* Anemograph <dyraybn@gmail.com>
* Andrzej Surowiec <emeryth@gmail.com>
* Andrew Watkins <randnv20@noreply.codeberg.org>
* andrewlytvyn <indusfreelancer@gmail.com>
* AndrewH <36428679+andrewheadricke@users.noreply.github.com>
* andre <andre.buesgen@yahoo.de>
* Andrea Lepori <mafaldo@hotmail.it>
* Allen B <28495335+Allen-B1@users.noreply.github.com>
* Alicia Hormann <ahormann@gmx.net>
* Alfeu Lucas Guedes dos Santos <alfeugds@gmail.com>
* Alex <leha-bot@yandex.ru>
* Alexey Afanasev <avafanasiev@gmail.com>
* Alexandra Sevostyanova <asevostyanova@gmail.com>
* Aidan Crane <aidancrane78@gmail.com>
* aerowolf <aerowolf@tom.com>
* Adam Büchner <buechner.adam@gmx.de>
* a b <65567823+abb128@users.noreply.github.com>
And all the former Transifex translators, who cannot be listed automatically.

View File

@ -1,35 +0,0 @@
## Feature Matrix
| | Pebble OG | Pebble Time/2 | Mi Band | Mi Band 2 | Mi Band 3 | Mi Band 4/5 | Amazfit Bip | Amazfit Cor |
|-----------------------------------| ----------|---------------|---------|-----------|-----------|-------------|-------------|-------------|
|Calls Notification | YES | YES | YES | YES | YES | YES | YES | YES |
|Reject Calls | YES | YES | NO | NO | YES | YES | YES | YES |
|Accept Calls | NO(2) | NO(2) | NO | NO | NO | NO | NO | NO |
|Generic Notification | YES | YES | YES | YES | YES | YES | YES | YES |
|Dismiss Notifications on Phone | YES | YES | NO | NO | NO | NO | NO | NO |
|Predefined Replies | YES | YES | NO | NO | NO | NO | NO | NO |
|Voice Replies | N/A | NO(3) | N/A | N/A | N/A | N/A | N/A | N/A |
|Calendar Sync | YES | YES | NO | NO | NO | NO | NO(3) | NO |
|Configure alarms from Gadgetbridge | NO | NO | YES | YES | YES | YES(1) | YES | YES |
|Smart alarms | NO(1) | YES | YES | NO | NO | NO | NO | NO |
|Weather | NO(1) | YES | NO | NO | YES | YES | YES | YES |
|Activity Tracking | NO(1) | YES | YES | YES | YES | YES | YES | YES |
|GPS tracks import | NO | NO | NO | NO | NO | NO | YES | NO |
|Sleep Tracking | NO(1) | YES | YES | YES | YES | YES | YES | YES |
|HR Tracking | N/A | YES | YES | YES | YES | YES | YES | YES |
|Realtime Activity Tracking | NO | NO | YES | YES | YES | YES | YES | YES |
|Music Control | YES | YES | NO | NO | NO | YES | NO | YES |
|Watchapp/face Installation | YES | YES | NO | NO | NO | YES | YES | YES |
|Firmware Installation | YES | YES | YES | YES | YES | YES | YES | YES |
|Taking Screenshots | YES | YES | NO | NO | NO | NO | NO | NO |
|Support Android Companion Apps | YES | YES | NO | NO | NO | NO | NO | NO |
(1) Possible via 3rd Party Watchapp
(2) Theoretically possible (works on iOS, would need lot of work)
(3) Possible but not implemented yet
### Notes about Pebble Firmware >=3.0
* Gadgetbridge will keep track of installed watchfaces, but if the Pebble is used with another phone or another app, the information displayed in the app manager can get out of sync since it is impossible to query Firmware >= 3.x for installed apps/watchfaces.

View File

@ -45,7 +45,7 @@ public class GBDaoGenerator {
public static void main(String[] args) throws Exception {
final Schema schema = new Schema(62, MAIN_PACKAGE + ".entities");
final Schema schema = new Schema(70, MAIN_PACKAGE + ".entities");
Entity userAttributes = addUserAttributes(schema);
Entity user = addUserInfo(schema, userAttributes);
@ -70,6 +70,18 @@ public class GBDaoGenerator {
addHuamiHeartRateRestingSample(schema, user, device);
addHuamiPaiSample(schema, user, device);
addHuamiSleepRespiratoryRateSample(schema, user, device);
addXiaomiActivitySample(schema, user, device);
addXiaomiSleepTimeSamples(schema, user, device);
addXiaomiSleepStageSamples(schema, user, device);
addXiaomiManualSamples(schema, user, device);
addXiaomiDailySummarySamples(schema, user, device);
addCmfActivitySample(schema, user, device);
addCmfStressSample(schema, user, device);
addCmfSpo2Sample(schema, user, device);
addCmfSleepSessionSample(schema, user, device);
addCmfSleepStageSample(schema, user, device);
addCmfHeartRateSample(schema, user, device);
addCmfWorkoutGpsSample(schema, user, device);
addPebbleHealthActivitySample(schema, user, device);
addPebbleHealthActivityKindOverlay(schema, user, device);
addPebbleMisfitActivitySample(schema, user, device);
@ -105,6 +117,12 @@ public class GBDaoGenerator {
addWena3StressSample(schema, user, device);
addFemometerVinca2TemperatureSample(schema, user, device);
addHuaweiActivitySample(schema, user, device);
Entity huaweiWorkoutSummary = addHuaweiWorkoutSummarySample(schema, user, device);
addHuaweiWorkoutDataSample(schema, user, device, huaweiWorkoutSummary);
addHuaweiWorkoutPaceSample(schema, user, device, huaweiWorkoutSummary);
addCalendarSyncState(schema, device);
addAlarms(schema, user, device);
addReminders(schema, user, device);
@ -264,7 +282,7 @@ public class GBDaoGenerator {
private static Entity addHuamiStressSample(Schema schema, Entity user, Entity device) {
Entity stressSample = addEntity(schema, "HuamiStressSample");
addCommonTimeSampleProperties("AbstractStressSample", stressSample, user, device);
stressSample.addIntProperty("typeNum").notNull().codeBeforeGetterAndSetter(OVERRIDE);
stressSample.addIntProperty("typeNum").notNull().codeBeforeGetter(OVERRIDE);
stressSample.addIntProperty("stress").notNull().codeBeforeGetter(OVERRIDE);
return stressSample;
}
@ -272,7 +290,7 @@ public class GBDaoGenerator {
private static Entity addHuamiSpo2Sample(Schema schema, Entity user, Entity device) {
Entity spo2sample = addEntity(schema, "HuamiSpo2Sample");
addCommonTimeSampleProperties("AbstractSpo2Sample", spo2sample, user, device);
spo2sample.addIntProperty("typeNum").notNull().codeBeforeGetterAndSetter(OVERRIDE);
spo2sample.addIntProperty("typeNum").notNull().codeBeforeGetter(OVERRIDE);
spo2sample.addIntProperty("spo2").notNull().codeBeforeGetter(OVERRIDE);
return spo2sample;
}
@ -324,6 +342,136 @@ public class GBDaoGenerator {
return sleepRespiratoryRateSample;
}
private static Entity addXiaomiActivitySample(Schema schema, Entity user, Entity device) {
Entity activitySample = addEntity(schema, "XiaomiActivitySample");
addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device);
activitySample.implementsSerializable();
activitySample.addIntProperty(SAMPLE_RAW_INTENSITY).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE);
addHeartRateProperties(activitySample);
activitySample.addIntProperty("stress");
activitySample.addIntProperty("spo2");
return activitySample;
}
private static Entity addXiaomiSleepTimeSamples(Schema schema, Entity user, Entity device) {
Entity sample = addEntity(schema, "XiaomiSleepTimeSample");
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
sample.addLongProperty("wakeupTime");
sample.addBooleanProperty("isAwake");
sample.addIntProperty("totalDuration");
sample.addIntProperty("deepSleepDuration");
sample.addIntProperty("lightSleepDuration");
sample.addIntProperty("remSleepDuration");
sample.addIntProperty("awakeDuration");
return sample;
}
private static Entity addXiaomiSleepStageSamples(Schema schema, Entity user, Entity device) {
Entity sample = addEntity(schema, "XiaomiSleepStageSample");
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
sample.addIntProperty("stage");
return sample;
}
private static Entity addXiaomiManualSamples(Schema schema, Entity user, Entity device) {
Entity sample = addEntity(schema, "XiaomiManualSample");
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
sample.addIntProperty("type");
sample.addIntProperty("value");
return sample;
}
private static Entity addXiaomiDailySummarySamples(Schema schema, Entity user, Entity device) {
Entity sample = addEntity(schema, "XiaomiDailySummarySample");
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
sample.addIntProperty("timezone");
sample.addIntProperty("steps");
sample.addIntProperty("hrResting");
sample.addIntProperty("hrMax");
sample.addIntProperty("hrMaxTs");
sample.addIntProperty("hrMin");
sample.addIntProperty("hrMinTs");
sample.addIntProperty("hrAvg");
sample.addIntProperty("stressAvg");
sample.addIntProperty("stressMax");
sample.addIntProperty("stressMin");
sample.addIntProperty("standing");
sample.addIntProperty("calories");
sample.addIntProperty("spo2Max");
sample.addIntProperty("spo2MaxTs");
sample.addIntProperty("spo2Min");
sample.addIntProperty("spo2MinTs");
sample.addIntProperty("spo2Avg");
sample.addIntProperty("trainingLoadDay");
sample.addIntProperty("trainingLoadWeek");
sample.addIntProperty("trainingLoadLevel");
sample.addIntProperty("vitalityIncreaseLight");
sample.addIntProperty("vitalityIncreaseModerate");
sample.addIntProperty("vitalityIncreaseHigh");
sample.addIntProperty("vitalityCurrent");
return sample;
}
private static Entity addCmfActivitySample(Schema schema, Entity user, Entity device) {
Entity activitySample = addEntity(schema, "CmfActivitySample");
addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device);
activitySample.implementsSerializable();
activitySample.addIntProperty(SAMPLE_RAW_INTENSITY).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE);
addHeartRateProperties(activitySample);
activitySample.addIntProperty("distance");
activitySample.addIntProperty("calories");
return activitySample;
}
private static Entity addCmfStressSample(Schema schema, Entity user, Entity device) {
Entity stressSample = addEntity(schema, "CmfStressSample");
addCommonTimeSampleProperties("AbstractStressSample", stressSample, user, device);
stressSample.addIntProperty("stress").notNull().codeBeforeGetter(OVERRIDE);
return stressSample;
}
private static Entity addCmfSpo2Sample(Schema schema, Entity user, Entity device) {
Entity spo2sample = addEntity(schema, "CmfSpo2Sample");
addCommonTimeSampleProperties("AbstractSpo2Sample", spo2sample, user, device);
spo2sample.addIntProperty("spo2").notNull().codeBeforeGetter(OVERRIDE);
return spo2sample;
}
private static Entity addCmfSleepSessionSample(Schema schema, Entity user, Entity device) {
Entity sleepSessionSample = addEntity(schema, "CmfSleepSessionSample");
addCommonTimeSampleProperties("AbstractTimeSample", sleepSessionSample, user, device);
sleepSessionSample.addLongProperty("wakeupTime");
sleepSessionSample.addByteArrayProperty("metadata");
return sleepSessionSample;
}
private static Entity addCmfSleepStageSample(Schema schema, Entity user, Entity device) {
Entity sleepStageSample = addEntity(schema, "CmfSleepStageSample");
addCommonTimeSampleProperties("AbstractTimeSample", sleepStageSample, user, device);
sleepStageSample.addIntProperty("duration").notNull();
sleepStageSample.addIntProperty("stage").notNull();
return sleepStageSample;
}
private static Entity addCmfHeartRateSample(Schema schema, Entity user, Entity device) {
Entity heartRateSample = addEntity(schema, "CmfHeartRateSample");
addCommonTimeSampleProperties("AbstractHeartRateSample", heartRateSample, user, device);
heartRateSample.addIntProperty(SAMPLE_HEART_RATE).notNull().codeBeforeGetter(OVERRIDE);
return heartRateSample;
}
private static Entity addCmfWorkoutGpsSample(Schema schema, Entity user, Entity device) {
Entity sample = addEntity(schema, "CmfWorkoutGpsSample");
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
sample.addIntProperty("latitude");
sample.addIntProperty("longitude");
return sample;
}
private static void addHeartRateProperties(Entity activitySample) {
activitySample.addIntProperty(SAMPLE_HEART_RATE).notNull().codeBeforeGetterAndSetter(OVERRIDE);
}
@ -862,6 +1010,7 @@ public class GBDaoGenerator {
return activitySample;
}
private static Entity addWithingsSteelHRActivitySample(Schema schema, Entity user, Entity device) {
Entity activitySample = addEntity(schema, "WithingsSteelHRActivitySample");
activitySample.implementsSerializable();
@ -897,7 +1046,7 @@ public class GBDaoGenerator {
private static Entity addWena3StressSample(Schema schema, Entity user, Entity device) {
Entity stressSample = addEntity(schema, "Wena3StressSample");
addCommonTimeSampleProperties("AbstractStressSample", stressSample, user, device);
stressSample.addIntProperty("typeNum").notNull().codeBeforeGetterAndSetter(OVERRIDE);
stressSample.addIntProperty("typeNum").notNull().codeBeforeGetter(OVERRIDE);
stressSample.addIntProperty("stress").notNull().codeBeforeGetter(OVERRIDE);
return stressSample;
}
@ -943,6 +1092,99 @@ public class GBDaoGenerator {
return perAppSetting;
}
private static Entity addHuaweiActivitySample(Schema schema, Entity user, Entity device) {
Entity activitySample = addEntity(schema, "HuaweiActivitySample");
addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device);
activitySample.addIntProperty("otherTimestamp").notNull().primaryKey();
activitySample.addByteProperty("source").notNull().primaryKey();
activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_RAW_INTENSITY).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty("calories").notNull();
activitySample.addIntProperty("distance").notNull();
activitySample.addIntProperty("spo").notNull();
activitySample.addIntProperty("heartRate").notNull();
return activitySample;
}
private static Entity addHuaweiWorkoutSummarySample(Schema schema, Entity user, Entity device) {
Entity workoutSummary = addEntity(schema, "HuaweiWorkoutSummarySample");
workoutSummary.setJavaDoc("Contains Huawei Workout Summary samples (one per workout)");
workoutSummary.addLongProperty("workoutId").primaryKey().autoincrement();
Property deviceId = workoutSummary.addLongProperty("deviceId").notNull().getProperty();
workoutSummary.addToOne(device, deviceId);
Property userId = workoutSummary.addLongProperty("userId").notNull().getProperty();
workoutSummary.addToOne(user, userId);
workoutSummary.addShortProperty("workoutNumber").notNull();
workoutSummary.addByteProperty("status").notNull();
workoutSummary.addIntProperty("startTimestamp").notNull();
workoutSummary.addIntProperty("endTimestamp").notNull();
workoutSummary.addIntProperty("calories").notNull();
workoutSummary.addIntProperty("distance").notNull();
workoutSummary.addIntProperty("stepCount").notNull();
workoutSummary.addIntProperty("totalTime").notNull();
workoutSummary.addIntProperty("duration").notNull();
workoutSummary.addByteProperty("type").notNull();
workoutSummary.addShortProperty("strokes").notNull();
workoutSummary.addShortProperty("avgStrokeRate").notNull();
workoutSummary.addShortProperty("poolLength").notNull();
workoutSummary.addShortProperty("laps").notNull();
workoutSummary.addShortProperty("avgSwolf").notNull();
workoutSummary.addByteArrayProperty("rawData");
return workoutSummary;
}
private static Entity addHuaweiWorkoutDataSample(Schema schema, Entity user, Entity device, Entity summaryEntity) {
Entity workoutDataSample = addEntity(schema, "HuaweiWorkoutDataSample");
workoutDataSample.setJavaDoc("Contains Huawei Workout data samples (multiple per workout)");
Property id = workoutDataSample.addLongProperty("workoutId").primaryKey().notNull().getProperty();
workoutDataSample.addToOne(summaryEntity, id);
workoutDataSample.addIntProperty("timestamp").notNull().primaryKey();
workoutDataSample.addByteProperty("heartRate").notNull();
workoutDataSample.addShortProperty("speed").notNull();
workoutDataSample.addByteProperty("stepRate").notNull();
workoutDataSample.addShortProperty("cadence").notNull();
workoutDataSample.addShortProperty("stepLength").notNull();
workoutDataSample.addShortProperty("groundContactTime").notNull();
workoutDataSample.addByteProperty("impact").notNull();
workoutDataSample.addShortProperty("swingAngle").notNull();
workoutDataSample.addByteProperty("foreFootLanding").notNull();
workoutDataSample.addByteProperty("midFootLanding").notNull();
workoutDataSample.addByteProperty("backFootLanding").notNull();
workoutDataSample.addByteProperty("eversionAngle").notNull();
workoutDataSample.addByteProperty("swolf").notNull();
workoutDataSample.addShortProperty("strokeRate").notNull();
workoutDataSample.addByteArrayProperty("dataErrorHex");
return workoutDataSample;
}
private static Entity addHuaweiWorkoutPaceSample(Schema schema, Entity user, Entity device, Entity summaryEntity) {
Entity workoutPaceSample = addEntity(schema, "HuaweiWorkoutPaceSample");
workoutPaceSample.setJavaDoc("Contains Huawei Workout pace data samples (one per workout)");
Property id = workoutPaceSample.addLongProperty("workoutId").primaryKey().notNull().getProperty();
workoutPaceSample.addToOne(summaryEntity, id);
workoutPaceSample.addIntProperty("distance").notNull().primaryKey();
workoutPaceSample.addByteProperty("type").notNull().primaryKey();
workoutPaceSample.addIntProperty("pace").notNull();
workoutPaceSample.addIntProperty("correction").notNull();
return workoutPaceSample;
}
private static void addTemperatureProperties(Entity activitySample) {
activitySample.addFloatProperty(SAMPLE_TEMPERATURE).notNull().codeBeforeGetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_TEMPERATURE_TYPE).notNull().codeBeforeGetter(OVERRIDE);
@ -954,5 +1196,4 @@ public class GBDaoGenerator {
addTemperatureProperties(sample);
return sample;
}
}

112
README.md
View File

@ -12,7 +12,7 @@ Pebble, Mi Band, Amazfit Bip and HPlus device (and more) without the vendor's cl
and without the need to create an account and transmit any of your data to the
vendor's servers.
[Homepage](https://gadgetbridge.org) - [Blog](https://blog.freeyourgadget.org) - [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki) - <a rel="me" href="https://social.anoxinon.de/@gadgetbridge">Mastodon</a>
[Homepage](https://gadgetbridge.org) - [Blog](https://blog.freeyourgadget.org) - <a rel="me" href="https://social.anoxinon.de/@gadgetbridge">Mastodon</a>
[![Donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/Gadgetbridge/donate)
@ -21,121 +21,25 @@ vendor's servers.
## Code Licenses
* Gadgetbrige is licensed under the AGPLv3
* Gadgetbridge is licensed under the AGPLv3
* Files in app/src/main/java/net/osmand/ and app/src/main/aidl/net/osmand/ are licensed under the GPLv3 by OsmAnd BV
* Files in app/src/main/java/org/bouncycastle are licensed under the MIT license by The Legion of the Bouncy Castle Inc.
## Download
[<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://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/CHANGELOG.md)
- [Nightly releases](https://freeyourgadget.codeberg.page/fdroid/repo?fingerprint=CD381ECCC465AB324E21BCC335895615E07E70EE11E9FD1DF3C020C5194F00B2)
- Nightly releases are updated more frequently and may be less stable than standard releases, and they are distributed by our F-Droid repository unlike standard releases.
- [List of changes](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/CHANGELOG.md)
## Supported Devices
**(WARNING: Some of them WIP and some of them without maintainer)**
- Amazfit
- [Amazfit Active](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Active), [Amazfit Active Edge](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Active-Edge) [**\[!\]**](#special-pairing-procedures)
- [Balance](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Balance) [**\[!\]**](#special-pairing-procedures)
- [Band 5](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Band-5), [Band 7](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Band-7) [**\[!\]**](#special-pairing-procedures)
- [Bip](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip)
- [Bip Lite](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-Lite), [Bip S](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-S), [Bip U, Bip U Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-U) [**\[!\]**](#special-pairing-procedures)
- [Bip 3 Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-3-Pro) [**\[!\]**](#special-pairing-procedures)
- [Bip 5 (experimental)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-5) [**\[!\]**](#special-pairing-procedures)
- [Cor](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor), [Cor 2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor-2)
- [Falcon (experimental)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Falcon) [**\[!\]**](#special-pairing-procedures)
- [GTR](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR), [GTR 2/2e](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR), [GTR 3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR-3), [GTR 3 Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR-3-Pro), [GTR 4](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR-4) [**\[!\]**](#special-pairing-procedures)
- [GTR Mini](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR-Mini) [**\[!\]**](#special-pairing-procedures)
- [GTS](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS), [GTS 2/2e](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS), [GTS 3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS-3), [GTS 4](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS-4), [GTS 4 Mini](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS-4-Mini) [**\[!\]**](#special-pairing-procedures)
- [Neo](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Neo) [**\[!\]**](#special-pairing-procedures)
- T-Rex, T-Rex Pro, [T-Rex 2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-T-Rex-2) [**\[!\]**](#special-pairing-procedures)
- [T-Rex Ultra (experimental)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-T-Rex-Ultra) [**\[!\]**](#special-pairing-procedures)
- [Cheetah (Round/Square) (experimental)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cheetah) [**\[!\]**](#special-pairing-procedures)
- [Cheetah Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cheetah-Pro) [**\[!\]**](#special-pairing-procedures)
- Verge Lite [**\[!\]**](#special-pairing-procedures)
- [X ](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-5) [**\[!\]**](#special-pairing-procedures)
- [Bangle.js](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Bangle.js)
- BFH-16
- [Casio](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Casio)
- Casio GB-X6900B
- Casio GB-6900B
- Casio GB-5600B
- Casio GW-B5600
- Casio GMW-B5000 (untested)
- Casio STB-1000
- Casio GBX-100
- Casio GBD-100
- Casio GBD-200
- Casio GBD-H1000
- [Femometer Vinca II](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Femometer-Vinca-II)
- [FitPro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/FitPro)
- Fossil
- [Hybrid HR](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Fossil-Hybrid-HR) [**\[!\]**](#special-pairing-procedures)
- Q Hybrid
- [Galaxy Buds](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds)
- [Galaxy Buds](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#user-content-galaxy-buds)
- [Galaxy Buds Live](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#user-content-galaxy-buds-live)
- [Galaxy Buds Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#galaxy-buds-pro)
- [Galaxy Buds2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#galaxy-buds2)
- [Galaxy Buds2 Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#galaxy-buds2-pro)
- Garmin
- Vívomove HR
- [HPlus Devices (e.g. ZeBand)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/HPlus)
- ID115
- [iTag](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/iTag)
- JYou Y5
- Lefun
- Lefun ID115 Plus
- Other clones: bohemic smart bracelet
- Lenovo
- Watch 9
- [Watch X (Plus)](https://codeberg.org/mamutcho/Gadgetbridge/wiki)
- Liveview
- Makibes HR3
- Mi
- [Band, Band 1A, Band 1S](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band), [Band 2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2), [Band 3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-3)
- [Band 4](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-4), [Band 5](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-5), [Band 6](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-6) [**\[!\]**](#special-pairing-procedures)
- [Xiaomi Smart Band 7](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-7) [**\[!\]**](#special-pairing-procedures)
- Xiaomi Temperature and Humidity Monitor Clock (LYWSD02/LYWSD02MMC) (partial support)
- Scale 2 (Currently only displays a toast after stepping on the scale)
- [MyKronoz ZeTime](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/MyKronoz-ZeTime)
- NO.1 F1
- [Nothing Ear (1)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Nothing-Ear-%281%29)
- [Nut Mini 3, Nut 2 and possibly others](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Nut)
- Pebble
- [Pebble, Steel, Time, Time Steel, Time Round, 2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Pebble)
- PineTime (InfiniTime Firmware)
- Roidmi, Roidmi 3, Mojietu 3 (Bluetooth FM Transmitters)
- [SMA](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/SMA) Q2 (SMA-Q2-OSS Firmware)
- Sony
- [Headphones](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Sony-Headphones)
- LinkBuds S
- WH-1000XM2, WH-1000XM3, WH-1000XM4, WH-1000XM5
- WF-SP800N
- WF-1000XM3, WF-1000XM4, WF-1000XM5 (experimental)
- [Wena 3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Sony-Wena-3)
- Teclast H10, H30
- TLW64
- Vibratissimo (Experimental)
- Wasp-OS devices
- XWatch (Affordable Chinese Casio-like smartwatches)
- [Zepp E](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR) [**\[!\]**](#special-pairing-procedures)
- [Shell Racing cars](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/SuperCars) (BLE RC car models)
- [Flipper Zero](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Flipper-Zero) (Multi-tool Device for Geeks)
- VESC (BLDC controller VESC)
- UM25 (USB Voltage meter)
### Special Pairing Procedures
Some Huami / Amazfit / Mi / Zepp devices can only be paired with Gadgetbridge using a secret key that has to be obtained once using the proprietary app with an account. Detailed instructions in the wiki: [Huami Server Pairing](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Huami-Server-Pairing)
The Fossil Hybrid HR also requires using the proprietary app, but with a more complicated procedure. Details in the wiki: [Hybrid HR](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Fossil-Hybrid-HR).
Please see the [Gadgets](https://gadgetbridge.org/gadgets/) page on the website for a complete list of supported devices.
## Features
Please see [FEATURES.md](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/FEATURES.md)
Please see the [Features](https://gadgetbridge.org/basics/features/) page on the website.
## Authors
### Core Team (in order of first code contribution)

View File

@ -78,17 +78,19 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
compileSdkVersion 33
buildToolsVersion "33.0.0"
namespace 'nodomain.freeyourgadget.gadgetbridge'
defaultConfig {
applicationId "nodomain.freeyourgadget.gadgetbridge"
minSdkVersion 21
targetSdkVersion 33
compileSdk 33
// Note: always bump BOTH versionCode and versionName!
versionName "0.76.1"
versionCode 226
versionName "0.79.0"
versionCode 229
vectorDrawables.useSupportLibrary = true
buildConfigField "String", "GIT_HASH_SHORT", "\"${getGitHashShort()}\""
buildConfigField "boolean", "INTERNET_ACCESS", "false"
@ -112,8 +114,8 @@ android {
flavorDimensions "device_type"
productFlavors {
main {
// Ensure that when starting from scratch, 'main' is selected, not 'banglejs'
mainline {
// Ensure that when starting from scratch, 'mainline' is selected, not 'banglejs'
getIsDefault().set(true)
// the default build product flavor
dimension "device_type"
@ -162,20 +164,20 @@ android {
resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly"
resValue "string", "about_description", "@string/about_description_main_nightly"
resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly"
debuggable true
if (System.getProperty("nightly_store_file") != null) {
signingConfig signingConfigs.nightly
//this was conflicting with regular debug type (it should not), so it is only available for CI builds:
productFlavors.main.resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
productFlavors.main.resValue "string", "app_name", "@string/application_name_main_nightly"
productFlavors.main.resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nightly"
productFlavors.main.resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly"
productFlavors.main.resValue "string", "about_description", "@string/about_description_main_nightly"
productFlavors.main.resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly"
productFlavors.mainline.resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
productFlavors.mainline.resValue "string", "app_name", "@string/application_name_main_nightly"
productFlavors.mainline.resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nightly"
productFlavors.mainline.resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly"
productFlavors.mainline.resValue "string", "about_description", "@string/about_description_main_nightly"
productFlavors.mainline.resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly"
//keep the pebble provider for people who want this. In case of need we can create Banglejs Nopebble
productFlavors.banglejs.resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
productFlavors.banglejs.resValue "string", "app_name", "@string/application_name_banglejs_nightly"
@ -222,10 +224,9 @@ android {
}
lintOptions {
lint {
abortOnError ABORT_ON_CHECK_FAILURE
lintConfig file("${project.rootDir}/app/src/main/lint.xml")
lintConfig file("$rootDir/app/src/main/lint.xml")
// If true, generate an HTML report (with issue explanations, sourcecode, etc)
htmlReport true
// Optional path to report (default will be lint-results.html in the builddir)
@ -251,7 +252,7 @@ dependencies {
// testImplementation "ch.qos.logback:logback-core:1.1.3"
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
testImplementation "junit:junit:4.13.2"
testImplementation "org.mockito:mockito-core:1.10.19"
testImplementation "org.mockito:mockito-core:2.28.2"
testImplementation "org.robolectric:robolectric:4.8.2"
testImplementation "org.hamcrest:hamcrest-library:1.3"
testImplementation "com.google.code.gson:gson:2.8.9"
@ -289,9 +290,15 @@ dependencies {
implementation 'com.jaredrummler:colorpicker:1.0.2'
// implementation project(":DaoCore")
implementation 'com.github.wax911:android-emojify:0.1.7'
implementation 'com.google.protobuf:protobuf-javalite:3.10.0'
implementation 'com.google.protobuf:protobuf-javalite:3.21.7'
implementation 'com.android.volley:volley:1.2.1'
// Bouncy Castle is included directly in GB, to avoid pulling the entire dependency
// It's included in the org.bouncycastle.shaded package, to fix conflicts with
// roboelectric
//implementation 'org.bouncycastle:bcpkix-jdk18on:1.76'
//implementation 'org.bouncycastle:bcprov-jdk18on:1.76'
// NON-FOSS dependencies
// implementation('androidx.core:core-google-shortcuts:1.0.1') {
// exclude group:'com.google.android.gms'
@ -399,7 +406,7 @@ tasks.clean.dependsOn(tasks.cleanGenerated)
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.10.0'
artifact = 'com.google.protobuf:protoc:3.21.7'
}
generateProtoTasks {
all().each { task ->

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="nodomain.freeyourgadget.gadgetbridge">
xmlns:tools="http://schemas.android.com/tools">
<!--
Comment in for testing Pebble Emulator
@ -600,6 +599,10 @@
android:name=".activities.ConfigureContacts"
android:label="@string/title_activity_set_contacts"
android:parentActivityName=".activities.ControlCenterv2" />
<activity
android:name=".activities.widgets.WidgetScreensListActivity"
android:label="@string/menuitem_widgets"
android:parentActivityName=".activities.ControlCenterv2" />
<activity
android:name=".activities.ConfigureWorldClocks"
android:label="@string/pref_world_clocks_title"
@ -625,6 +628,12 @@
android:parentActivityName=".activities.ConfigureReminders"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".activities.widgets.WidgetScreenDetailsActivity"
android:label="@string/widget_screen"
android:parentActivityName=".activities.widgets.WidgetScreensListActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".activities.WorldClockDetails"
android:label="@string/title_activity_world_clock_details"

View File

@ -1,6 +1,8 @@
/* Copyright (C) 2015-2021 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Martin, Matthieu Baerts, Normano64, odavo32nof, Pauli Salmenrinne,
Pavel Elagin, Petr Vaněk, Saul Nunez, Taavi Eomäe
/* Copyright (C) 2015-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Damien Gaignon, Daniel Dakhno, Daniele Gobbetti, Davis Mosenkovs,
Dmitriy Bogdanov, Joel Beckmeyer, José Rebelo, Kornél Schmidt, Ludovic
Jozeau, Martin, Martin.JM, mvn23, Normano64, odavo32nof, Pauli Salmenrinne,
Pavel Elagin, Petr Vaněk, Saul Nunez, Taavi Eomäe, x29a
This file is part of Gadgetbridge.
@ -15,7 +17,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge;
import android.annotation.TargetApi;
@ -54,6 +56,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
@ -121,9 +124,9 @@ public class GBApplication extends Application {
private static SharedPreferences sharedPrefs;
private static final String PREFS_VERSION = "shared_preferences_version";
//if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version
private static final int CURRENT_PREFS_VERSION = 26;
private static final int CURRENT_PREFS_VERSION = 28;
private static LimitedQueue mIDSenderLookup = new LimitedQueue(16);
private static final LimitedQueue<Integer, String> mIDSenderLookup = new LimitedQueue<>(16);
private static Prefs prefs;
private static GBPrefs gbPrefs;
private static LockHandler lockHandler;
@ -1186,7 +1189,7 @@ public class GBApplication extends Application {
if (oldVersion < 16) {
// If transliteration was enabled for a device, migrate it to the per-language setting
final String defaultLanguagesIfEnabled = "extended_ascii,common_symbols,scandinavian,german,russian,hebrew,greek,ukranian,arabic,persian,latvian,lithuanian,polish,estonian,icelandic,czech,turkish,bengali,korean";
final String defaultLanguagesIfEnabled = "extended_ascii,common_symbols,scandinavian,german,russian,hebrew,greek,ukranian,arabic,persian,latvian,lithuanian,polish,estonian,icelandic,czech,turkish,bengali,korean,hungarian";
try (DBHandler db = acquireDB()) {
final DaoSession daoSession = db.getDaoSession();
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
@ -1372,6 +1375,78 @@ public class GBApplication extends Application {
}
}
if (oldVersion < 27) {
try (DBHandler db = acquireDB()) {
final DaoSession daoSession = db.getDaoSession();
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
for (final Device dbDevice : activeDevices) {
final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
for (final Map.Entry<String, ?> entry : deviceSharedPrefs.getAll().entrySet()) {
final String key = entry.getKey();
if (key.startsWith("huami_2021_known_config_")) {
deviceSharedPrefsEdit.putString(
key.replace("huami_2021_known_config_", "") + "_is_known",
entry.getValue().toString()
);
} else if (key.endsWith("_huami_2021_possible_values")) {
deviceSharedPrefsEdit.putString(
key.replace("_huami_2021_possible_values", "") + "_possible_values",
entry.getValue().toString()
);
}
}
deviceSharedPrefsEdit.apply();
}
} catch (Exception e) {
Log.w(TAG, "error acquiring DB lock");
}
}
if (oldVersion < 28) {
try (DBHandler db = acquireDB()) {
final DaoSession daoSession = db.getDaoSession();
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
for (final Device dbDevice : activeDevices) {
final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
boolean shouldApply = false;
if (!"UNKNOWN".equals(deviceSharedPrefs.getString("events_forwarding_fellsleep_action_selection", "UNKNOWN"))) {
shouldApply = true;
deviceSharedPrefsEdit.putStringSet(
"events_forwarding_fellsleep_action_selections",
Collections.singleton(deviceSharedPrefs.getString("events_forwarding_fellsleep_action_selection", "UNKNOWN"))
);
}
if (!"UNKNOWN".equals(deviceSharedPrefs.getString("events_forwarding_wokeup_action_selection", "UNKNOWN"))) {
shouldApply = true;
deviceSharedPrefsEdit.putStringSet(
"events_forwarding_wokeup_action_selections",
Collections.singleton(deviceSharedPrefs.getString("events_forwarding_wokeup_action_selection", "UNKNOWN"))
);
}
if (!"UNKNOWN".equals(deviceSharedPrefs.getString("events_forwarding_startnonwear_action_selection", "UNKNOWN"))) {
shouldApply = true;
deviceSharedPrefsEdit.putStringSet(
"events_forwarding_startnonwear_action_selections",
Collections.singleton(deviceSharedPrefs.getString("events_forwarding_startnonwear_action_selection", "UNKNOWN"))
);
}
if (shouldApply) {
deviceSharedPrefsEdit.apply();
}
}
} catch (Exception e) {
Log.w(TAG, "error acquiring DB lock");
}
}
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
editor.apply();
}
@ -1408,7 +1483,7 @@ public class GBApplication extends Application {
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
public static LimitedQueue getIDSenderLookup() {
public static LimitedQueue<Integer, String> getIDSenderLookup() {
return mIDSenderLookup;
}
@ -1489,6 +1564,10 @@ public class GBApplication extends Application {
return BuildConfig.APPLICATION_ID.contains("nightly");
}
public static boolean isDebug() {
return BuildConfig.DEBUG;
}
public String getVersion() {
try {
return getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA).versionName;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge;
/**

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2021 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge;
public class GBException extends Exception {

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge;
import android.database.sqlite.SQLiteDatabase;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2016-2021 Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, José Rebelo, Pavel Elagin, Petr Vaněk
This file is part of Gadgetbridge.
@ -13,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge;
import android.util.Log;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2021 Carsten Pfeiffer
/* Copyright (C) 2015-2024 Carsten Pfeiffer
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2016-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2016-2024 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Dmitry Markin, Ganblejs, José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -13,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge;
import android.annotation.TargetApi;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous
/* Copyright (C) 2019-2024 Andreas Shimokawa, Carsten Pfeiffer, Ganblejs,
José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -11,27 +12,9 @@
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.
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/>. */
/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous
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.
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge;
import android.app.PendingIntent;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Lem Dulfo
/* Copyright (C) 2020-2024 Petr Vaněk, Taavi Eomäe
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2023 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo,
vanous, José Rebelo
/* Copyright (C) 2020-2024 Andreas Shimokawa, José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_ACTIVETIME_MINUTES;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniele Gobbetti
/* Copyright (C) 2015-2024 Carsten Pfeiffer, Daniele Gobbetti
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.view.ViewGroup;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo
/* Copyright (C) 2017-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniele Gobbetti, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, walkjivefly
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import androidx.annotation.Nullable;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2017-2024 Andreas Shimokawa, Carsten Pfeiffer, Petr Vaněk
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019-2023 Andreas Shimokawa, Cre3per, José Rebelo
/* Copyright (C) 2023-2024 Andreas Shimokawa, Arjan Schrijver, José Rebelo
This file is part of Gadgetbridge.
@ -13,11 +13,12 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.fragment.app.DialogFragment;
import androidx.preference.EditTextPreference;
@ -38,9 +39,12 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreferenceFragment;
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialEditTextPreferenceDialogFragment;
@ -199,7 +203,29 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragmentCompa
}
if (getPreferenceKeysWithSummary().contains(key)) {
final String summary = prefs.getString(key, preference.getSummary() != null ? preference.getSummary().toString() : "");
final String summary;
// For multi select preferences, let's set the summary to the values, comma-delimited
if (preference instanceof MultiSelectListPreference) {
final Set<String> prefSetValue = prefs.getStringSet(key, Collections.emptySet());
if (prefSetValue.isEmpty()) {
summary = requireContext().getString(R.string.not_set);
} else {
final MultiSelectListPreference multiSelectListPreference = (MultiSelectListPreference) preference;
final CharSequence[] entries = multiSelectListPreference.getEntries();
final CharSequence[] entryValues = multiSelectListPreference.getEntryValues();
final List<String> translatedEntries = new ArrayList<>();
for (int i = 0; i < entryValues.length; i++) {
if (prefSetValue.contains(entryValues[i].toString())) {
translatedEntries.add(entries[i].toString());
}
}
summary = TextUtils.join(", ", translatedEntries);
}
} else {
summary = prefs.getString(key, preference.getSummary() != null ? preference.getSummary().toString() : "");
}
preference.setSummary(summary);
}

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Christian
Fischer, Daniele Gobbetti, Lem Dulfo
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Christian
Fischer, Daniele Gobbetti, José Rebelo, Lem Dulfo, Petr Vaněk, Taavi Eomäe
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.BroadcastReceiver;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019-2023 Andreas Shimokawa, José Rebelo
/* Copyright (C) 2023-2024 José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
/* Copyright (C) 2017-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniele Gobbetti, José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.DatePickerDialog;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, Pavel Elagin
/* Copyright (C) 2020-2024 José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Context;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019-2020 vanous
/* Copyright (C) 2020-2024 Daniel Dakhno, Petr Vaněk
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.DatePickerDialog;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, Pavel Elagin
/* Copyright (C) 2020-2024 José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.graphics.Bitmap;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Lem Dulfo
/* Copyright (C) 2020-2024 Andreas Shimokawa, Arjan Schrijver, Daniel Dakhno,
José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,9 +14,11 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.*;
import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Context;
@ -86,7 +88,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryJsonSummary;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.SwipeEvents;
@ -464,13 +465,13 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
if (!show_raw_data) {
//special casing here + imperial units handling
switch (unit) {
case "cm":
case UNIT_CM:
if (units.equals(UNIT_IMPERIAL)) {
value = value * 0.0328084;
unit = "ft";
}
break;
case "meters_second":
case UNIT_METERS_PER_SECOND:
if (units.equals(UNIT_IMPERIAL)) {
value = value * 2.236936D;
unit = "mi_h";
@ -479,7 +480,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
unit = "km_h";
}
break;
case "seconds_m":
case UNIT_SECONDS_PER_M:
if (units.equals(UNIT_IMPERIAL)) {
value = value * (1609.344 / 60D);
unit = "minutes_mi";
@ -488,7 +489,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
unit = "minutes_km";
}
break;
case "seconds_km":
case UNIT_SECONDS_PER_KM:
if (units.equals(UNIT_IMPERIAL)) {
value = value / 60D * 1.609344;
unit = "minutes_mi";
@ -497,7 +498,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
unit = "minutes_km";
}
break;
case "meters":
case UNIT_METERS:
if (units.equals(UNIT_IMPERIAL)) {
value = value * 3.28084D;
unit = "ft";

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniel
Dakhno, Daniele Gobbetti, Dmitry Markin, Lem Dulfo, Taavi Eomäe
This file is part of Gadgetbridge.
@ -14,10 +14,11 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.format.DateFormat;
import android.view.MenuItem;
import android.view.View;
@ -132,10 +133,15 @@ public class AlarmDetails extends AbstractGBActivity {
int snoozeVisibility = supportsSnoozing() ? View.VISIBLE : View.GONE;
cbSnooze.setVisibility(snoozeVisibility);
int descriptionVisibility = supportsDescription() ? View.VISIBLE : View.GONE;
title.setVisibility(descriptionVisibility);
title.setVisibility(supportsTitle() ? View.VISIBLE : View.GONE);
title.setText(alarm.getTitle());
description.setVisibility(descriptionVisibility);
final int titleLimit = getAlarmTitleLimit();
if (titleLimit > 0) {
title.setFilters(new InputFilter[]{new InputFilter.LengthFilter(titleLimit)});
}
description.setVisibility(supportsDescription() ? View.VISIBLE : View.GONE);
description.setText(alarm.getDescription());
cbMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON));
@ -145,7 +151,6 @@ public class AlarmDetails extends AbstractGBActivity {
cbFriday.setChecked(alarm.getRepetition(Alarm.ALARM_FRI));
cbSaturday.setChecked(alarm.getRepetition(Alarm.ALARM_SAT));
cbSunday.setChecked(alarm.getRepetition(Alarm.ALARM_SUN));
}
private boolean supportsSmartWakeup() {
@ -156,6 +161,22 @@ public class AlarmDetails extends AbstractGBActivity {
return false;
}
private boolean supportsTitle() {
if (device != null) {
DeviceCoordinator coordinator = device.getDeviceCoordinator();
return coordinator.supportsAlarmTitle(device);
}
return false;
}
private int getAlarmTitleLimit() {
if (device != null) {
DeviceCoordinator coordinator = device.getDeviceCoordinator();
return coordinator.getAlarmTitleLimit(device);
}
return -1;
}
private boolean supportsDescription() {
if (device != null) {
DeviceCoordinator coordinator = device.getDeviceCoordinator();

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Lem Dulfo
/* Copyright (C) 2015-2024 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Lem Dulfo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;

View File

@ -1,3 +1,19 @@
/* Copyright (C) 2021-2024 Daniel Dakhno, José Rebelo, Petr Vaněk
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.DatePickerDialog;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, Pavel Elagin
/* Copyright (C) 2021-2024 José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Context;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti
/* Copyright (C) 2017-2024 Carsten Pfeiffer, Daniele Gobbetti, José Rebelo,
Ludovic Jozeau
This file is part of Gadgetbridge.
@ -13,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.Manifest;

View File

@ -1,5 +1,6 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo, vanous
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Damien
Gaignon, Daniel Dakhno, Daniele Gobbetti, Dmitry Markin, José Rebelo,
Lem Dulfo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +15,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.BroadcastReceiver;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 José Rebelo
/* Copyright (C) 2023-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 José Rebelo
/* Copyright (C) 2021-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
This file is part of Gadgetbridge.
@ -13,16 +13,20 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -49,7 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.Reminder;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
@ -61,12 +65,25 @@ public class ConfigureReminders extends AbstractGBActivity {
private GBReminderListAdapter mGBReminderListAdapter;
private GBDevice gbDevice;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (DeviceService.ACTION_SAVE_REMINDERS.equals(intent.getAction())) {
updateRemindersFromDB();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_configure_reminders);
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(DeviceService.ACTION_SAVE_REMINDERS);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
gbDevice = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
mGBReminderListAdapter = new GBReminderListAdapter(this);
@ -118,6 +135,12 @@ public class ConfigureReminders extends AbstractGBActivity {
});
}
@Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 José Rebelo
/* Copyright (C) 2022-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.BroadcastReceiver;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 José Rebelo
/* Copyright (C) 2023-2024 Daniel Dakhno, José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;

View File

@ -1,5 +1,7 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Johannes Tysiak, Taavi Eomäe, vanous
/* Copyright (C) 2016-2024 Andreas Shimokawa, Andrzej Surowiec, Arjan
Schrijver, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Ganblejs,
gfwilliams, Gordon Williams, Johannes Tysiak, José Rebelo, marco.altomonte,
Petr Vaněk, Taavi Eomäe
This file is part of Gadgetbridge.
@ -14,7 +16,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2016-2020 Alberto, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, vanous
/* Copyright (C) 2021-2024 Arjan Schrijver, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Context;

View File

@ -1,6 +1,7 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Frank Slezak, ivanovlev, Kasha, Lem Dulfo, Pavel Elagin, Steffen
Liebergeld, vanous
/* Copyright (C) 2015-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Dmitriy Bogdanov, Frank Slezak,
Ganblejs, ivanovlev, José Rebelo, Kamalei Zestri, Kasha, Lem Dulfo, Pavel
Elagin, Petr Vaněk, Steffen Liebergeld, Tim
This file is part of Gadgetbridge.
@ -15,7 +16,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import static android.content.Intent.EXTRA_SUBJECT;
@ -63,6 +64,7 @@ import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
@ -778,7 +780,7 @@ public class DebugActivity extends AbstractGBActivity {
final GBDevice device = devices.get(0);
final CompanionDeviceManager manager = (CompanionDeviceManager) GBApplication.getContext().getSystemService(Context.COMPANION_DEVICE_SERVICE);
final CompanionDeviceManager manager = (CompanionDeviceManager) getSystemService(Context.COMPANION_DEVICE_SERVICE);
if (manager.getAssociations().contains(device.getAddress())) {
GB.toast(device.getAliasOrName() + " already paired as companion", Toast.LENGTH_LONG, GB.INFO);
@ -801,7 +803,7 @@ public class DebugActivity extends AbstractGBActivity {
}
@Override
public void onDeviceFound(final IntentSender chooserLauncher) {
public void onDeviceFound(@NonNull final IntentSender chooserLauncher) {
GB.toast("Found device", Toast.LENGTH_SHORT, GB.INFO);
try {

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo, Uwe Hermann
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Davis Mosenkovs, Lem Dulfo, Taavi Eomäe, Uwe Hermann
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Intent;
@ -35,8 +35,10 @@ import androidx.core.app.NavUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -51,6 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.GBWeb
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.JSInterface;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.WebViewSingleton;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
@ -91,28 +94,22 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity {
DeviceManager deviceManager = ((GBApplication) getApplication()).getDeviceManager();
List<GBDevice> deviceList = deviceManager.getDevices();
for (GBDevice device : deviceList) {
if (device.getState() == GBDevice.State.INITIALIZED) {
if (device.getType().equals(DeviceType.PEBBLE)) {
currentDevice = device;
break;
} else {
LOG.error("attempting to load pebble configuration but a different device type is connected!!!");
finish();
return;
}
if (device.getState() == GBDevice.State.INITIALIZED && device.getType().equals(DeviceType.PEBBLE)) {
currentDevice = device;
break;
}
}
if (currentDevice == null) {
//then try to reconnect to last connected device
String btDeviceAddress = GBApplication.getPrefs().getPreferences().getString("last_device_address", null);
if (btDeviceAddress != null) {
GBDevice candidate = DeviceHelper.getInstance().findAvailableDevice(btDeviceAddress, this);
if(!candidate.isConnected() && candidate.getType() == DeviceType.PEBBLE){
//then try to reconnect to one of last connected Pebble devices
Set<String> lastDeviceAddresses = GBApplication.getPrefs().getStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, Collections.emptySet());
for (GBDevice device : deviceList) {
if (!device.isConnected() && device.getType() == DeviceType.PEBBLE && lastDeviceAddresses.contains(device.getAddress())) {
Intent intent = new Intent(this, DeviceCommunicationService.class)
.setAction(ACTION_CONNECT)
.putExtra(GBDevice.EXTRA_DEVICE, currentDevice);
.putExtra(GBDevice.EXTRA_DEVICE, device);
this.startService(intent);
currentDevice = candidate;
currentDevice = device;
break;
}
}
}
@ -195,6 +192,9 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity {
webSettings.setDomStorageEnabled(true);
//needed for localstorage
webSettings.setDatabaseEnabled(true);
// #3373 #3424 - Fix configuration for pebble apps
// TODO: this should use a WebViewAssetLoader
webSettings.setAllowFileAccess(true);
JSInterface gbJSInterface = new JSInterface(device, uuid);
myWebView.addJavascriptInterface(gbJSInterface, "GBjs");

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2018-2020 Andreas Shimokawa, Carsten Pfeiffer, Cre3per,
Daniele Gobbetti
/* Copyright (C) 2018-2024 Andreas Shimokawa, Anemograph, Carsten Pfeiffer,
Cre3per, Daniele Gobbetti, Dmitriy Bogdanov, José Rebelo, Pauli Salmenrinne
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.BroadcastReceiver;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Lem Dulfo, Taavi Eomäe
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniel
Dakhno, Daniele Gobbetti, José Rebelo, Lem Dulfo, Petr Vaněk, Taavi Eomäe
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.BroadcastReceiver;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import java.util.Locale;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Lem Dulfo
/* Copyright (C) 2021-2024 Gordon Williams, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.ClipData;

View File

@ -1,3 +1,19 @@
/* Copyright (C) 2021-2024 Petr Vaněk
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Dialog;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2020 Carsten Pfeiffer, Dikay900
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Dikay900
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.graphics.Bitmap;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2018-2020 abettenburg, AndrewBedscastle, Carsten Pfeiffer,
/* Copyright (C) 2018-2024 abettenburg, AndrewBedscastle, Carsten Pfeiffer,
Daniele Gobbetti
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2023 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo,
vanous, José Rebelo
/* Copyright (C) 2021-2024 José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Intent;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2020 vanous,
/* Copyright (C) 2022-2024 Petr Vaněk
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 José Rebelo
/* Copyright (C) 2021-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.DatePickerDialog;

View File

@ -1,6 +1,7 @@
/* Copyright (C) 2015-2023 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniel Dakhno, Daniele Gobbetti, Felix Konstantin Maurer, José Rebelo,
Martin, Normano64, Pavel Elagin, Sebastian Kranz, vanous
/* Copyright (C) 2015-2024 0nse, Andreas Shimokawa, Anemograph, Arjan
Schrijver, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Felix Konstantin
Maurer, José Rebelo, Martin, Normano64, Pavel Elagin, Petr Vaněk, Sebastian
Kranz, Taavi Eomäe
This file is part of Gadgetbridge.
@ -15,7 +16,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.Manifest;

View File

@ -1,3 +1,20 @@
/* Copyright (C) 2022-2024 Arjan Schrijver, Damien Gaignon, Daniel Dakhno,
Petr Vaněk
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 José Rebelo
/* Copyright (C) 2023-2024 José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Intent;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;

View File

@ -1,3 +1,19 @@
/* Copyright (C) 2022-2024 Ganblejs
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2019-2020 vanous
/* Copyright (C) 2019-2024 Dmitry Markin, José Rebelo, Petr Vaněk,
Taavi Eomäe
This file is part of Gadgetbridge.
@ -13,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;

View File

@ -1,3 +1,19 @@
/* Copyright (C) 2020-2024 Arjan Schrijver, Daniel Dakhno, Petr Vaněk
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 José Rebelo
/* Copyright (C) 2022-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.DialogInterface;

View File

@ -1,22 +1,19 @@
/*
* Copyright (C) 2023 akasaka / Genjitsu Labs
*
* 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/>.
*/
/* Copyright (C) 2023-2024 akasaka / Genjitsu Labs
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.app_specific_notifications;
import android.os.Bundle;

View File

@ -1,22 +1,19 @@
/*
* Copyright (C) 2023 akasaka / Genjitsu Labs
*
* 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/>.
*/
/* Copyright (C) 2023-2024 akasaka / Genjitsu Labs, Daniel Dakhno
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.app_specific_notifications;
import android.os.Bundle;

View File

@ -1,5 +1,6 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Konrad Iturbe, Lem Dulfo
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniel Dakhno, Daniele Gobbetti, José Rebelo, Konrad Iturbe,
TylerWilliamson
This file is part of Gadgetbridge.
@ -14,7 +15,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_ACTION_DOWNLOADED_FILE;
@ -279,6 +280,11 @@ public abstract class AbstractAppManagerFragment extends Fragment {
return cachedAppList;
}
if (cachePath == null) {
LOG.warn("Cached apps path is null");
return Collections.emptyList();
}
File[] files;
if (uuids == null) {
files = cachePath.listFiles();

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniele Gobbetti, José Rebelo
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
import android.app.Activity;
@ -45,6 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractFragmentPagerAdapter;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBFragmentActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.FwAppInstallerActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
@ -56,6 +57,8 @@ public class AppManagerActivity extends AbstractGBFragmentActivity {
private GBDevice mGBDevice = null;
private List<String> enabledTabsList;
public GBDevice getGBDevice() {
return mGBDevice;
}
@ -75,6 +78,20 @@ public class AppManagerActivity extends AbstractGBFragmentActivity {
throw new IllegalArgumentException("Must provide a device when invoking this activity");
}
final DeviceCoordinator coordinator = mGBDevice.getDeviceCoordinator();
enabledTabsList = new ArrayList<>();
if (coordinator.supportsCachedAppManagement(mGBDevice)) {
enabledTabsList.add("cache");
}
if (coordinator.supportsInstalledAppManagement(mGBDevice)) {
enabledTabsList.add("apps");
}
if (coordinator.supportsWatchfaceManagement(mGBDevice)) {
enabledTabsList.add("watchfaces");
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
assert fab != null;
fab.setOnClickListener(new View.OnClickListener() {
@ -114,12 +131,12 @@ public class AppManagerActivity extends AbstractGBFragmentActivity {
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
switch (position) {
case 0:
switch (enabledTabsList.get(position)) {
case "cache":
return new AppManagerFragmentCache();
case 1:
case "apps":
return new AppManagerFragmentInstalledApps();
case 2:
case "watchfaces":
return new AppManagerFragmentInstalledWatchfaces();
}
return null;
@ -127,19 +144,18 @@ public class AppManagerActivity extends AbstractGBFragmentActivity {
@Override
public int getCount() {
return 3;
return enabledTabsList.toArray().length;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
switch (enabledTabsList.get(position)) {
case "cache":
return getString(R.string.appmanager_cached_watchapps_watchfaces);
case 1:
case "apps":
return getString(R.string.appmanager_installed_watchapps);
case 2:
case "watchfaces":
return getString(R.string.appmanager_installed_watchfaces);
case 3:
}
return super.getPageTitle(position);
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, José Rebelo
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
import java.util.List;

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, Daniele
Gobbetti
This file is part of Gadgetbridge.
@ -13,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
import java.nio.charset.StandardCharsets;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
import java.util.ArrayList;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Dikay900, Pavel Elagin, vanous, walkjivefly
/* Copyright (C) 2023-2024 Daniel Dakhno, José Rebelo
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.util.TypedValue;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Dikay900, Pavel Elagin, vanous, walkjivefly
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, José Rebelo, Pavel Elagin, Petr Vaněk, walkjivefly
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.annotation.SuppressLint;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, vanous, Vebryn
/* Copyright (C) 2023-2024 José Rebelo
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.BroadcastReceiver;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 0nse, Alberto, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, Pavel Elagin, vanous
/* Copyright (C) 2017-2024 Alberto, Andreas Shimokawa, Carsten Pfeiffer,
Daniele Gobbetti, José Rebelo, Pavel Elagin, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.app.Activity;
@ -371,14 +371,14 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
private ActivityAmounts getActivityAmountsForDay(DBHandler db, Calendar day, GBDevice device) {
LimitedQueue activityAmountCache = null;
LimitedQueue<Integer, ActivityAmounts> activityAmountCache = null;
ActivityAmounts amounts = null;
Activity activity = getActivity();
int key = (int) (day.getTimeInMillis() / 1000) + (mOffsetHours * 3600);
if (activity != null) {
activityAmountCache = ((ActivityChartsActivity) activity).mActivityAmountCache;
amounts = (ActivityAmounts) (activityAmountCache.lookup(key));
amounts = activityAmountCache.lookup(key);
}
if (amounts == null) {

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Pavel Elagin, vanous, Vebryn
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, José Rebelo, Pavel Elagin, Petr Vaněk, Vebryn
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import org.slf4j.Logger;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, vanous, Vebryn
/* Copyright (C) 2023-2024 Daniel Dakhno, José Rebelo, Martin.JM
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.Context;
@ -33,12 +32,13 @@ import nodomain.freeyourgadget.gadgetbridge.activities.AbstractFragmentPagerAdap
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public class ActivityChartsActivity extends AbstractChartsActivity {
LimitedQueue mActivityAmountCache = new LimitedQueue(60);
LimitedQueue<Integer, ActivityAmounts> mActivityAmountCache = new LimitedQueue<>(60);
@Override
protected AbstractFragmentPagerAdapter createFragmentPagerAdapter(final FragmentManager fragmentManager) {
@ -171,7 +171,7 @@ public class ActivityChartsActivity extends AbstractChartsActivity {
case "stress":
return getString(R.string.menuitem_stress);
case "pai":
return getString(R.string.menuitem_pai);
return getString(getDevice().getDeviceCoordinator().getPaiName());
case "stepsweek":
return getStepsTitle();
case "speedzones":

View File

@ -1,3 +1,19 @@
/* Copyright (C) 2020-2024 José Rebelo, Petr Vaněk
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.Context;

View File

@ -1,5 +1,4 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, Pavel Elagin
/* Copyright (C) 2020-2024 José Rebelo, Petr Vaněk
This file is part of Gadgetbridge.
@ -14,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.Context;

View File

@ -1,3 +1,19 @@
/* Copyright (C) 2021-2024 Arjan Schrijver, Daniel Dakhno, Petr Vaněk
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.app.DatePickerDialog;

View File

@ -1,3 +1,19 @@
/* Copyright (C) 2021-2024 Petr Vaněk
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.Context;

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, Pavel Elagin
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, José Rebelo, Pavel Elagin
This file is part of Gadgetbridge.
@ -14,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.Context;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous
/* Copyright (C) 2019-2024 Andreas Shimokawa, Petr Vaněk
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.graphics.Canvas;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2016-2020 Carsten Pfeiffer
/* Copyright (C) 2016-2024 Carsten Pfeiffer
This file is part of Gadgetbridge.
@ -13,7 +13,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
public abstract class ChartsData {

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, vanous
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo,
Petr Vaněk
This file is part of Gadgetbridge.
@ -13,7 +14,7 @@
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/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.view.ViewGroup;

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