diff --git a/android-auto-app/build.gradle.kts b/android-auto-app/build.gradle.kts index 206fc48204..b86d49b366 100644 --- a/android-auto-app/build.gradle.kts +++ b/android-auto-app/build.gradle.kts @@ -46,7 +46,10 @@ androidExtensions { dependencies { implementation(project(":extension-androidauto")) implementation(project(":sdk")) - implementation(Dependencies.googleCarAppLibrary) + + // Upgrade the google car library to demonstrate adopting new apis. + implementation("androidx.car.app:app:1.3.0-beta01") + implementation(Dependencies.kotlin) implementation(Dependencies.androidxAppCompat) implementation(Dependencies.androidxCoreKtx) diff --git a/android-auto-app/src/main/AndroidManifest.xml b/android-auto-app/src/main/AndroidManifest.xml index 050e93ee3e..aa12635c96 100644 --- a/android-auto-app/src/main/AndroidManifest.xml +++ b/android-auto-app/src/main/AndroidManifest.xml @@ -35,7 +35,7 @@ tools:ignore="MetadataTagInsideApplicationTag" /> + if (carAppPreferences.isCustomCallbackEnabled() != isChecked) { + Toast.makeText( + this, + "Custom setting changed, reconnect Android Auto to ensure a restart", + Toast.LENGTH_LONG + ).show() + carAppPreferences.enableCustomCallback(isChecked) + } + } } } \ No newline at end of file diff --git a/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/custom/CustomMapSession.kt b/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/custom/CustomMapSession.kt new file mode 100644 index 0000000000..9db0755fd7 --- /dev/null +++ b/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/custom/CustomMapSession.kt @@ -0,0 +1,81 @@ +package com.mapbox.maps.testapp.auto.custom + +import android.Manifest.permission.ACCESS_FINE_LOCATION +import android.content.Intent +import android.content.pm.PackageManager.PERMISSION_GRANTED +import android.content.res.Configuration +import androidx.car.app.AppManager +import androidx.car.app.Screen +import androidx.car.app.ScreenManager +import androidx.car.app.Session +import androidx.car.app.SurfaceCallback +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import com.mapbox.maps.MapInitOptions +import com.mapbox.maps.MapboxExperimental +import com.mapbox.maps.extension.androidauto.MapboxCarMap +import com.mapbox.maps.logI +import com.mapbox.maps.testapp.auto.car.CarAnimationThreadController +import com.mapbox.maps.testapp.auto.car.CarMapShowcase +import com.mapbox.maps.testapp.auto.car.CarMapWidgets +import com.mapbox.maps.testapp.auto.car.MapScreen +import com.mapbox.maps.testapp.auto.car.RequestPermissionScreen + +/** + * This session demonstrates an ability to upgrade the androidx.car.app:app: dependency to a new + * version and use the [SurfaceCallback.onClick] function. + */ +@OptIn(MapboxExperimental::class) +class CustomMapSession : Session() { + + private val carAnimationThreadController = CarAnimationThreadController() + private val carMapWidgets = CarMapWidgets() + private val carMapShowcase = CarMapShowcase() + private val mapboxCarMap = MapboxCarMap() + + init { + lifecycle.addObserver(object : DefaultLifecycleObserver { + override fun onCreate(owner: LifecycleOwner) { + val mapInitOptions = MapInitOptions(carContext) + mapboxCarMap.registerObserver(carAnimationThreadController) + mapboxCarMap.registerObserver(carMapWidgets) + mapboxCarMap.registerObserver(carMapShowcase) + + val surfaceCallback = mapboxCarMap.prepareSurfaceCallback(carContext, mapInitOptions) + carContext.getCarService(AppManager::class.java) + .setSurfaceCallback(object : SurfaceCallbackInterceptor(surfaceCallback) { + override fun onClick(x: Float, y: Float) { + super.onClick(x, y) + onMapSurfaceClick(x, y) + } + }) + } + + override fun onDestroy(owner: LifecycleOwner) { + // This may not be needed, but it will ensure the reference is removed. + carContext.getCarService(AppManager::class.java).setSurfaceCallback(null) + + mapboxCarMap.unregisterObserver(carMapShowcase) + mapboxCarMap.unregisterObserver(carMapWidgets) + mapboxCarMap.unregisterObserver(carAnimationThreadController) + } + }) + } + + override fun onCreateScreen(intent: Intent): Screen { + val mapScreen = MapScreen(mapboxCarMap) + return if (carContext.checkSelfPermission(ACCESS_FINE_LOCATION) != PERMISSION_GRANTED) { + carContext.getCarService(ScreenManager::class.java) + .push(mapScreen) + RequestPermissionScreen(carContext) + } else mapScreen + } + + override fun onCarConfigurationChanged(newConfiguration: Configuration) { + carMapShowcase.loadMapStyle(carContext) + } + + private fun onMapSurfaceClick(x: Float, y: Float) { + logI("CustomMapSession", "onClick $x $y") + } +} \ No newline at end of file diff --git a/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/custom/SurfaceCallbackInterceptor.kt b/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/custom/SurfaceCallbackInterceptor.kt new file mode 100644 index 0000000000..98e7fc8bfa --- /dev/null +++ b/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/custom/SurfaceCallbackInterceptor.kt @@ -0,0 +1,34 @@ +package com.mapbox.maps.testapp.auto.custom + +import android.graphics.Rect +import androidx.car.app.SurfaceCallback +import androidx.car.app.SurfaceContainer + +abstract class SurfaceCallbackInterceptor constructor( + private val surfaceCallback: SurfaceCallback +) : SurfaceCallback { + + override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) = + surfaceCallback.onSurfaceAvailable(surfaceContainer) + + override fun onSurfaceDestroyed(surfaceContainer: SurfaceContainer) = + surfaceCallback.onSurfaceDestroyed(surfaceContainer) + + override fun onVisibleAreaChanged(visibleArea: Rect) = + surfaceCallback.onVisibleAreaChanged(visibleArea) + + override fun onStableAreaChanged(stableArea: Rect) = + surfaceCallback.onStableAreaChanged(stableArea) + + override fun onScale(focusX: Float, focusY: Float, scaleFactor: Float) = + surfaceCallback.onScale(focusX, focusY, scaleFactor) + + override fun onScroll(distanceX: Float, distanceY: Float) = + surfaceCallback.onScroll(distanceX, distanceY) + + override fun onFling(velocityX: Float, velocityY: Float) = + surfaceCallback.onFling(velocityX, velocityY) + + override fun onClick(x: Float, y: Float) = + surfaceCallback.onClick(x, y) +} \ No newline at end of file diff --git a/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/service/CarAppPreferences.kt b/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/service/CarAppPreferences.kt new file mode 100644 index 0000000000..c02110390d --- /dev/null +++ b/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/service/CarAppPreferences.kt @@ -0,0 +1,26 @@ +package com.mapbox.maps.testapp.auto.service + +import android.content.Context + +/** + * Class gives you the ability to modify the demo app shared preferences. + */ +class CarAppPreferences(context: Context) { + + private val sharedPreferences by lazy { + context.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE) + } + + fun enableCustomCallback(enable: Boolean) { + sharedPreferences.edit().putBoolean(BOOLEAN_KEY_ENABLE_CUSTOM_CALLBACK, enable).apply() + } + + fun isCustomCallbackEnabled() = sharedPreferences + .getBoolean(BOOLEAN_KEY_ENABLE_CUSTOM_CALLBACK, false) + + private companion object { + private const val SHARED_PREFERENCES_KEY = "mapbox_maps_android_auto_app" + + private const val BOOLEAN_KEY_ENABLE_CUSTOM_CALLBACK = "enable_custom_callback" + } +} \ No newline at end of file diff --git a/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/service/MapboxCarAppService.kt b/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/service/MapboxCarAppService.kt index 987de0d1c5..de79570816 100644 --- a/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/service/MapboxCarAppService.kt +++ b/android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/service/MapboxCarAppService.kt @@ -4,6 +4,7 @@ import androidx.car.app.CarAppService import androidx.car.app.Session import androidx.car.app.validation.HostValidator import com.mapbox.maps.testapp.auto.car.MapSession +import com.mapbox.maps.testapp.auto.custom.CustomMapSession /** * Entry point for the templated app. @@ -18,6 +19,10 @@ class MapboxCarAppService : CarAppService() { } override fun onCreateSession(): Session { - return MapSession() + return if (CarAppPreferences(this).isCustomCallbackEnabled()) { + CustomMapSession() + } else { + MapSession() + } } } \ No newline at end of file diff --git a/android-auto-app/src/main/res/layout/activity_main.xml b/android-auto-app/src/main/res/layout/activity_main.xml index 14e372440e..fb82985f5d 100644 --- a/android-auto-app/src/main/res/layout/activity_main.xml +++ b/android-auto-app/src/main/res/layout/activity_main.xml @@ -7,13 +7,25 @@ tools:context=".app.MainActivity"> + + \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/Project.kt b/buildSrc/src/main/kotlin/Project.kt index 906be13622..eeb4d23e59 100644 --- a/buildSrc/src/main/kotlin/Project.kt +++ b/buildSrc/src/main/kotlin/Project.kt @@ -5,7 +5,7 @@ object AndroidVersions { object AndroidAuto { const val minSdkVersion = 23 const val targetSdkVersion = 30 - const val compileSdkVersion = 31 + const val compileSdkVersion = 33 } object Compose { const val minSdkVersion = 23 @@ -96,7 +96,7 @@ object Dependencies { object Versions { const val pluginAndroidGradle = "7.0.4" - const val pluginKotlin = "1.5.31" + const val pluginKotlin = "1.7.10" const val pluginLicense = "0.8.80" const val pluginDokka = "1.5.31" const val pluginJacoco = "0.2"