Skip to content

Commit

Permalink
Merge pull request #257 from stadiamaps/feat/android/google-play
Browse files Browse the repository at this point in the history
feat: google play services extensions
  • Loading branch information
ianthetechie authored Sep 18, 2024
2 parents 7494ec1 + 6288bf3 commit fc1b524
Show file tree
Hide file tree
Showing 17 changed files with 232 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ if useLocalFramework {
path: "./common/target/ios/libferrostar-rs.xcframework"
)
} else {
let releaseTag = "0.11.0"
let releaseTag = "0.12.0"
let releaseChecksum = "32a28d66933b6dc7f9b206c79e265767fc51339a9a81f81304c3f15cd7722d19"
binaryTarget = .binaryTarget(
name: "FerrostarCoreRS",
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ plugins {

allprojects {
group = "com.stadiamaps.ferrostar"
version = "0.11.0"
version = "0.12.0"
}
1 change: 1 addition & 0 deletions android/google-play-services/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
67 changes: 67 additions & 0 deletions android/google-play-services/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import com.vanniktech.maven.publish.AndroidMultiVariantLibrary
import com.vanniktech.maven.publish.SonatypeHost

plugins {
alias libs.plugins.androidLibrary
alias libs.plugins.jetbrainsKotlinAndroid
alias libs.plugins.ktfmt
alias libs.plugins.mavenPublish
}

android {
namespace 'com.stadiamaps.ferrostar.googleplayservices'
compileSdk 34

defaultConfig {
minSdk 25

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}

dependencies {
// For as long as we support API 25; once we can raise support to 26, all is fine
coreLibraryDesugaring libs.desugar.jdk.libs

implementation libs.androidx.ktx
implementation libs.androidx.appcompat
implementation libs.material

implementation project(':core')
implementation libs.play.services.location

testImplementation libs.junit
androidTestImplementation libs.androidx.test.junit
androidTestImplementation libs.androidx.test.espresso
}

mavenPublishing {
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
signAllPublications()

configure(new AndroidMultiVariantLibrary(true, true))

apply from: "${rootProject.projectDir}/common-pom.gradle"

pom {
name = "Ferrostar Google Play Services"
description = "Ferrostar components that rely on Google Play Services"
commonPomConfig(it, true)
}
}
Empty file.
21 changes: 21 additions & 0 deletions android/google-play-services/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.stadiamaps.ferrostar.googleplayservices

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.stadiamaps.ferrostar.googleplayservices.test", appContext.packageName)
}
}
4 changes: 4 additions & 0 deletions android/google-play-services/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.stadiamaps.ferrostar.googleplayservices

import android.annotation.SuppressLint
import android.content.Context
import android.os.Looper
import android.util.Log
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationListener
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.stadiamaps.ferrostar.core.LocationProvider
import com.stadiamaps.ferrostar.core.LocationUpdateListener
import com.stadiamaps.ferrostar.core.toUserLocation
import java.util.concurrent.Executor
import uniffi.ferrostar.Heading
import uniffi.ferrostar.UserLocation

class FusedLocationProvider(
context: Context,
private val fusedLocationProviderClient: FusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(context)
) : LocationProvider {

companion object {
private const val TAG = "FusedLocationProvider"
}

override var lastLocation: UserLocation? = null
private set

override var lastHeading: Heading? = null
private set

private val listeners: MutableMap<LocationUpdateListener, LocationListener> = mutableMapOf()

@SuppressLint("MissingPermission")
override fun addListener(listener: LocationUpdateListener, executor: Executor) {
Log.d(TAG, "Adding listener")
if (listeners.contains(listener)) {
Log.d(TAG, "Listener already added")
return
}

val locationListener = LocationListener { newLocation ->
listener.onLocationUpdated(newLocation.toUserLocation())
}
listeners[listener] = locationListener

val locationRequest =
LocationRequest.Builder(1000L).setPriority(Priority.PRIORITY_HIGH_ACCURACY).build()

fusedLocationProviderClient.requestLocationUpdates(
locationRequest, locationListener, Looper.getMainLooper())
}

override fun removeListener(listener: LocationUpdateListener) {
val activeListener = listeners.remove(listener)

if (activeListener != null) {
fusedLocationProviderClient.removeLocationUpdates(activeListener)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.stadiamaps.ferrostar.googleplayservices

import org.junit.Assert.*
import org.junit.Test

/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
5 changes: 5 additions & 0 deletions android/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ compose = "2024.09.01"
okhttp = "4.12.0"
moshi = "1.15.1"
maplibre-compose = "0.1.0"
playServicesLocation = "21.3.0"
junit = "4.13.2"
junitVersion = "1.2.1"
junitCompose = "1.7.1"
espressoCore = "3.6.1"
okhttp-mock = "2.0.0"
mavenPublish = "0.29.0"
material = "1.12.0"

[libraries]
desugar_jdk_libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar_jdk_libs" }
Expand Down Expand Up @@ -53,11 +55,14 @@ moshi = { group = "com.squareup.moshi", name = "moshi", version.ref = "moshi" }
okhttp-mock = { group = "com.github.gmazzo", name = "okhttp-mock", version.ref = "okhttp-mock" }
# MapLibre
maplibre-compose = { group = "io.github.rallista", name = "maplibre-compose", version.ref = "maplibre-compose" }
# Google Play Services (for Google module)
play-services-location = { module = "com.google.android.gms:play-services-location", version.ref = "playServicesLocation" }
# Testing
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-test-espresso = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4", version.ref = "junitCompose" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
Expand Down
1 change: 1 addition & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ include ':core'
include ':composeui'
include ':demo-app'
include ':maplibreui'
include ':google-play-services'
2 changes: 1 addition & 1 deletion common/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion common/ferrostar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ lints.workspace = true

[package]
name = "ferrostar"
version = "0.11.0"
version = "0.12.0"
readme = "README.md"
description = "The core of modern turn-by-turn navigation."
keywords = ["navigation", "routing", "valhalla", "osrm"]
Expand Down
25 changes: 24 additions & 1 deletion guide/src/android-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ dependencies {
implementation "com.stadiamaps.ferrostar:core:${ferrostarVersion}"
implementation "com.stadiamaps.ferrostar:maplibreui:${ferrostarVersion}"
// Optional - if using Google Play Service's FusedLocation
implementation "com.stadiamaps.ferrostar:google-play-services:${ferrostarVersion}"
// okhttp3
implementation platform("com.squareup.okhttp3:okhttp-bom:4.11.0")
implementation 'com.squareup.okhttp3:okhttp'
Expand Down Expand Up @@ -129,7 +132,27 @@ In other cases, get a context using an appropriate method.
locationProvider = AndroidSystemLocationProvider(context = this)
```

#### TODO: Google Play Fused Location Client
#### Google Play Fused Location Client

Alternatively, you can use the `FusedLocationProvider`
if your app uses Google Play Services.
This normally offers better device positioning than the default Android location provider
on supported devices.
To make use of it,
you will need to include the optional `implementation "com.stadiamaps.ferrostar:google-play-services:${ferrostarVersion}"`
in your Gradle dependencies block.

Just as with the `AndroidSystemLocationProvider`,
you probably need to declare it as a `lateinit var` instance variable first,
and then initialize later once the `Context` is available.

```kotlin
// Instance variable definition
private lateinit var locationProvider: FusedLocationProvider

// Later when the activity loads and a context is avaialable
locationProvider = FusedLocationProvider(context = this)
```

#### `SimulatedLocationProvider`

Expand Down
4 changes: 2 additions & 2 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"CatMe0w <[email protected]> (https://github.com/CatMe0w)",
"Luke Seelenbinder <[email protected]>"
],
"version": "0.11.0",
"version": "0.12.0",
"license": "BSD-3-Clause",
"type": "module",
"main": "./dist/ferrostar-webcomponents.js",
Expand Down

0 comments on commit fc1b524

Please sign in to comment.