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

Develop #137

Merged
merged 32 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0226803
Fix GlucoDataAuto standalone
pachi81 Feb 22, 2024
dd5ca1d
Fix AAPS unit handling
pachi81 Feb 22, 2024
122fb2e
Fix AAPS sensor name
pachi81 Feb 22, 2024
57e59db
Remove IOB/COB after a day...
pachi81 Feb 22, 2024
f0b60b6
WatchDrip+ support
pachi81 Feb 23, 2024
6b3de09
Fix delta for watchdrip
pachi81 Feb 24, 2024
c620ed2
Floating widget exception handling
pachi81 Feb 26, 2024
2a180ac
GDA state broadcast
pachi81 Feb 26, 2024
5eb3779
Fix GDA time task
pachi81 Feb 26, 2024
89f84d8
Refactor/fix AA connection handling
pachi81 Feb 28, 2024
2c03bb8
GDA Foreground service while AA connected
pachi81 Feb 28, 2024
8c64e3e
Foreground service while connected
pachi81 Feb 28, 2024
75ea450
Update strings
pachi81 Feb 28, 2024
d99de78
Update strings.xml PL - Watchdrip+
froster82 Feb 29, 2024
0a8579e
AA communication improved
pachi81 Feb 29, 2024
fa6e1df
Update strings pl
pachi81 Feb 29, 2024
f78a138
Reappear interval setting for AA notification
pachi81 Mar 5, 2024
edca2db
Change icon for AA media player
pachi81 Mar 5, 2024
c36d998
Update strings.xml PL
froster82 Mar 6, 2024
b742f37
Saving logs
pachi81 Mar 6, 2024
5d38a7c
Mew ps images
pachi81 Mar 8, 2024
fd019da
Mew AA version
pachi81 Mar 8, 2024
21ab861
Logs from wear
pachi81 Mar 8, 2024
f168b29
Schedule exact alarm permission
pachi81 Mar 10, 2024
f5de31c
add dependenciesInfo
pachi81 Mar 10, 2024
3959725
Update strings.xml
pachi81 Mar 11, 2024
f51222b
Update strings_pl.xml
pachi81 Mar 11, 2024
f283a83
Update strings_de.xml
pachi81 Mar 11, 2024
93329d9
Update strings.xml PL
froster82 Mar 11, 2024
db8435c
New version 24
pachi81 Mar 11, 2024
c8a7f02
Update strings.xml rephrased Polish version
froster82 Mar 12, 2024
883d970
New version 25
pachi81 Mar 12, 2024
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 auto/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ dependencies {
implementation "androidx.preference:preference:1.2.1"
implementation "com.jaredrummler:colorpicker:1.1.0"
implementation "androidx.media:media:1.7.0"
implementation 'androidx.work:work-runtime:2.9.0'
}

