Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding chart to GDH #202

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
025c0b3
add chart to phone
pachi81 Dec 20, 2024
bf193fa
chart as bitmap
pachi81 Jan 19, 2025
add18a2
Rename class
pachi81 Jan 20, 2025
fd5cb42
Chart time line added
pachi81 Jan 20, 2025
a8912de
Create chart data from LibreLinkUp
pachi81 Jan 21, 2025
e0609a7
Reset chart for GraphData changed
pachi81 Jan 21, 2025
b9440a2
Update gradle
pachi81 Jan 23, 2025
264f309
Chart creation asynch
pachi81 Jan 23, 2025
5b238b6
Using database
pachi81 Jan 24, 2025
6faf101
Fixes for chart
pachi81 Jan 26, 2025
feb99db
DB sync
pachi81 Jan 28, 2025
83741a4
Wear Graph
pachi81 Jan 28, 2025
b27bfd8
Refactor chart
pachi81 Jan 29, 2025
67ebf63
Chart complication
pachi81 Jan 29, 2025
cedf8c1
Fix chart exceptions
pachi81 Jan 30, 2025
cf3902e
Wear chart duration setting
pachi81 Jan 30, 2025
ae13c45
Wear chart activity
pachi81 Jan 30, 2025
1f9b5d7
Fix duplicate values
pachi81 Jan 31, 2025
e8cdd92
Complication Tap action: show graph
pachi81 Jan 31, 2025
3b9bb6c
Graph fixes
pachi81 Jan 31, 2025
f0dfa5b
Enable touch after drawing
pachi81 Feb 2, 2025
a263b6b
Wear Graph: only last 24h
pachi81 Feb 2, 2025
c2044b0
Fix x compare
pachi81 Feb 2, 2025
b82e3bc
Cleanup DB
pachi81 Feb 3, 2025
7b06d49
Mobile Layout adjust to graph
pachi81 Feb 3, 2025
e348d50
Cleanup db data
pachi81 Feb 4, 2025
33f0649
Graphdata for Nightscout and Dexcom Share
pachi81 Feb 6, 2025
7acce5b
Disable graph setting
pachi81 Feb 7, 2025
c5b6f5f
Delta and rate calculation
pachi81 Feb 8, 2025
9ccadca
Change foreground service startup
pachi81 Feb 9, 2025
99efa70
Hungarian translation
pachi81 Feb 9, 2025
a956b88
Added widget for WearOS device battery level
rwalker-bluebeck Dec 23, 2024
2b22e3e
Moved bettery level widget into it's own class. Updated BatteryReceiv…
rwalker-bluebeck Jan 8, 2025
8618594
Now using broadcaster to update widgets. Removed DeviceName field fro…
rwalker-bluebeck Jan 8, 2025
9bd7718
Only add notifiers if widgets present. Handle watch disconnection pro…
rwalker-bluebeck Jan 9, 2025
fa3ad9c
Removed init function from BatteryLevelWidgetNotifier. Added safety c…
rwalker-bluebeck Jan 9, 2025
a575b06
Use pickBestNodeId to get battery level
rwalker-bluebeck Jan 9, 2025
d1032c5
Change no value color and wear display-name
pachi81 Feb 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ release/
dev_release/
debug/
second/
/.kotlin/
11 changes: 6 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.6.1' apply false
id 'com.android.library' version '8.6.1' apply false
id 'org.jetbrains.kotlin.android' version '1.9.23' apply false
id 'com.android.application' version '8.8.0' apply false
id 'com.android.library' version '8.8.0' apply false
id 'org.jetbrains.kotlin.android' version '2.1.0' apply false
id 'com.google.devtools.ksp' version "2.1.0-1.0.29" apply false
}

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

project.ext.set("versionCode", 98)
project.ext.set("versionName", "1.3")
project.ext.set("versionCode", 99)
project.ext.set("versionName", "1.3.1")
project.ext.set("compileSdk", 34)
project.ext.set("targetSdk", 34)
project.ext.set("minSdk", 26)
Expand Down
9 changes: 9 additions & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id 'com.google.devtools.ksp'
}

