From de68dfc1214b50cf035d09476ef14bc6aaa94135 Mon Sep 17 00:00:00 2001 From: "v.lazin" Date: Wed, 25 Sep 2024 18:36:30 +0600 Subject: [PATCH] SDK 12.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [SDK-#] В пример Android Auto добавлен CustomRenderer для демонстрации отрисовки поверх карты --- .../ru/dgis/sdk/demo/car/CustomRenderer.kt | 77 +++++++++++++++++++ .../java/ru/dgis/sdk/demo/car/MainScreen.kt | 33 ++++++++ .../ru/dgis/sdk/demo/car/MainScreenModel.kt | 25 ++++++ .../java/ru/dgis/sdk/demo/car/MapService.kt | 17 +++- .../java/ru/dgis/sdk/demo/car/MapSession.kt | 49 +++++++++--- app/src/main/res/drawable/ic_zoom_in.xml | 10 +++ app/src/main/res/drawable/ic_zoom_out.xml | 10 +++ gradle/libs.versions.toml | 2 +- 8 files changed, 210 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/ru/dgis/sdk/demo/car/CustomRenderer.kt create mode 100644 app/src/main/java/ru/dgis/sdk/demo/car/MainScreenModel.kt create mode 100644 app/src/main/res/drawable/ic_zoom_in.xml create mode 100644 app/src/main/res/drawable/ic_zoom_out.xml diff --git a/app/src/main/java/ru/dgis/sdk/demo/car/CustomRenderer.kt b/app/src/main/java/ru/dgis/sdk/demo/car/CustomRenderer.kt new file mode 100644 index 0000000..2c60be3 --- /dev/null +++ b/app/src/main/java/ru/dgis/sdk/demo/car/CustomRenderer.kt @@ -0,0 +1,77 @@ +package ru.dgis.sdk.demo.car + +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.os.Build +import android.view.Surface +import androidx.annotation.RequiresApi + +class CustomRenderer { + private var renderThread: RenderThread? = null + + fun start(surface: Surface) { + renderThread = RenderThread(surface) + renderThread?.start() + } + + fun stop() { + renderThread?.interrupt() + renderThread?.join() + renderThread = null + } + + private class RenderThread(private val surface: Surface) : Thread() { + private val renderIntervalMs = 1000L + + @RequiresApi(Build.VERSION_CODES.M) + override fun run() { + var value = 0 + + while (!isInterrupted) { + var canvas: Canvas? = null + try { + canvas = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + surface.lockHardwareCanvas() + } else { + surface.lockCanvas(null) + } + draw(value++, canvas) + } catch (e: Exception) { + e.printStackTrace() + } finally { + if (canvas != null) { + surface.unlockCanvasAndPost(canvas) + } + } + + try { + sleep(renderIntervalMs) + } catch (e: InterruptedException) { + break + } + } + } + + private fun draw(value: Int, canvas: Canvas) { + val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { + color = Color.BLACK + style = Paint.Style.FILL + } + + // Draw a black circle + val centerX = 100f + val centerY = 100f + val radius = 50f + canvas.drawCircle(centerX, centerY, radius, paint) + + // Draw the white text inside the circle + paint.apply { + color = Color.WHITE + textSize = 30f + textAlign = Paint.Align.CENTER + } + canvas.drawText("$value", centerX, centerY + paint.textSize / 3, paint) + } + } +} diff --git a/app/src/main/java/ru/dgis/sdk/demo/car/MainScreen.kt b/app/src/main/java/ru/dgis/sdk/demo/car/MainScreen.kt index 9f6e02c..efc256a 100644 --- a/app/src/main/java/ru/dgis/sdk/demo/car/MainScreen.kt +++ b/app/src/main/java/ru/dgis/sdk/demo/car/MainScreen.kt @@ -1,14 +1,44 @@ package ru.dgis.sdk.demo.car +import androidx.annotation.DrawableRes import androidx.car.app.CarContext import androidx.car.app.Screen import androidx.car.app.model.Action import androidx.car.app.model.ActionStrip +import androidx.car.app.model.CarIcon import androidx.car.app.model.Template import androidx.car.app.navigation.model.NavigationTemplate +import androidx.core.graphics.drawable.IconCompat +import ru.dgis.sdk.demo.R +import ru.dgis.sdk.map.Map class MainScreen(carContext: CarContext) : Screen(carContext) { + private var model: MainScreenModel? = null + + private fun buildCarIcon(@DrawableRes id: Int): CarIcon { + return CarIcon.Builder(IconCompat.createWithResource(carContext, id)).build() + } + + fun setMap(map: Map) { + model = MainScreenModel(map) + } + override fun onGetTemplate(): Template { + val zoomInAction = Action.Builder() + .setIcon(buildCarIcon(R.drawable.ic_zoom_in)) + .setOnClickListener { model?.zoomIn() } + .build() + + val zoomOutAction = Action.Builder() + .setIcon(buildCarIcon(R.drawable.ic_zoom_out)) + .setOnClickListener { model?.zoomOut() } + .build() + + val myLocationAction = Action.Builder() + .setIcon(buildCarIcon(R.drawable.ic_nav_point)) + .setOnClickListener { model?.recenter() } + .build() + return NavigationTemplate.Builder() .setActionStrip( ActionStrip.Builder() @@ -18,6 +48,9 @@ class MainScreen(carContext: CarContext) : Screen(carContext) { .setMapActionStrip( ActionStrip.Builder() .addAction(Action.PAN) + .addAction(zoomInAction) + .addAction(zoomOutAction) + .addAction(myLocationAction) .build() ) .build() diff --git a/app/src/main/java/ru/dgis/sdk/demo/car/MainScreenModel.kt b/app/src/main/java/ru/dgis/sdk/demo/car/MainScreenModel.kt new file mode 100644 index 0000000..e5b43f4 --- /dev/null +++ b/app/src/main/java/ru/dgis/sdk/demo/car/MainScreenModel.kt @@ -0,0 +1,25 @@ +package ru.dgis.sdk.demo.car + +import ru.dgis.sdk.map.CameraBehaviour +import ru.dgis.sdk.map.FollowPosition +import ru.dgis.sdk.map.Map +import ru.dgis.sdk.map.ZoomControlButton +import ru.dgis.sdk.map.ZoomControlModel + +class MainScreenModel(private val map: Map) { + private val zoomControlModel = ZoomControlModel(map) + + fun zoomIn() { + zoomControlModel.setPressed(ZoomControlButton.ZOOM_IN, true) + zoomControlModel.setPressed(ZoomControlButton.ZOOM_IN, false) + } + + fun zoomOut() { + zoomControlModel.setPressed(ZoomControlButton.ZOOM_OUT, true) + zoomControlModel.setPressed(ZoomControlButton.ZOOM_OUT, false) + } + + fun recenter() { + map.camera.setBehaviour(CameraBehaviour(position = FollowPosition())) + } +} diff --git a/app/src/main/java/ru/dgis/sdk/demo/car/MapService.kt b/app/src/main/java/ru/dgis/sdk/demo/car/MapService.kt index 9c0d4c8..6be58e8 100644 --- a/app/src/main/java/ru/dgis/sdk/demo/car/MapService.kt +++ b/app/src/main/java/ru/dgis/sdk/demo/car/MapService.kt @@ -3,8 +3,23 @@ package ru.dgis.sdk.demo.car import androidx.car.app.CarAppService import androidx.car.app.Session import androidx.car.app.validation.HostValidator +import ru.dgis.sdk.DGis +import ru.dgis.sdk.map.DgisSource.Companion.createDgisSource +import ru.dgis.sdk.map.DgisSourceWorkingMode +import ru.dgis.sdk.map.MapOptions +import ru.dgis.sdk.map.MyLocationMapObjectSource class MapService : CarAppService() { + + private fun createMapOptions(): MapOptions { + return MapOptions().apply { + sources = listOf( + createDgisSource(DGis.context(), DgisSourceWorkingMode.HYBRID_ONLINE_FIRST), + MyLocationMapObjectSource(DGis.context()) + ) + } + } + override fun createHostValidator(): HostValidator { // Avoid using ALLOW_ALL_HOSTS_VALIDATOR in production as it is insecure. // Refer to the Android Auto documentation for proper security practices. @@ -18,6 +33,6 @@ class MapService : CarAppService() { // only when certain activity/fragment/etc opened, and it is not created in Application's onCreate, // ru.dgis.sdk.Context should be created here in onCreateSession or somewhere earlier. override fun onCreateSession(): Session { - return MapSession() + return MapSession(createMapOptions()) } } diff --git a/app/src/main/java/ru/dgis/sdk/demo/car/MapSession.kt b/app/src/main/java/ru/dgis/sdk/demo/car/MapSession.kt index ec9c190..5b4c65e 100644 --- a/app/src/main/java/ru/dgis/sdk/demo/car/MapSession.kt +++ b/app/src/main/java/ru/dgis/sdk/demo/car/MapSession.kt @@ -1,38 +1,65 @@ package ru.dgis.sdk.demo.car import android.content.Intent +import android.view.Gravity +import android.view.Surface import androidx.car.app.AppManager import androidx.car.app.CarToast import androidx.car.app.Screen +import ru.dgis.sdk.Future import ru.dgis.sdk.androidauto.AndroidAutoMapSession +import ru.dgis.sdk.androidauto.CopyrightMargins +import ru.dgis.sdk.androidauto.CopyrightPosition import ru.dgis.sdk.map.Map import ru.dgis.sdk.map.MapOptions +import ru.dgis.sdk.map.RenderedObjectInfo import ru.dgis.sdk.map.ScreenPoint -class MapSession : AndroidAutoMapSession(MapOptions()) { +class MapSession(mapOptions: MapOptions) : AndroidAutoMapSession(mapOptions) { + private val mainScreen = MainScreen(carContext) private var map: Map? = null + private var customRenderer = CustomRenderer() + private var getRenderedObjectFuture: Future>? = null private fun showToast(message: String) { - carContext.getCarService(AppManager::class.java) - .showToast(message, CarToast.LENGTH_SHORT) + carContext.getCarService(AppManager::class.java).showToast(message, CarToast.LENGTH_SHORT) } override fun onCreateScreen(intent: Intent): Screen { - return MainScreen(carContext) + return mainScreen + } + + override fun onSurfaceAvailable(surface: Surface, width: Int, height: Int) { + customRenderer.start(surface) + } + + override fun onSurfaceClicked(x: Float, y: Float) { + getRenderedObjectFuture = map?.getRenderedObjects(centerPoint = ScreenPoint(x = x, y = y))?.apply { + onResult { + val objectInfo = it.firstOrNull() + showToast("$objectInfo") + } + } + } + + override fun onSurfaceDestroyed(surface: Surface) { + customRenderer.stop() } override fun onMapReady(map: Map) { this.map = map + + mainScreen.setMap(map) + + setCopyrightPosition( + CopyrightPosition( + gravity = Gravity.BOTTOM or Gravity.START, + margins = CopyrightMargins(left = 20, bottom = 20) + ) + ) } override fun onMapReadyException(exception: Exception) { exception.message?.let(::showToast) } - - override fun onMapClicked(x: Float, y: Float) { - map?.getRenderedObjects(centerPoint = ScreenPoint(x = x, y = y))?.onResult { - val objectInfo = it.firstOrNull() - showToast("$objectInfo") - } - } } diff --git a/app/src/main/res/drawable/ic_zoom_in.xml b/app/src/main/res/drawable/ic_zoom_in.xml new file mode 100644 index 0000000..09ebdd0 --- /dev/null +++ b/app/src/main/res/drawable/ic_zoom_in.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_zoom_out.xml b/app/src/main/res/drawable/ic_zoom_out.xml new file mode 100644 index 0000000..c66c9ca --- /dev/null +++ b/app/src/main/res/drawable/ic_zoom_out.xml @@ -0,0 +1,10 @@ + + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 499ffc4..f14a8f7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ taskTree = "2.1.1" undercouch-download = "5.4.0" ktlint = "11.5.0" -dgis-sdk = "12.0.0" +dgis-sdk = "12.1.0" appcompat = "1.6.1" constraintlayout = "2.1.4"