Skip to content

Commit

Permalink
feat: Add background execution, convert Status to Composable (#550)
Browse files Browse the repository at this point in the history
This is a major overhaul of the app internals to support a foreground service (i.e., a notification that shows current GNSS status even when the main Activity UI is not showing).

This involves moving all the API listeners for GNSS events into their own "manager" classes based on Kotlin callbackFlow that exist the entire lifecycle of the app, so the various app components (Fragments, ViewModels, Activity, Service) can all receive updates from this single source.

This bumps minSdkVersion to Android N (24) so we we don't need to deal with the legacy GPS* APIs anymore, which greatly simplifies the data processing within the app.

*  Convert Activity and Fragments to Kotlin
*  Add service with notification
*  Remove legacy GPS* APIs (pre-Android N)
*  Convert all location / GNSS API registrations to data managers based on Kotlin callbackFlow as detailed in https://barbeau.medium.com/kotlin-callbackflow-a-lightweight-architecture-for-location-aware-android-apps-f97b5e66aaa2.
    *  NMEA
    *  Location
    *  GNSS measurement
    *  Antenna
    *  Nav message
    *  Sensor (orientation)
* Add view binding to fragments
* Fix filter bug - it currently shows # signals being filtered, not number satellites (doesn't match # Sats field)
* Move aggregation of signals to satellites into Flow/ViewModel.
* Change Status to Composable - Use LiveData in ViewModel instead - see https://bladecoder.medium.com/kotlins-flow-in-viewmodels-it-s-complicated-556b472e281a that says don't use Flows in ViewModels.

Closes #299
Closes #492
  • Loading branch information
barbeau authored Nov 11, 2021
1 parent 3fec6bf commit 23b482d
Show file tree
Hide file tree
Showing 123 changed files with 9,995 additions and 8,700 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
api-level: [21, 23, 29]
api-level: [24, 29]
target: [default, google_apis]
steps:
- name: checkout
Expand Down
99 changes: 79 additions & 20 deletions GPSTest/build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'

android {
compileSdkVersion 31

defaultConfig {
minSdkVersion 18
minSdkVersion 24
targetSdkVersion 29
multiDexEnabled true
// versionCode scheme - first two digits are minSdkVersion, last three digits are build number
Expand All @@ -17,6 +19,11 @@ android {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildFeatures {
// Enables Jetpack Compose for this module
compose true
}

flavorDimensions "map"

productFlavors {
Expand All @@ -33,10 +40,18 @@ android {
}
}

// http://stackoverflow.com/questions/20673625/gradle-0-7-0-duplicate-files-during-packaging-of-apk
packagingOptions {
// http://stackoverflow.com/questions/20673625/gradle-0-7-0-duplicate-files-during-packaging-of-apk
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
// https://github.com/Kotlin/kotlinx.coroutines/issues/2023
// for JNA and JNA-platform
exclude "META-INF/AL2.0"
exclude "META-INF/LGPL2.1"
// for byte-buddy
exclude "META-INF/licenses/ASM"
pickFirst "win32-x86-64/attach_hotspot_windows.dll"
pickFirst "win32-x86/attach_hotspot_windows.dll"
}

lintOptions {
Expand Down Expand Up @@ -103,6 +118,14 @@ android {
unitTests.includeAndroidResources true
}

composeOptions {
kotlinCompilerExtensionVersion '1.1.0-alpha05'
}

buildFeatures {
viewBinding true
}

// Gradle automatically adds 'android.test.runner' as a dependency.
useLibrary 'android.test.runner'

Expand All @@ -111,14 +134,15 @@ android {
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-rc1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0-beta01"
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation 'androidx.fragment:fragment-ktx:1.3.6'

// Sliding drawer in map view
implementation 'com.sothree.slidinguppanel:library:3.4.0'
Expand All @@ -130,38 +154,73 @@ dependencies {
implementation 'com.google.zxing:android-integration:3.3.0'

// Uploading device properties on user request
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'
implementation 'commons-io:commons-io:2.6'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
implementation 'commons-io:commons-io:2.8.0'

// Share dialog
implementation 'androidx.viewpager2:viewpager2:1.0.0'

// Write GNSS antenna info to JSON
implementation 'com.fasterxml.jackson.core:jackson-core:2.11.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.2'
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.4'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.4'

// Multidex - Needed for APIs < 21
implementation 'androidx.multidex:multidex:2.0.1'

// To observe flows via co-routines within the Service
def lifecycle_version = "2.4.0-rc01"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"

// To use trySend() instead of offer() in callbackFlow (see https://github.com/Kotlin/kotlinx.coroutines/issues/974)
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'

// Hilt for dependency injection
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"

// Map (Google flavor only)
googleImplementation 'com.google.android.gms:play-services-maps:16.1.0'
googleImplementation 'com.google.android.gms:play-services-maps:17.0.1'
// Calculating offset for camera target in map view (Google flavor only)
googleImplementation 'com.google.maps.android:android-maps-utils:0.5'
googleImplementation 'com.google.maps.android:android-maps-utils:2.2.6'
// Use suspend coroutines instead of callbacks (Google flavor only)
implementation 'com.google.maps.android:maps-ktx:3.1.0'
// OSM Droid (fdroid flavor only)
osmdroidImplementation 'org.osmdroid:osmdroid-android:6.1.4'
osmdroidImplementation 'org.osmdroid:osmdroid-android:6.1.11'

//
// Jetpack Compose for UI
//

// Integration with activities
implementation 'androidx.activity:activity-compose:1.3.1'
implementation "androidx.compose.compiler:compiler:1.1.0-alpha06"
// Compose Material Design
implementation 'androidx.compose.material:material:1.0.4'
// Bridging XML themes to Compose
implementation "com.google.android.material:compose-theme-adapter:1.0.4"
// Animations
implementation 'androidx.compose.animation:animation:1.1.0-alpha06'
// Tooling support (Previews, etc.)
implementation 'androidx.compose.ui:ui-tooling:1.0.4'
// Integration with ViewModels
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0-rc01'
//Integration with LiveData
implementation 'androidx.compose.runtime:runtime-livedata:1.1.0-alpha06'
// UI Tests
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.0.4'

//
// Unit tests
//
testImplementation 'junit:junit:4.13.1'
testImplementation 'junit:junit:4.13.2'
// Core library
androidTestImplementation 'androidx.test:core:1.3.0'
androidTestImplementation 'androidx.test:core:1.4.0'

// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test:rules:1.3.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test:rules:1.4.0'

// Assertions
androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
Expand Down
Loading

0 comments on commit 23b482d

Please sign in to comment.