Skip to content

Commit 2f0dc6f

Browse files
committed
Add example for onClick
1 parent d9b9ea7 commit 2f0dc6f

File tree

9 files changed

+179
-8
lines changed

9 files changed

+179
-8
lines changed

android-auto-app/build.gradle.kts

+6-2
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,16 @@ androidExtensions {
4545

4646
dependencies {
4747
implementation(project(":extension-androidauto"))
48-
implementation(Dependencies.googleCarAppLibrary)
49-
48+
5049
// Please review the compatibility guide. This app is showcasing the latest features.
5150
// https://github.com/mapbox/mapbox-maps-android/tree/main/extension-androidauto#compatibility-with-maps-sdk-v10
5251
implementation("com.mapbox.maps:android:10.9.0-beta.2")
5352

53+
// Upgrade the google car library to demonstrate adopting new apis.
54+
// https://developer.android.com/jetpack/androidx/releases/car-app
55+
implementation("androidx.car.app:app:1.3.0-beta01")
56+
// implementation(Dependencies.googleCarAppLibrary)
57+
5458
implementation(Dependencies.kotlin)
5559
implementation(Dependencies.androidxAppCompat)
5660
implementation(Dependencies.androidxCoreKtx)

android-auto-app/src/main/AndroidManifest.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
tools:ignore="MetadataTagInsideApplicationTag" />
3636
<meta-data
3737
android:name="androidx.car.app.minCarApiLevel"
38-
android:value="1"
38+
android:value="5"
3939
tools:ignore="MetadataTagInsideApplicationTag" />
4040

4141
<service
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.mapbox.maps.testapp.auto
2+
3+
import android.content.Context
4+
import android.content.SharedPreferences
5+
6+
/**
7+
* Class gives you the ability to modify preferences that can be used by the car and app.
8+
*/
9+
class CarAppPreferences(context: Context) {
10+
11+
val sharedPreferences: SharedPreferences by lazy {
12+
context.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
13+
}
14+
15+
fun enableOnClick(enable: Boolean) {
16+
sharedPreferences.edit().putBoolean(BOOLEAN_KEY_ENABLE_ON_CLICK, enable).apply()
17+
}
18+
19+
fun isOnClickEnabled() = sharedPreferences
20+
.getBoolean(BOOLEAN_KEY_ENABLE_ON_CLICK, false)
21+
22+
companion object {
23+
private const val SHARED_PREFERENCES_KEY = "mapbox_maps_android_auto_app"
24+
25+
const val BOOLEAN_KEY_ENABLE_ON_CLICK = "enable_onclick"
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
package com.mapbox.maps.testapp.auto.app
22

33
import android.os.Bundle
4+
import android.widget.Toast
45
import androidx.appcompat.app.AppCompatActivity
6+
import androidx.appcompat.widget.SwitchCompat
7+
import com.mapbox.maps.testapp.auto.CarAppPreferences
58
import com.mapbox.maps.testapp.auto.R
69

710
class MainActivity : AppCompatActivity() {
811
override fun onCreate(savedInstanceState: Bundle?) {
912
super.onCreate(savedInstanceState)
1013
setContentView(R.layout.activity_main)
14+
val switchButton: SwitchCompat = findViewById(R.id.switchButton)
15+
16+
val carAppPreferences = CarAppPreferences(applicationContext)
17+
switchButton.isChecked = carAppPreferences.isOnClickEnabled()
18+
switchButton.setOnCheckedChangeListener { _, isChecked ->
19+
if (carAppPreferences.isOnClickEnabled() != isChecked) {
20+
Toast.makeText(
21+
this,
22+
"Custom setting changed, reconnect Android Auto to ensure a restart",
23+
Toast.LENGTH_LONG
24+
).show()
25+
carAppPreferences.enableOnClick(isChecked)
26+
}
27+
}
1128
}
1229
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.mapbox.maps.testapp.auto.car
2+
3+
import android.content.SharedPreferences
4+
import androidx.car.app.AppManager
5+
import androidx.lifecycle.DefaultLifecycleObserver
6+
import androidx.lifecycle.LifecycleOwner
7+
import com.mapbox.maps.MapboxExperimental
8+
import com.mapbox.maps.extension.androidauto.MapboxCarMap
9+
import com.mapbox.maps.extension.androidauto.MapboxCarMapInitializer
10+
import com.mapbox.maps.logI
11+
import com.mapbox.maps.testapp.auto.CarAppPreferences
12+
import com.mapbox.maps.testapp.auto.custom.SurfaceCallbackInterceptor
13+
14+
/**
15+
* In order to enable onClick, you need to override the mapboxCarMap.prepareSurfaceCallback
16+
*
17+
* This class allows you to toggle the preference from the app, to show that you can change this
18+
* setting at runtime. In real scenarios, it may be initialize the map with onClick enabled.
19+
*/
20+
@OptIn(MapboxExperimental::class)
21+
class CarMapOnClickEnabler(
22+
private val mapboxCarMap: MapboxCarMap,
23+
private val initializer: MapboxCarMapInitializer
24+
) : DefaultLifecycleObserver {
25+
26+
private var carAppPreferences: CarAppPreferences? = null
27+
28+
private val listener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
29+
if (key == CarAppPreferences.BOOLEAN_KEY_ENABLE_ON_CLICK) {
30+
val customCallbackEnabled = sharedPreferences.getBoolean(key, false)
31+
onEnableOnClickPreferenceChanged(customCallbackEnabled)
32+
}
33+
}
34+
35+
override fun onResume(owner: LifecycleOwner) {
36+
super.onResume(owner)
37+
carAppPreferences = CarAppPreferences(mapboxCarMap.carContext).apply {
38+
sharedPreferences.registerOnSharedPreferenceChangeListener(listener)
39+
onEnableOnClickPreferenceChanged(isOnClickEnabled())
40+
}
41+
}
42+
43+
override fun onPause(owner: LifecycleOwner) {
44+
super.onPause(owner)
45+
carAppPreferences?.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(listener)
46+
carAppPreferences = null
47+
}
48+
49+
private fun onEnableOnClickPreferenceChanged(customCallbackEnabled: Boolean) {
50+
val carContext = mapboxCarMap.carContext
51+
if (customCallbackEnabled) {
52+
val surfaceCallback = mapboxCarMap.prepareSurfaceCallback(
53+
carContext, initializer.onCreate(carContext)
54+
)
55+
carContext.getCarService(AppManager::class.java)
56+
.setSurfaceCallback(object : SurfaceCallbackInterceptor(surfaceCallback) {
57+
override fun onClick(x: Float, y: Float) {
58+
super.onClick(x, y)
59+
onMapSurfaceClick(x, y)
60+
}
61+
})
62+
} else {
63+
mapboxCarMap.setup(carContext, initializer.onCreate(carContext))
64+
}
65+
}
66+
67+
private fun onMapSurfaceClick(x: Float, y: Float) {
68+
logI("CarMapOnClickEnabler", "onMapSurfaceClick $x $y")
69+
}
70+
}

android-auto-app/src/main/java/com/mapbox/maps/testapp/auto/car/MapSession.kt

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.car.app.ScreenManager
99
import androidx.car.app.Session
1010
import com.mapbox.maps.MapInitOptions
1111
import com.mapbox.maps.MapboxExperimental
12+
import com.mapbox.maps.extension.androidauto.MapboxCarMapInitializer
1213
import com.mapbox.maps.extension.androidauto.mapboxMapInstaller
1314

1415
/**
@@ -18,14 +19,20 @@ import com.mapbox.maps.extension.androidauto.mapboxMapInstaller
1819
class MapSession : Session() {
1920

2021
private val carMapShowcase = CarMapShowcase()
22+
private val initializer = MapboxCarMapInitializer { carContext -> MapInitOptions(carContext) }
2123
private val mapboxCarMap = mapboxMapInstaller()
22-
.onCreated(CarAnimationThreadController(), CarMapWidgets(), carMapShowcase)
24+
.onCreated(CarAnimationThreadController(), CarMapWidgets(), carMapShowcase,)
2325
.install { carContext ->
2426
// Callback is triggered when the Session calls onCreate. This allows you to specify
2527
// custom MapInitOptions.
26-
MapInitOptions(carContext)
28+
initializer.onCreate(carContext)
2729
}
2830

31+
init {
32+
// Override the SurfaceCallback to capture onClick events
33+
lifecycle.addObserver(CarMapOnClickEnabler(mapboxCarMap, initializer))
34+
}
35+
2936
override fun onCreateScreen(intent: Intent): Screen {
3037
// The onCreate is guaranteed to be called before onCreateScreen. You can pass the
3138
// mapboxCarMap to other screens. Each screen can register and unregister observers.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.mapbox.maps.testapp.auto.custom
2+
3+
import android.graphics.Rect
4+
import androidx.car.app.SurfaceCallback
5+
import androidx.car.app.SurfaceContainer
6+
7+
abstract class SurfaceCallbackInterceptor constructor(
8+
private val surfaceCallback: SurfaceCallback
9+
) : SurfaceCallback {
10+
11+
override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) =
12+
surfaceCallback.onSurfaceAvailable(surfaceContainer)
13+
14+
override fun onSurfaceDestroyed(surfaceContainer: SurfaceContainer) =
15+
surfaceCallback.onSurfaceDestroyed(surfaceContainer)
16+
17+
override fun onVisibleAreaChanged(visibleArea: Rect) =
18+
surfaceCallback.onVisibleAreaChanged(visibleArea)
19+
20+
override fun onStableAreaChanged(stableArea: Rect) =
21+
surfaceCallback.onStableAreaChanged(stableArea)
22+
23+
override fun onScale(focusX: Float, focusY: Float, scaleFactor: Float) =
24+
surfaceCallback.onScale(focusX, focusY, scaleFactor)
25+
26+
override fun onScroll(distanceX: Float, distanceY: Float) =
27+
surfaceCallback.onScroll(distanceX, distanceY)
28+
29+
override fun onFling(velocityX: Float, velocityY: Float) =
30+
surfaceCallback.onFling(velocityX, velocityY)
31+
32+
override fun onClick(x: Float, y: Float) =
33+
surfaceCallback.onClick(x, y)
34+
}

android-auto-app/src/main/res/layout/activity_main.xml

+13-1
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,25 @@
77
tools:context=".app.MainActivity">
88

99
<TextView
10+
android:id="@+id/textView"
1011
android:layout_width="wrap_content"
1112
android:layout_height="wrap_content"
13+
android:text="Android Auto testing activity"
1214
app:layout_constraintBottom_toBottomOf="parent"
1315
app:layout_constraintEnd_toEndOf="parent"
1416
app:layout_constraintStart_toStartOf="parent"
1517
app:layout_constraintTop_toTopOf="parent"
16-
android:text="Android Auto testing activity"
1718
tools:ignore="HardcodedText" />
1819

20+
<androidx.appcompat.widget.SwitchCompat
21+
android:id="@+id/switchButton"
22+
android:layout_width="wrap_content"
23+
android:layout_height="wrap_content"
24+
android:text="Enable onClick"
25+
app:layout_constraintBottom_toBottomOf="parent"
26+
app:layout_constraintEnd_toEndOf="parent"
27+
app:layout_constraintStart_toStartOf="parent"
28+
app:layout_constraintTop_toBottomOf="@+id/textView"
29+
tools:ignore="HardcodedText"/>
30+
1931
</androidx.constraintlayout.widget.ConstraintLayout>

buildSrc/src/main/kotlin/Project.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ object AndroidVersions {
55
object AndroidAuto {
66
const val minSdkVersion = 23
77
const val targetSdkVersion = 30
8-
const val compileSdkVersion = 31
8+
const val compileSdkVersion = 33
99
}
1010
object Compose {
1111
const val minSdkVersion = 23
@@ -98,7 +98,7 @@ object Dependencies {
9898

9999
object Versions {
100100
const val pluginAndroidGradle = "7.0.4"
101-
const val pluginKotlin = "1.5.31"
101+
const val pluginKotlin = "1.7.10"
102102
const val pluginLicense = "0.8.80"
103103
const val pluginDokka = "1.5.31"
104104
const val pluginJacoco = "0.2"

0 commit comments

Comments
 (0)