afterEvaluate {
Expand Down
22 changes: 22 additions & 0 deletions auto/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>


<queries>
Expand Down Expand Up @@ -54,6 +56,17 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>


<service android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
tools:node="merge" />
<service
android:name=".GlucoDataServiceAuto"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="dataSync"/>

<receiver
android:name=".receiver.GlucoDataActionReceiver"
android:enabled="true"
Expand Down Expand Up @@ -81,6 +94,15 @@
<action android:name="com.eveningoutpost.dexdrip.BgEstimate" />
</intent-filter>
</receiver>
<receiver
android:name=".receiver.AAPSReceiver"
android:enabled="true"
android:exported="true"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="info.nightscout.androidaps.status" />
</intent-filter>
</receiver>
<receiver android:name="de.michelinside.glucodatahandler.common.tasks.TimeAlarmReceiver" />

<service
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package de.michelinside.glucodataauto

import android.app.Notification
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.car.app.connection.CarConnection
import de.michelinside.glucodataauto.android_auto.CarMediaBrowserService
import de.michelinside.glucodataauto.android_auto.CarNotification
import de.michelinside.glucodatahandler.common.Constants
import de.michelinside.glucodatahandler.common.GlucoDataService
import de.michelinside.glucodatahandler.common.ReceiveData
import de.michelinside.glucodatahandler.common.notification.ChannelType
import de.michelinside.glucodatahandler.common.notification.Channels
import de.michelinside.glucodatahandler.common.notifier.InternalNotifier
import de.michelinside.glucodatahandler.common.notifier.NotifySource
import de.michelinside.glucodatahandler.common.tasks.BackgroundWorker
import de.michelinside.glucodatahandler.common.tasks.TimeTaskService
import de.michelinside.glucodatahandler.common.utils.Utils

class GlucoDataServiceAuto: Service() {
companion object {
private const val LOG_ID = "GDH.AA.GlucoDataServiceAuto"
private var isForegroundService = false
const val NOTIFICATION_ID = 666
private var car_connected = false
private var running = false
private var init = false
val connected: Boolean get() = car_connected || CarMediaBrowserService.active
fun init(context: Context) {
if(!init) {
Log.v(LOG_ID, "init called")
GlucoDataService.context = context
TimeTaskService.useWorker = true
ReceiveData.initData(context)
CarConnection(context.applicationContext).type.observeForever(GlucoDataServiceAuto::onConnectionStateUpdated)
init = true
}
}

private fun setForeground(context: Context, foreground: Boolean) {
try {
Log.v(LOG_ID, "setForeground called " + foreground)
if (isForegroundService != foreground) {
val serviceIntent = Intent(context, GlucoDataServiceAuto::class.java)
serviceIntent.putExtra(Constants.SHARED_PREF_FOREGROUND_SERVICE, foreground)
if (foreground)
context.startForegroundService(serviceIntent)
else
context.startService(serviceIntent)
}
} catch (exc: Exception) {
Log.e(LOG_ID, "setForeground exception: " + exc.toString())
}
}

fun start(context: Context) {
try {
if(!running) {
Log.i(LOG_ID, "starting")
CarNotification.enable(context)
TimeTaskService.run(context)
sendStateBroadcast(context, true)
setForeground(context, true)
running = true
}
} catch (exc: Exception) {
Log.e(LOG_ID, "start exception: " + exc.toString())
}
}

fun stop(context: Context) {
try {
if(!connected && running) {
Log.i(LOG_ID, "stopping")
CarNotification.disable(context)
sendStateBroadcast(context, false)
BackgroundWorker.stopAllWork(context)
setForeground(context, false)
running = false
}
} catch (exc: Exception) {
Log.e(LOG_ID, "stop exception: " + exc.toString())
}
}

fun onConnectionStateUpdated(connectionState: Int) {
try {
val message = when(connectionState) {
CarConnection.CONNECTION_TYPE_NOT_CONNECTED -> "Not connected to a head unit"
CarConnection.CONNECTION_TYPE_NATIVE -> "Connected to Android Automotive OS"
CarConnection.CONNECTION_TYPE_PROJECTION -> "Connected to Android Auto"
else -> "Unknown car connection type"
}
Log.v(LOG_ID, "onConnectionStateUpdated: " + message + " (" + connectionState.toString() + ")")
if (init) {
if (connectionState == CarConnection.CONNECTION_TYPE_NOT_CONNECTED) {
if(car_connected) {
Log.i(LOG_ID, "Exited Car Mode")
car_connected = false
stop(GlucoDataService.context!!)
}
} else {
if(!car_connected) {
Log.i(LOG_ID, "Entered Car Mode")
car_connected = true
start(GlucoDataService.context!!)
}
}
InternalNotifier.notify(GlucoDataService.context!!, NotifySource.CAR_CONNECTION, null)
}
} catch (exc: Exception) {
Log.e(LOG_ID, "onConnectionStateUpdated exception: " + exc.message.toString() + "\n" + exc.stackTraceToString() )
}
}

private fun sendStateBroadcast(context: Context, enabled: Boolean) {
try {
Log.d(LOG_ID, "Sending state broadcast for state: " + enabled)
val intent = Intent(Constants.GLUCODATAAUTO_STATE_ACTION)
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
intent.putExtra(Constants.GLUCODATAAUTO_STATE_EXTRA, enabled)
context.sendBroadcast(intent)
} catch (exc: Exception) {
Log.e(LOG_ID, "sendStateBroadcast exception: " + exc.toString())
}
}
}

@RequiresApi(Build.VERSION_CODES.Q)
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
try {
Log.d(LOG_ID, "onStartCommand called")
super.onStartCommand(intent, flags, startId)
val isForeground = intent.getBooleanExtra(Constants.SHARED_PREF_FOREGROUND_SERVICE, false)
if (isForeground && !isForegroundService && Utils.checkPermission(this, android.Manifest.permission.POST_NOTIFICATIONS, Build.VERSION_CODES.TIRAMISU)) {
Log.i(LOG_ID, "Starting service in foreground!")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
startForeground(NOTIFICATION_ID, getNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
else
startForeground(NOTIFICATION_ID, getNotification())
isForegroundService = true
} else if ( isForegroundService && !isForeground ) {
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())
}
if (isForegroundService)
return START_STICKY // keep alive
return START_NOT_STICKY
}

override fun onDestroy() {
Log.v(LOG_ID, "onDestroy called")
super.onDestroy()
}

override fun onBind(intent: Intent?): IBinder? {
Log.v(LOG_ID, "onBind called with intent " + intent)
return null
}

private fun getNotification(): Notification {
Channels.createNotificationChannel(this, ChannelType.ANDROID_AUTO_FOREGROUND)

val pendingIntent = Utils.getAppIntent(this, MainActivity::class.java, 11, false)

return Notification.Builder(this, ChannelType.ANDROID_AUTO_FOREGROUND.channelId)
.setContentTitle(getString(de.michelinside.glucodatahandler.common.R.string.activity_main_car_connected_label))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.setOngoing(true)
.setOnlyAlertOnce(true)
.setAutoCancel(false)
.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.build()
}

}
11 changes: 2 additions & 9 deletions auto/src/main/java/de/michelinside/glucodataauto/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuCompat
import androidx.preference.PreferenceManager
import de.michelinside.glucodataauto.android_auto.CarNotification
import de.michelinside.glucodatahandler.common.Constants
import de.michelinside.glucodatahandler.common.ReceiveData
import de.michelinside.glucodatahandler.common.notifier.InternalNotifier
Expand Down Expand Up @@ -81,19 +80,13 @@ class MainActivity : AppCompatActivity(), NotifierInterface {
apply()
}
}
CarNotification.initNotification(this)
GlucoDataServiceAuto.init(this)
requestPermission()
} catch (exc: Exception) {
Log.e(LOG_ID, "onCreate exception: " + exc.message.toString() )
}
}

