Skip to content

Commit

Permalink
Merge pull request #137 from pachi81/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
pachi81 committed Mar 12, 2024
2 parents fe5f58b + 883d970 commit 6382dcc
Show file tree
Hide file tree
Showing 48 changed files with 1,673 additions and 292 deletions.
12 changes: 9 additions & 3 deletions auto/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "de.michelinside.glucodataauto"
minSdk rootProject.minSdk
targetSdk rootProject.targetSdk
versionCode 1000 + rootProject.versionCode
versionName rootProject.versionName
versionCode 1022
versionName "0.9.9.7"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand All @@ -29,7 +29,6 @@ android {
resValue "string", "app_name", "GlucoDataAuto"
}
debug {
applicationIdSuffix '.debug'
minifyEnabled false
resValue "string", "app_name", "GlucoDataAuto Debug"
}
Expand Down Expand Up @@ -59,6 +58,12 @@ android {
buildFeatures {
viewBinding true
}
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
}

dependencies {
Expand All @@ -72,6 +77,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,213 @@
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
private var dataSyncCount = 0
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)
startDataSync(context)
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)
stopDataSync(context)
setForeground(context, false)
running = false
}
} catch (exc: Exception) {
Log.e(LOG_ID, "stop exception: " + exc.toString())
}
}

fun startDataSync(context: Context) {
try {
if (dataSyncCount == 0) {
Log.d(LOG_ID, "startDataSync")
TimeTaskService.run(context)
sendStateBroadcast(context, true)
}
dataSyncCount++
} catch (exc: Exception) {
Log.e(LOG_ID, "startDataSync exception: " + exc.toString())
}
}

fun stopDataSync(context: Context) {
try {
dataSyncCount--
if (dataSyncCount == 0) {
Log.d(LOG_ID, "stopDataSync")
sendStateBroadcast(context, false)
BackgroundWorker.stopAllWork(context)
}
} catch (exc: Exception) {
Log.e(LOG_ID, "stopDataSync exception: " + exc.toString())
}
}

private 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()
}

}
Loading

0 comments on commit 6382dcc

Please sign in to comment.