android {
Expand Down Expand Up @@ -48,10 +49,18 @@ dependencies {
implementation 'com.google.android.gms:play-services-wearable:19.0.0'
implementation 'androidx.work:work-runtime:2.9.1'
implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
testImplementation 'junit:junit:4.13.2'
testImplementation 'io.mockk:mockk:1.13.12'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
testImplementation 'org.mockito:mockito-core:4.11.0'
testImplementation 'org.mockito.kotlin:mockito-kotlin:4.0.0'
implementation 'com.google.code.gson:gson:2.10.1'

//Room
def roomVersion = "2.6.1"
implementation("androidx.room:room-runtime:$roomVersion")
implementation("androidx.room:room-ktx:$roomVersion")
ksp("androidx.room:room-compiler:$roomVersion")
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ object Constants {
const val REQUEST_DATA_MESSAGE_PATH = "/request_data_intent"
const val REQUEST_LOGCAT_MESSAGE_PATH = "/request_logcat_intent"
const val LOGCAT_CHANNEL_PATH = "/logcat_intent"
const val DB_SYNC_CHANNEL_PATH = "/db_sync_intent"
const val COMMAND_PATH = "/command_intent"
const val GLUCODATA_BROADCAST_ACTION = "glucodata.Minute"
const val SETTINGS_BUNDLE = "settings_bundle"
Expand All @@ -28,6 +29,7 @@ object Constants {
const val ACTION_FLOATING_WIDGET_TOGGLE = ACTION_PREFIX + "floating_widget_toggle"
const val ACTION_DUMMY_VALUE = ACTION_PREFIX + "dummy_value"
const val ACTION_SPEAK = ACTION_PREFIX + "speak"
const val ACTION_GRAPH = ACTION_PREFIX + "show_graph"

const val IS_SECOND = BuildConfig.BUILD_TYPE == "second"

Expand Down Expand Up @@ -284,4 +286,16 @@ object Constants {
const val AA_MEDIA_PLAYER_DURATION = "aa_media_player_duration"

const val PATIENT_NAME = "patient_name"

// database
const val DB_MAX_DATA_WEAR_TIME_MS = (24*60*60*1000) // 24h
const val DB_MAX_DATA_TIME_MS = (7*24*60*60*1000) // 7 days
const val SHARED_PREF_RESET_DATABASE = "reset_db"
const val SHARED_PREF_USE_RATE_CALCULATION = "rate_calculation"

// graph
const val GRAPH_ID = "graph_id"
const val SHARED_PREF_GRAPH_DURATION_WEAR_COMPLICATION = "graph_duration_wear_complication"
const val SHARED_PREF_GRAPH_DURATION_PHONE_MAIN = "graph_duration_phone_main"

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package de.michelinside.glucodatahandler.common

import android.annotation.SuppressLint
import android.app.Notification
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
Expand All @@ -11,7 +12,6 @@ import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.annotation.RequiresApi
import com.google.android.gms.wearable.WearableListenerService
import de.michelinside.glucodatahandler.common.notification.ChannelType
import de.michelinside.glucodatahandler.common.notification.Channels
import de.michelinside.glucodatahandler.common.notifier.DataSource
Expand Down Expand Up @@ -44,7 +44,7 @@ enum class AppSource {
AUTO_APP;
}

abstract class GlucoDataService(source: AppSource) : WearableListenerService(), SharedPreferences.OnSharedPreferenceChangeListener {
abstract class GlucoDataService(source: AppSource) : Service(), SharedPreferences.OnSharedPreferenceChangeListener {
protected var batteryReceiver: BatteryReceiver? = null
protected var screenEventReceiver: ScreenEventReceiver? = null
private lateinit var broadcastServiceAPI: BroadcastServiceAPI
Expand All @@ -60,6 +60,7 @@ abstract class GlucoDataService(source: AppSource) : WearableListenerService(),
const val NOTIFICATION_ID = 1234
var appSource = AppSource.NOT_SET
private var isRunning = false
private var started = false
val running get() = isRunning
private var created = false

Expand All @@ -84,31 +85,46 @@ abstract class GlucoDataService(source: AppSource) : WearableListenerService(),
}

fun start(source: AppSource, context: Context, cls: Class<*>) {
Log.v(LOG_ID, "start called (running: $running - foreground: $foreground)")
if (!running) {
Log.v(LOG_ID, "start called (running: $running - foreground: $foreground - started: $started)")
if (!running||!foreground||!started) {
try {
isRunning = true
appSource = source
migrateSettings(context)
val serviceIntent = Intent(
context,
cls
)
/*
val sharedPref = context.getSharedPreferences(
Constants.SHARED_PREF_TAG,
Context.MODE_PRIVATE
)*/
serviceIntent.putExtra(
Constants.SHARED_PREF_FOREGROUND_SERVICE,
// default on wear and phone
true//sharedPref.getBoolean(Constants.SHARED_PREF_FOREGROUND_SERVICE, true)
)
if (foreground) {
context.startService(serviceIntent)
} else {
Log.v(LOG_ID, "start foreground service")
context.startForegroundService(serviceIntent)
if(!started || !running || service == null) {
isRunning = true
appSource = source
migrateSettings(context)
val serviceIntent = Intent(
context,
cls
)
/*
val sharedPref = context.getSharedPreferences(
Constants.SHARED_PREF_TAG,
Context.MODE_PRIVATE
)*/
serviceIntent.putExtra(
Constants.SHARED_PREF_FOREGROUND_SERVICE,
// default on wear and phone
true//sharedPref.getBoolean(Constants.SHARED_PREF_FOREGROUND_SERVICE, true)
)
//if (foreground) {
context.startService(serviceIntent)
/*} else {
Log.v(LOG_ID, "start foreground service")
context.startForegroundService(serviceIntent)
}*/
} else if(!foreground && service != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Log.i(LOG_ID, "Starting service in foreground with type ${ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC}!")
service!!.startForeground(
NOTIFICATION_ID,
service!!.getNotification(),
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
)
} else {
Log.i(LOG_ID, "Starting service in foreground!")
service!!.startForeground(NOTIFICATION_ID, service!!.getNotification())
}
isForegroundService = true
}
} catch (exc: Exception) {
Log.e(
Expand Down Expand Up @@ -168,6 +184,10 @@ abstract class GlucoDataService(source: AppSource) : WearableListenerService(),
}
}

fun getWearPhoneConnection(): WearPhoneConnection? {
return connection
}

private var glucoDataReceiver: GlucoseDataReceiver? = null
private var xDripReceiver: XDripBroadcastReceiver? = null
private var aapsReceiver: AAPSReceiver? = null
Expand All @@ -180,11 +200,7 @@ abstract class GlucoDataService(source: AppSource) : WearableListenerService(),
fun registerReceiver(context: Context, receiver: ReceiverBase, filter: IntentFilter): Boolean {
Log.i(LOG_ID, "Register receiver ${receiver.getName()} for $receiver on $context")
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
context.registerReceiver(receiver, filter, RECEIVER_EXPORTED or RECEIVER_VISIBLE_TO_INSTANT_APPS)
} else {
context.registerReceiver(receiver, filter)
}
PackageUtils.registerReceiver(context, receiver, filter)
registeredReceivers.add(receiver.getName())
return true
} catch (exc: Exception) {
Expand Down Expand Up @@ -429,11 +445,13 @@ abstract class GlucoDataService(source: AppSource) : WearableListenerService(),
@RequiresApi(Build.VERSION_CODES.Q)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
try {
Log.v(LOG_ID, "onStartCommand called")
if(started && isForegroundService)
return START_STICKY
Log.v(LOG_ID, "onStartCommand called - running: $running - foreground: $foreground")
started = true
GdhUncaughtExecptionHandler.init()
super.onStartCommand(intent, flags, startId)
val isForeground = true // intent?.getBooleanExtra(Constants.SHARED_PREF_FOREGROUND_SERVICE, true) --> always use foreground!!!
if (isForeground && !isForegroundService) {
//super.onStartCommand(intent, flags, startId)
if (!isForegroundService) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Log.i(LOG_ID, "Starting service in foreground with type ${ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC}!")
startForeground(
Expand All @@ -446,11 +464,11 @@ abstract class GlucoDataService(source: AppSource) : WearableListenerService(),
startForeground(NOTIFICATION_ID, getNotification())
}
isForegroundService = true
} else if ( isForegroundService && intent?.getBooleanExtra(Constants.ACTION_STOP_FOREGROUND, false) == true ) {
} /*else if ( isForegroundService && intent?.getBooleanExtra(Constants.ACTION_STOP_FOREGROUND, false) == true ) {
isForegroundService = false
Log.i(LOG_ID, "Stopping service in foreground!")
stopForeground(STOP_FOREGROUND_REMOVE)
}
}*/
} catch (exc: Exception) {
Log.e(LOG_ID, "onStartCommand exception: " + exc.toString())
}
Expand Down
Loading