override fun onDestroy() {
super.onDestroy()
if (!CarNotification.connected)
CarNotification.cleanupNotification(this)
}

override fun onPause() {
try {
super.onPause()
Expand Down Expand Up @@ -234,7 +227,7 @@ class MainActivity : AppCompatActivity(), NotifierInterface {
}
viewIcon.setImageIcon(BitmapUtils.getRateAsIcon())
txtLastValue.text = ReceiveData.getAsString(this, CR.string.gda_no_data)
txtCarInfo.text = if (CarNotification.connected) resources.getText(CR.string.activity_main_car_connected_label) else resources.getText(CR.string.activity_main_car_disconnected_label)
txtCarInfo.text = if (GlucoDataServiceAuto.connected) resources.getText(CR.string.activity_main_car_connected_label) else resources.getText(CR.string.activity_main_car_disconnected_label)
} catch (exc: Exception) {
Log.e(LOG_ID, "update exception: " + exc.message.toString() )
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import android.util.Log
import androidx.media.MediaBrowserServiceCompat
import de.michelinside.glucodataauto.GlucoDataServiceAuto
import de.michelinside.glucodatahandler.common.Constants
import de.michelinside.glucodatahandler.common.ReceiveData
import de.michelinside.glucodatahandler.common.utils.BitmapUtils
import de.michelinside.glucodatahandler.common.notifier.InternalNotifier
import de.michelinside.glucodatahandler.common.notifier.NotifierInterface
import de.michelinside.glucodatahandler.common.notifier.NotifySource
import de.michelinside.glucodatahandler.common.tasks.BackgroundWorker
import de.michelinside.glucodatahandler.common.tasks.TimeTaskService

class CarMediaBrowserService: MediaBrowserServiceCompat(), NotifierInterface, SharedPreferences.OnSharedPreferenceChangeListener {
private val LOG_ID = "GDH.AA.CarMediaBrowserService"
Expand All @@ -29,13 +28,17 @@ class CarMediaBrowserService: MediaBrowserServiceCompat(), NotifierInterface, Sh
private lateinit var sharedPref: SharedPreferences
private lateinit var session: MediaSessionCompat

companion object {
var active = false
}

override fun onCreate() {
Log.v(LOG_ID, "onCreate")
try {
super.onCreate()
TimeTaskService.useWorker = true
CarNotification.initNotification(this)
ReceiveData.initData(this)
active = true
GlucoDataServiceAuto.init(this)
GlucoDataServiceAuto.start(this)
sharedPref = this.getSharedPreferences(Constants.SHARED_PREF_TAG, Context.MODE_PRIVATE)
sharedPref.registerOnSharedPreferenceChangeListener(this)

Expand Down Expand Up @@ -69,11 +72,11 @@ class CarMediaBrowserService: MediaBrowserServiceCompat(), NotifierInterface, Sh
override fun onDestroy() {
Log.v(LOG_ID, "onDestroy")
try {
active = false
InternalNotifier.remNotifier(this, this)
sharedPref.unregisterOnSharedPreferenceChangeListener(this)
session.release()
CarNotification.cleanupNotification(this)
BackgroundWorker.stopAllWork(this)
GlucoDataServiceAuto.stop(this)
super.onDestroy()
} catch (exc: Exception) {
Log.e(LOG_ID, "onDestroy exception: " + exc.message.toString() )
Expand Down Expand Up @@ -139,6 +142,7 @@ class CarMediaBrowserService: MediaBrowserServiceCompat(), NotifierInterface, Sh
}

private fun createMediaItem(): MediaBrowserCompat.MediaItem {
Log.v(LOG_ID, "createMediaItem called")
if (sharedPref.getBoolean(Constants.SHARED_PREF_CAR_MEDIA,true)) {
session.setPlaybackState(buildState(PlaybackState.STATE_PAUSED))
session.setMetadata(
Expand Down Expand Up @@ -167,6 +171,7 @@ class CarMediaBrowserService: MediaBrowserServiceCompat(), NotifierInterface, Sh
}

private fun buildState(state: Int): PlaybackStateCompat? {
Log.v(LOG_ID, "buildState called for state " + state)
return PlaybackStateCompat.Builder()
.setState(
state,
Expand Down
Loading