Fixing deprecation messages (issue 1607) (#2654)

This commit is contained in:
Eric Smith
2024-07-30 18:22:21 -04:00
committed by GitHub
parent f40b5e045b
commit 090f7fd3d6
71 changed files with 959 additions and 1140 deletions

2
.gitignore vendored
View File

@@ -56,3 +56,5 @@ __generated__
cache.sqlite
cache.sqlite-journal
out.png
/test/android/app/.cxx
/test/android/app/build

View File

@@ -1,6 +1,5 @@
package org.maplibre.android.maps;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
@@ -10,6 +9,7 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import org.maplibre.android.utils.MapFragmentUtils;

View File

@@ -44,7 +44,7 @@ public class HttpRequestImpl implements HttpRequest {
BuildConfig.MAPLIBRE_VERSION_STRING,
BuildConfig.GIT_REVISION_SHORT,
Build.VERSION.SDK_INT,
Build.CPU_ABI)
Build.SUPPORTED_ABIS[0])
);
@VisibleForTesting

View File

@@ -9,7 +9,6 @@ import org.maplibre.android.geometry.LatLngBounds
import org.maplibre.android.geometry.LatLngBounds.Companion.from
import org.maplibre.android.style.expressions.Expression
import java.lang.ref.WeakReference
import java.util.Arrays
import java.util.Locale
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadFactory
@@ -19,7 +18,6 @@ import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
/**
@@ -108,7 +106,7 @@ class CustomGeometrySource @UiThread constructor(id: String?, options: CustomGeo
fun querySourceFeatures(filter: Expression?): List<Feature> {
checkThread()
val features = querySourceFeatures(filter?.toArray())
return if (features != null) Arrays.asList(*features) else ArrayList()
return listOf(*features)
}
@Keep
@@ -246,18 +244,17 @@ class CustomGeometrySource @UiThread constructor(id: String?, options: CustomGeo
internal class TileID(var z: Int, var x: Int, var y: Int) {
override fun hashCode(): Int {
return Arrays.hashCode(intArrayOf(z, x, y))
return intArrayOf(z, x, y).contentHashCode()
}
override fun equals(`object`: Any?): Boolean {
if (`object` === this) {
override fun equals(other: Any?): Boolean {
if (other === this) {
return true
}
if (`object` == null || javaClass != `object`.javaClass) {
if (other == null || javaClass != other.javaClass) {
return false
}
if (`object` is TileID) {
val other = `object`
if (other is TileID) {
return z == other.z && x == other.x && y == other.y
}
return false
@@ -299,7 +296,7 @@ class CustomGeometrySource @UiThread constructor(id: String?, options: CustomGeo
if (!isCancelled()) {
val data = provider!!.getFeaturesForBounds(from(id.z, id.x, id.y), id.z)
val source = sourceRef.get()
if (!isCancelled() && source != null && data != null) {
if (!isCancelled() && source != null) {
source.setTileData(id, data)
}
}
@@ -324,14 +321,14 @@ class CustomGeometrySource @UiThread constructor(id: String?, options: CustomGeo
return cancelled!!.get()
}
override fun equals(o: Any?): Boolean {
if (this === o) {
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (o == null || javaClass != o.javaClass) {
if (other == null || javaClass != other.javaClass) {
return false
}
val request = o as GeometryTileRequest
val request = other as GeometryTileRequest
return id == request.id
}
}

View File

@@ -112,7 +112,7 @@ class VectorSource : Source {
fun querySourceFeatures(@Size(min = 1) sourceLayerIds: Array<String>, filter: Expression?): List<Feature> {
checkThread()
val features = querySourceFeatures(sourceLayerIds, filter?.toArray())
return if (features != null) Arrays.asList(*features) else ArrayList()
return listOf(*features)
}
/**

View File

@@ -120,7 +120,7 @@ dependencies {
androidTestImplementation libs.appCenter
androidTestImplementation libs.androidxTestExtJUnit
androidTestImplementation libs.androidxTestCoreKtx
androidTestImplementation libs.kotlinxCoroutinesTest
}
apply from: "${rootDir}/gradle/gradle-make.gradle"

View File

@@ -192,7 +192,7 @@ class LocationComponentTest : EspressoTest() {
uiController: UiController,
context: Context
) {
maplibreMap.setStyle(Style.Builder().fromUrl(TestStyles.getPredefinedStyleWithFallback("Bright")))
maplibreMap.setStyle(Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Bright")))
component.activateLocationComponent(
LocationComponentActivationOptions
@@ -677,7 +677,7 @@ class LocationComponentTest : EspressoTest() {
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
component.isLocationComponentEnabled = false
maplibreMap.setStyle(Style.Builder().fromUrl(TestStyles.getPredefinedStyleWithFallback("Bright")))
maplibreMap.setStyle(Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Bright")))
component.isLocationComponentEnabled = true
TestingAsyncUtils.waitForLayer(uiController, mapView)
@@ -823,7 +823,7 @@ class LocationComponentTest : EspressoTest() {
.build()
)
component.isLocationComponentEnabled = true
maplibreMap.setStyle(Style.Builder().fromUrl(TestStyles.getPredefinedStyleWithFallback("Bright")))
maplibreMap.setStyle(Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Bright")))
component.onStop()
component.onStart()
TestingAsyncUtils.waitForLayer(uiController, mapView)
@@ -910,7 +910,7 @@ class LocationComponentTest : EspressoTest() {
)
component.isLocationComponentEnabled = true
component.forceLocationUpdate(location)
maplibreMap.setStyle(Style.Builder().fromUrl(TestStyles.getPredefinedStyleWithFallback("Bright")))
maplibreMap.setStyle(Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Bright")))
component.onStop()
TestingAsyncUtils.waitForLayer(uiController, mapView)
component.onStart()

View File

@@ -30,10 +30,10 @@ import org.maplibre.android.testapp.utils.TestingAsyncUtils
import org.maplibre.android.utils.BitmapUtils
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -504,7 +504,7 @@ class LocationLayerControllerTest : EspressoTest() {
`is`(true)
)
maplibreMap.setStyle(Style.Builder().fromUrl(TestStyles.getPredefinedStyleWithFallback("Bright")))
maplibreMap.setStyle(Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Bright")))
TestingAsyncUtils.waitForLayer(uiController, mapView)
assertThat(
@@ -676,7 +676,7 @@ class LocationLayerControllerTest : EspressoTest() {
assertThat(
Math.abs(zoom - maplibreMap.cameraPosition.zoom) < 0.1 &&
Math.abs(target.latitude - maplibreMap.cameraPosition.target!!.latitude) < 0.1 &&
Math.abs(target!!.longitude - maplibreMap.cameraPosition.target!!.longitude) < 0.1,
Math.abs(target.longitude - maplibreMap.cameraPosition.target!!.longitude) < 0.1,
`is`(true)
)
@@ -722,7 +722,7 @@ class LocationLayerControllerTest : EspressoTest() {
assertThat(
abs(zoom - maplibreMap.cameraPosition.zoom) < 0.1 &&
abs(target.latitude - maplibreMap.cameraPosition.target!!.latitude) < 0.1 &&
abs(target!!.longitude - maplibreMap.cameraPosition.target!!.longitude) < 0.1,
abs(target.longitude - maplibreMap.cameraPosition.target!!.longitude) < 0.1,
`is`(true)
)

View File

@@ -3,6 +3,8 @@ package org.maplibre.android.testapp.offline
import android.content.Context
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import androidx.test.rule.ActivityTestRule
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import java.io.IOException
import java.util.concurrent.CountDownLatch
import org.junit.After
@@ -50,6 +52,7 @@ class OfflineManagerTest : AppCenter() {
latch.await()
}
@OptIn(ExperimentalCoroutinesApi::class)
@Test(timeout = 30_000)
fun combinedTest() {
@@ -59,18 +62,19 @@ class OfflineManagerTest : AppCenter() {
val latch1 = CountDownLatch(1)
rule.activity.runOnUiThread {
FileUtils.CopyFileFromAssetsTask(
rule.activity,
object : FileUtils.OnFileCopiedFromAssetsListener {
override fun onFileCopiedFromAssets() {
latch1.countDown()
}
override fun onError() {
throw IOException("Unable to copy DB file.")
}
}
).execute(TEST_DB_FILE_NAME, FileSource.getResourcesCachePath(rule.activity))
var copied = false
runTest {
copied = FileUtils.copyFileFromAssetsTask(
rule.activity,
TEST_DB_FILE_NAME,
FileSource.getResourcesCachePath(rule.activity)
)
}
if (copied) {
latch1.countDown()
} else {
throw IOException("Unable to copy DB file.")
}
}
latch1.await()

View File

@@ -26,7 +26,7 @@ class ImageTest : EspressoTest() {
fun testAddGetImage() {
validateTestSetup()
MapLibreMapAction.invoke(maplibreMap) { uiController, maplibreMap ->
val drawable = rule.activity.resources.getDrawable(R.drawable.ic_launcher_round)
val drawable = rule.activity.resources.getDrawable(R.drawable.ic_launcher_round, null)
assertTrue(drawable is BitmapDrawable)
val bitmapSet = (drawable as BitmapDrawable).bitmap

View File

@@ -5,17 +5,17 @@ import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.res.Resources.NotFoundException
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SimpleOnItemTouchListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.adapter.FeatureAdapter
import org.maplibre.android.testapp.adapter.FeatureSectionAdapter
@@ -37,7 +37,6 @@ class FeatureOverviewActivity : AppCompatActivity() {
private var sectionAdapter: FeatureSectionAdapter? = null
private var features: List<Feature>? = null
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_feature_overview)
@@ -65,22 +64,26 @@ class FeatureOverviewActivity : AppCompatActivity() {
}
private fun loadFeatures() {
try {
LoadFeatureTask().execute(
packageManager.getPackageInfo(
packageName,
PackageManager.GET_ACTIVITIES or PackageManager.GET_META_DATA
lifecycleScope.launch(Dispatchers.IO) {
try {
features = loadFeaturesTask(
packageManager.getPackageInfo(
packageName,
PackageManager.GET_ACTIVITIES or PackageManager.GET_META_DATA
)
)
)
} catch (exception: PackageManager.NameNotFoundException) {
Timber.e(exception, "Could not resolve package info")
withContext(Dispatchers.Main) {
onFeaturesLoaded(features)
}
} catch (exception: PackageManager.NameNotFoundException) {
Timber.e(exception, "Could not resolve package info")
}
}
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun onFeaturesLoaded(featuresList: List<Feature>?) {
features = featuresList
if (featuresList == null || featuresList.isEmpty()) {
if (featuresList.isNullOrEmpty()) {
return
}
val sections: MutableList<FeatureSectionAdapter.Section> = ArrayList()
@@ -100,7 +103,7 @@ class FeatureOverviewActivity : AppCompatActivity() {
FeatureAdapter(features!!)
)
sectionAdapter!!.setSections(sections.toTypedArray())
recyclerView!!.adapter = sectionAdapter
recyclerView.adapter = sectionAdapter
}
private fun startFeature(feature: Feature) {
@@ -114,59 +117,52 @@ class FeatureOverviewActivity : AppCompatActivity() {
outState.putParcelableArrayList(KEY_STATE_FEATURES, features as ArrayList<Feature>?)
}
private inner class LoadFeatureTask : AsyncTask<PackageInfo?, Void?, List<Feature>>() {
protected override fun doInBackground(vararg p0: PackageInfo?): List<Feature>? {
val features: MutableList<Feature> = ArrayList()
val app = p0[0]
val packageName = FeatureOverviewActivity.javaClass.`package`.name
val metaDataKey = getString(R.string.category)
if (app != null) {
for (info in app.activities) {
if (info.labelRes != 0 && info.name.startsWith(packageName) &&
info.name != FeatureOverviewActivity::class.java.name
) {
val label = getString(info.labelRes)
val description = resolveString(info.descriptionRes)
val category = resolveMetaData(info.metaData, metaDataKey)
features.add(Feature(info.name, label, description, category!!))
}
private fun loadFeaturesTask(vararg p0: PackageInfo?): List<Feature> {
val features: MutableList<Feature> = ArrayList()
val app = p0[0]
val packageName = FeatureOverviewActivity::class.java.`package`!!.name
val metaDataKey = getString(R.string.category)
if (app != null) {
for (info in app.activities) {
if (info.labelRes != 0 && info.name.startsWith(packageName) &&
info.name != FeatureOverviewActivity::class.java.name
) {
val label = getString(info.labelRes)
val description = resolveString(info.descriptionRes)
val category = resolveMetaData(info.metaData, metaDataKey)
features.add(Feature(info.name, label, description, category!!))
}
}
if (!features.isEmpty()) {
val comparator = Comparator { lhs: Feature, rhs: Feature ->
var result = lhs.category.compareTo(rhs.category, ignoreCase = true)
if (result == 0) {
result = lhs.getLabel().compareTo(rhs.getLabel(), ignoreCase = true)
}
result
}
if (features.isNotEmpty()) {
val comparator = Comparator { lhs: Feature, rhs: Feature ->
var result = lhs.category.compareTo(rhs.category, ignoreCase = true)
if (result == 0) {
result = lhs.getLabel().compareTo(rhs.getLabel(), ignoreCase = true)
}
Collections.sort(features, comparator)
result
}
return features
Collections.sort(features, comparator)
}
return features
}
private fun resolveMetaData(bundle: Bundle?, key: String): String? {
var category: String? = null
if (bundle != null) {
category = bundle.getString(key)
}
return category
private fun resolveMetaData(bundle: Bundle?, key: String): String? {
var category: String? = null
if (bundle != null) {
category = bundle.getString(key)
}
return category
}
private fun resolveString(@StringRes stringRes: Int): String {
return try {
getString(stringRes)
} catch (exception: NotFoundException) {
"-"
}
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onPostExecute(features: List<Feature>) {
super.onPostExecute(features)
onFeaturesLoaded(features)
private fun resolveString(@StringRes stringRes: Int): String {
return try {
getString(stringRes)
} catch (exception: NotFoundException) {
"-"
}
}
companion object {
private const val KEY_STATE_FEATURES = "featureList"
}

View File

@@ -1,7 +1,6 @@
package org.maplibre.android.testapp.activity.annotation
import android.app.ProgressDialog
import android.os.AsyncTask
import android.os.Bundle
import android.view.Menu
import android.view.View
@@ -10,20 +9,22 @@ import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter
import android.widget.Spinner
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuItemCompat
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.maplibre.android.annotations.MarkerOptions
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
import org.maplibre.android.testapp.utils.GeoParseUtil
import timber.log.Timber
import java.io.IOException
import java.lang.ref.WeakReference
import java.text.DecimalFormat
import java.util.*
import kotlin.math.min
/**
* Test activity showcasing adding a large amount of Markers.
@@ -38,7 +39,7 @@ class BulkMarkerActivity : AppCompatActivity(), OnItemSelectedListener {
setContentView(R.layout.activity_marker_bulk)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(OnMapReadyCallback { maplibreMap: MapLibreMap -> initMap(maplibreMap) })
mapView.getMapAsync { initMap(it) }
}
private fun initMap(maplibreMap: MapLibreMap) {
@@ -55,7 +56,7 @@ class BulkMarkerActivity : AppCompatActivity(), OnItemSelectedListener {
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
menuInflater.inflate(R.menu.menu_bulk_marker, menu)
val item = menu.findItem(R.id.spinner)
val spinner = MenuItemCompat.getActionView(item) as Spinner
val spinner = item.actionView as Spinner
spinner.adapter = spinnerAdapter
spinner.onItemSelectedListener = this@BulkMarkerActivity
return true
@@ -65,7 +66,12 @@ class BulkMarkerActivity : AppCompatActivity(), OnItemSelectedListener {
val amount = Integer.valueOf(resources.getStringArray(R.array.bulk_marker_list)[position])
if (locations == null) {
progressDialog = ProgressDialog.show(this, "Loading", "Fetching markers", false)
LoadLocationTask(this, amount).execute()
lifecycleScope.launch(Dispatchers.IO) {
locations = loadLocationTask(this@BulkMarkerActivity)
withContext(Dispatchers.Main) {
onLatLngListLoaded(locations, amount)
}
}
} else {
showMarkers(amount)
}
@@ -78,15 +84,11 @@ class BulkMarkerActivity : AppCompatActivity(), OnItemSelectedListener {
}
private fun showMarkers(amount: Int) {
var amount = amount
if (maplibreMap == null || locations == null || mapView.isDestroyed) {
if (!this::maplibreMap.isInitialized || locations == null || mapView.isDestroyed) {
return
}
maplibreMap.clear()
if (locations!!.size < amount) {
amount = locations!!.size
}
showGlMarkers(amount)
showGlMarkers(min(amount, locations!!.size))
}
private fun showGlMarkers(amount: Int) {
@@ -149,38 +151,18 @@ class BulkMarkerActivity : AppCompatActivity(), OnItemSelectedListener {
mapView.onLowMemory()
}
private class LoadLocationTask constructor(
private fun loadLocationTask(
activity: BulkMarkerActivity,
private val amount: Int
) : AsyncTask<Void?, Int?, List<LatLng>?>() {
private val activity: WeakReference<BulkMarkerActivity>
override fun doInBackground(vararg p0: Void?): List<LatLng>? {
val activity = activity.get()
if (activity != null) {
var json: String? = null
try {
json = GeoParseUtil.loadStringFromAssets(
activity.applicationContext,
"points.geojson"
)
} catch (exception: IOException) {
Timber.e(exception, "Could not add markers")
}
if (json != null) {
return GeoParseUtil.parseGeoJsonCoordinates(json)
}
}
return null
}
override fun onPostExecute(locations: List<LatLng>?) {
super.onPostExecute(locations)
val activity = activity.get()
activity?.onLatLngListLoaded(locations, amount)
}
init {
this.activity = WeakReference(activity)
) : List<LatLng>? {
try {
val json = GeoParseUtil.loadStringFromAssets(
activity.applicationContext,
"points.geojson"
)
return GeoParseUtil.parseGeoJsonCoordinates(json)
} catch (exception: IOException) {
Timber.e(exception, "Could not add markers")
}
return null
}
}

View File

@@ -1,7 +1,6 @@
package org.maplibre.android.testapp.activity.annotation
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
@@ -30,9 +29,9 @@ class DynamicMarkerChangeActivity : AppCompatActivity() {
mapView.setTag(false)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { maplibreMap: MapLibreMap ->
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets"))
this@DynamicMarkerChangeActivity.maplibreMap = maplibreMap
OnMapReadyCallback { map: MapLibreMap ->
map.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets"))
maplibreMap = map
// Create marker
val markerOptions = MarkerOptions()
.position(LAT_LNG_CHELSEA)
@@ -45,14 +44,12 @@ class DynamicMarkerChangeActivity : AppCompatActivity() {
)
.title(getString(R.string.dynamic_marker_chelsea_title))
.snippet(getString(R.string.dynamic_marker_chelsea_snippet))
marker = maplibreMap.addMarker(markerOptions)
marker = map.addMarker(markerOptions)
}
)
val fab = findViewById<FloatingActionButton>(R.id.fab)
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary))
fab.setOnClickListener { view: View? ->
updateMarker()
}
fab.setOnClickListener { updateMarker() }
}
private fun updateMarker() {

View File

@@ -103,7 +103,7 @@ class JsonApiActivity : AppCompatActivity() {
// Intentionally specify package name
// This makes copy from another project easier
org.maplibre.android.R.drawable.maplibre_info_icon_default,
null
theme
)!!
val bitmapBlue = infoIconDrawable.toBitmap()
val bitmapRed = infoIconDrawable

View File

@@ -12,7 +12,6 @@ import org.maplibre.android.annotations.PolylineOptions
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
import java.util.*
@@ -33,6 +32,7 @@ class PolylineActivity : AppCompatActivity() {
private var showPolylines = true
private var width = true
private var color = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_polyline)
@@ -43,23 +43,21 @@ class PolylineActivity : AppCompatActivity() {
}
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { maplibreMap: MapLibreMap ->
this@PolylineActivity.maplibreMap = maplibreMap
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Satellite Hybrid"))
maplibreMap.setOnPolylineClickListener { polyline: Polyline ->
Toast.makeText(
this@PolylineActivity,
"You clicked on polyline with id = " + polyline.id,
Toast.LENGTH_SHORT
).show()
}
polylines = maplibreMap.addPolylines(polylineOptions!!)
mapView.getMapAsync {
maplibreMap = it
it.setStyle(TestStyles.getPredefinedStyleWithFallback("Satellite Hybrid"))
it.setOnPolylineClickListener { polyline: Polyline ->
Toast.makeText(
this@PolylineActivity,
"You clicked on polyline with id = " + polyline.id,
Toast.LENGTH_SHORT
).show()
}
)
polylines = it.addPolylines(polylineOptions!!)
}
val fab = findViewById<View>(R.id.fab)
fab?.setOnClickListener { view: View? ->
if (maplibreMap != null) {
fab?.setOnClickListener {
if (this::maplibreMap.isInitialized) {
if (polylines != null && polylines!!.size > 0) {
if (polylines!!.size == 1) {
// test for removing annotation
@@ -70,14 +68,14 @@ class PolylineActivity : AppCompatActivity() {
}
}
polylineOptions!!.clear()
polylineOptions!!.addAll(randomLine)
polylineOptions!!.add(allPolylines.random())
polylines = maplibreMap.addPolylines(polylineOptions!!)
}
}
}
private val allPolylines: List<PolylineOptions?>
private get() {
get() {
val options: MutableList<PolylineOptions?> = ArrayList()
options.add(generatePolyline(ANDORRA, LUXEMBOURG, "#F44336"))
options.add(generatePolyline(ANDORRA, MONACO, "#FF5722"))
@@ -96,17 +94,6 @@ class PolylineActivity : AppCompatActivity() {
return line
}
val randomLine: List<PolylineOptions?>
get() {
val randomLines = allPolylines
Collections.shuffle(randomLines)
return object : ArrayList<PolylineOptions?>() {
init {
add(randomLines[0])
}
}
}
override fun onStart() {
super.onStart()
mapView.onStart()

View File

@@ -25,6 +25,7 @@ class PressForMarkerActivity : AppCompatActivity() {
private lateinit var mapView: MapView
private lateinit var maplibreMap: MapLibreMap
private var markerList: ArrayList<MarkerOptions>? = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_press_for_marker)
@@ -45,7 +46,7 @@ class PressForMarkerActivity : AppCompatActivity() {
}
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets"))
if (savedInstanceState != null) {
markerList = savedInstanceState.getParcelableArrayList(STATE_MARKER_LIST)
markerList = savedInstanceState.getParcelableArrayList(STATE_MARKER_LIST, MarkerOptions::class.java)
if (markerList != null) {
maplibreMap.addMarkers(markerList!!)
}
@@ -69,11 +70,10 @@ class PressForMarkerActivity : AppCompatActivity() {
}
private fun resetMap() {
if (maplibreMap == null) {
return
if (this::maplibreMap.isInitialized) {
markerList?.clear()
maplibreMap.removeAnnotations()
}
markerList!!.clear()
maplibreMap.removeAnnotations()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {

View File

@@ -36,8 +36,6 @@ import org.maplibre.android.testapp.utils.BenchmarkResults
import org.maplibre.android.testapp.utils.FrameTimeStore
import java.io.File
import java.util.*
data class BenchmarkInputData(
val styleNames: List<String>,
val styleURLs: List<String>,
@@ -120,18 +118,6 @@ class BenchmarkActivity : AppCompatActivity() {
// ```
private lateinit var inputData: BenchmarkInputData
@SuppressLint("DiscouragedApi")
private fun getStringFromResources(name: String): String {
return try {
resources.getString(applicationContext.resources.getIdentifier(
name,
"string",
applicationContext.packageName))
} catch (e: Throwable) {
""
}
}
@SuppressLint("DiscouragedApi")
private fun getArrayFromResources(name: String): Array<String> {
return try {

View File

@@ -50,7 +50,7 @@ class CameraAnimationTypeActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mapView: MapView
private var cameraState = false
private val cameraIdleListener = OnCameraIdleListener {
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
Timber.w(maplibreMap.cameraPosition.toString())
}
}
@@ -114,7 +114,7 @@ class CameraAnimationTypeActivity : AppCompatActivity(), OnMapReadyCallback {
}
private val nextLatLng: LatLng
private get() {
get() {
cameraState = !cameraState
return if (cameraState) LAT_LNG_TOWER_BRIDGE else LAT_LNG_LONDON_EYE
}
@@ -146,7 +146,7 @@ class CameraAnimationTypeActivity : AppCompatActivity(), OnMapReadyCallback {
override fun onDestroy() {
super.onDestroy()
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.removeOnCameraIdleListener(cameraIdleListener)
}
mapView.onDestroy()

View File

@@ -208,7 +208,7 @@ class CameraAnimatorActivity : AppCompatActivity(), OnMapReadyCallback {
for (i in 0 until animators.size()) {
animators[animators.keyAt(i)]!!.cancel()
}
if (set != null) {
if (this::set.isInitialized) {
set.cancel()
}
}

View File

@@ -4,7 +4,11 @@ import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.*
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.ColorInt
@@ -13,21 +17,26 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mapbox.android.gestures.*
import com.mapbox.android.gestures.AndroidGesturesManager
import com.mapbox.android.gestures.MoveGestureDetector
import com.mapbox.android.gestures.RotateGestureDetector
import com.mapbox.android.gestures.ShoveGestureDetector
import com.mapbox.android.gestures.StandardScaleGestureDetector
import org.maplibre.android.annotations.Marker
import org.maplibre.android.annotations.MarkerOptions
import org.maplibre.android.camera.CameraUpdateFactory
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.MapLibreMap.*
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.MapLibreMap.CancelableCallback
import org.maplibre.android.maps.MapLibreMap.OnMoveListener
import org.maplibre.android.maps.MapLibreMap.OnRotateListener
import org.maplibre.android.maps.MapLibreMap.OnScaleListener
import org.maplibre.android.maps.MapLibreMap.OnShoveListener
import org.maplibre.android.maps.MapView
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
import org.maplibre.android.testapp.utils.FontCache
import org.maplibre.android.testapp.utils.ResourceUtils
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
/** Test activity showcasing APIs around gestures implementation. */
class GestureDetectorActivity : AppCompatActivity() {
@@ -43,13 +52,11 @@ class GestureDetectorActivity : AppCompatActivity() {
setContentView(R.layout.activity_gesture_detector)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { maplibreMap: MapLibreMap ->
this@GestureDetectorActivity.maplibreMap = maplibreMap
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets"))
initializeMap()
}
)
mapView.getMapAsync { map: MapLibreMap ->
maplibreMap = map
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets"))
initializeMap()
}
recyclerView = findViewById(R.id.alerts_recycler)
recyclerView.setLayoutManager(LinearLayoutManager(this))
gestureAlertsAdapter = GestureAlertsAdapter()
@@ -94,10 +101,10 @@ class GestureDetectorActivity : AppCompatActivity() {
private fun initializeMap() {
gesturesManager = maplibreMap.gesturesManager
val layoutParams = recyclerView!!.layoutParams as RelativeLayout.LayoutParams
val layoutParams = recyclerView.layoutParams as RelativeLayout.LayoutParams
layoutParams.height = (mapView.height / 1.75).toInt()
layoutParams.width = mapView.width / 3
recyclerView!!.layoutParams = layoutParams
recyclerView.layoutParams = layoutParams
attachListeners()
fixedFocalPointEnabled(maplibreMap.uiSettings.focalPoint != null)
}
@@ -313,8 +320,6 @@ class GestureDetectorActivity : AppCompatActivity() {
class ViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
var alertMessageTv: TextView
@ColorInt var textColor = 0
init {
val typeface = FontCache.get("Roboto-Regular.ttf", view.context)
alertMessageTv = view.findViewById(R.id.alert_message)
@@ -371,25 +376,24 @@ class GestureDetectorActivity : AppCompatActivity() {
}
}
private class GestureAlert
internal constructor(
private class GestureAlert(
@field:Type @param:Type
val alertType: Int,
val message: String?
) {
@Retention(RetentionPolicy.SOURCE)
@Retention(AnnotationRetention.SOURCE)
@IntDef(TYPE_NONE, TYPE_START, TYPE_PROGRESS, TYPE_END, TYPE_OTHER)
internal annotation class Type
annotation class Type
@ColorInt var color = 0
override fun equals(o: Any?): Boolean {
if (this === o) {
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (o == null || javaClass != o.javaClass) {
if (other == null || javaClass != other.javaClass) {
return false
}
val that = o as GestureAlert
val that = other as GestureAlert
if (alertType != that.alertType) {
return false
}

View File

@@ -99,7 +99,7 @@ class LatLngBoundsActivity : AppCompatActivity() {
private fun initBottomSheet() {
bottomSheetBehavior = BottomSheetBehavior.from(binding.bottomSheet)
bottomSheetBehavior.setBottomSheetCallback(
bottomSheetBehavior.addBottomSheetCallback(
object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
val offset = convertSlideOffset(slideOffset)

View File

@@ -3,7 +3,6 @@ package org.maplibre.android.testapp.activity.camera
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapView.OnDidFinishLoadingStyleListener
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.MapLibreMap.OnMapClickListener
import org.maplibre.android.maps.OnMapReadyCallback
@@ -17,7 +16,7 @@ class MaxMinZoomActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mapView: MapView
private lateinit var maplibreMap: MapLibreMap
private val clickListener = OnMapClickListener {
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.setStyle(Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Outdoor")))
}
true
@@ -26,12 +25,10 @@ class MaxMinZoomActivity : AppCompatActivity(), OnMapReadyCallback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maxmin_zoom)
mapView = findViewById<MapView>(R.id.mapView)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(this)
mapView.addOnDidFinishLoadingStyleListener(
OnDidFinishLoadingStyleListener { Timber.d("Style Loaded") }
)
mapView.addOnDidFinishLoadingStyleListener { Timber.d("Style Loaded") }
}
override fun onMapReady(map: MapLibreMap) {
@@ -69,7 +66,7 @@ class MaxMinZoomActivity : AppCompatActivity(), OnMapReadyCallback {
override fun onDestroy() {
super.onDestroy()
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.removeOnMapClickListener(clickListener)
}
mapView.onDestroy()

View File

@@ -46,7 +46,7 @@ class ScrollByActivity : AppCompatActivity(), OnMapReadyCallback {
PixelBarChangeListener(textViewY, R.string.scrollby_y_value)
)
mapView = findViewById(R.id.mapView)
mapView.setTag(true)
mapView.tag = true
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(this)
}
@@ -59,10 +59,10 @@ class ScrollByActivity : AppCompatActivity(), OnMapReadyCallback {
uiSettings.isAttributionEnabled = false
val fab = findViewById<FloatingActionButton>(R.id.fab)
fab.setColorFilter(ContextCompat.getColor(this@ScrollByActivity, R.color.primary))
fab.setOnClickListener { view: View? ->
fab.setOnClickListener { _: View? ->
maplibreMap.scrollBy(
(seekBarX!!.progress * MULTIPLIER_PER_PIXEL).toFloat(),
(seekBarY!!.progress * MULTIPLIER_PER_PIXEL).toFloat()
(seekBarX.progress * MULTIPLIER_PER_PIXEL).toFloat(),
(seekBarY.progress * MULTIPLIER_PER_PIXEL).toFloat()
)
}
}
@@ -105,15 +105,14 @@ class ScrollByActivity : AppCompatActivity(), OnMapReadyCallback {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
private class PixelBarChangeListener
internal constructor(
private class PixelBarChangeListener(
private val valueView: TextView,
@field:StringRes @param:StringRes
private val prefixTextResource: Int

View File

@@ -11,7 +11,6 @@ import org.maplibre.android.camera.CameraUpdateFactory
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.style.layers.CustomLayer
import org.maplibre.android.testapp.R
@@ -35,30 +34,26 @@ class CustomLayerActivity : AppCompatActivity() {
setContentView(R.layout.activity_custom_layer)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { map: MapLibreMap? ->
maplibreMap = map!!
maplibreMap.moveCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(39.91448, -243.60947),
10.0
)
mapView.getMapAsync { map: MapLibreMap ->
maplibreMap = map
maplibreMap.moveCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(39.91448, -243.60947),
10.0
)
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style? -> initFab() }
}
)
)
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { _: Style? -> initFab() }
}
}
private fun initFab() {
fab = findViewById(R.id.fab)
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary))
fab.setOnClickListener(
View.OnClickListener { view: View? ->
if (maplibreMap != null) {
swapCustomLayer()
}
fab.setOnClickListener { _: View? ->
if (this::maplibreMap.isInitialized) {
swapCustomLayer()
}
)
}
}
private fun swapCustomLayer() {
@@ -66,19 +61,19 @@ class CustomLayerActivity : AppCompatActivity() {
if (customLayer != null) {
style!!.removeLayer(customLayer!!)
customLayer = null
fab!!.setImageResource(R.drawable.ic_layers)
fab.setImageResource(R.drawable.ic_layers)
} else {
customLayer = CustomLayer(
"custom",
ExampleCustomLayer.createContext()
)
style!!.addLayerBelow(customLayer!!, "building")
fab!!.setImageResource(R.drawable.ic_layers_clear)
fab.setImageResource(R.drawable.ic_layers_clear)
}
}
private fun updateLayer() {
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.triggerRepaint()
}
}

View File

@@ -6,6 +6,7 @@ import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import org.maplibre.geojson.Feature
import org.maplibre.android.maps.MapView
@@ -26,6 +27,13 @@ class QueryRenderedFeaturesBoxCountActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
NavUtils.navigateHome(this@QueryRenderedFeaturesBoxCountActivity)
}
})
setContentView(R.layout.activity_query_features_box)
val selectionBox = findViewById<View>(R.id.selection_box)
@@ -35,7 +43,7 @@ class QueryRenderedFeaturesBoxCountActivity : AppCompatActivity() {
mapView.getMapAsync { maplibreMap: MapLibreMap ->
this@QueryRenderedFeaturesBoxCountActivity.maplibreMap = maplibreMap
maplibreMap.setStyle(Style.Builder().fromUri(TestStyles.AMERICANA))
selectionBox.setOnClickListener { view: View? ->
selectionBox.setOnClickListener { _: View? ->
// Query
val top = selectionBox.top - mapView.top
val left = selectionBox.left - mapView.left
@@ -132,16 +140,10 @@ class QueryRenderedFeaturesBoxCountActivity : AppCompatActivity() {
android.R.id.home -> {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
onBackPressed()
NavUtils.navigateHome(this)
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onBackPressed() {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
NavUtils.navigateHome(this)
}
}

View File

@@ -161,7 +161,7 @@ class QueryRenderedFeaturesPropertiesActivity : AppCompatActivity() {
override fun onDestroy() {
super.onDestroy()
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.removeOnMapClickListener(mapClickListener)
}
mapView.onDestroy()
@@ -172,7 +172,7 @@ class QueryRenderedFeaturesPropertiesActivity : AppCompatActivity() {
mapView.onLowMemory()
}
private class CustomMarker internal constructor(
private class CustomMarker constructor(
baseMarkerOptions: BaseMarkerOptions<*, *>?,
val features: List<Feature>?
) : Marker(baseMarkerOptions)

View File

@@ -1,6 +1,7 @@
package org.maplibre.android.testapp.activity.fragment
import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.SupportMapFragment
@@ -26,6 +27,18 @@ class FragmentBackStackActivity : AppCompatActivity() {
binding = ActivityBackstackFragmentBinding.inflate(layoutInflater)
setContentView(binding.root)
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (supportFragmentManager.backStackEntryCount == 0) {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
NavUtils.navigateHome(this@FragmentBackStackActivity)
} else {
finish()
}
}
})
if (savedInstanceState == null) {
mapFragment = SupportMapFragment.newInstance()
mapFragment.getMapAsync { initMap(it) }
@@ -61,14 +74,4 @@ class FragmentBackStackActivity : AppCompatActivity() {
addToBackStack("map_empty_fragment")
}.commit()
}
override fun onBackPressed() {
if (supportFragmentManager.backStackEntryCount == 0) {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
NavUtils.navigateHome(this)
} else {
super.onBackPressed()
}
}
}

View File

@@ -32,12 +32,12 @@ class MapFragmentActivity :
val mapFragment: MapFragment
if (savedInstanceState == null) {
mapFragment = MapFragment.newInstance(createFragmentOptions())
fragmentManager
supportFragmentManager
.beginTransaction()
.add(R.id.fragment_container, mapFragment, TAG)
.commit()
} else {
mapFragment = fragmentManager.findFragmentByTag(TAG) as MapFragment
mapFragment = supportFragmentManager.findFragmentByTag(TAG) as MapFragment
}
mapFragment.getMapAsync(this)
}
@@ -73,13 +73,13 @@ class MapFragmentActivity :
override fun onDestroy() {
super.onDestroy()
if (mapView != null) {
if (this::mapView.isInitialized) {
mapView.removeOnDidFinishRenderingFrameListener(this)
}
}
override fun onDidFinishRenderingFrame(fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double) {
if (initialCameraAnimation && fully && maplibreMap != null) {
if (initialCameraAnimation && fully && this::maplibreMap.isInitialized) {
maplibreMap.animateCamera(
CameraUpdateFactory.newCameraPosition(CameraPosition.Builder().tilt(45.0).build()),
5000

View File

@@ -8,6 +8,8 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import org.maplibre.android.camera.CameraPosition
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapLibreMapOptions
@@ -99,7 +101,7 @@ class NestedViewPagerActivity : AppCompatActivity() {
}
}
class MapPagerAdapter(private val context: Context, fm: androidx.fragment.app.FragmentManager) : androidx.fragment.app.FragmentStatePagerAdapter(fm) {
class MapPagerAdapter(private val context: Context, fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): androidx.fragment.app.Fragment {
val options = MapLibreMapOptions.createFromAttributes(context)

View File

@@ -77,7 +77,7 @@ class SupportMapFragmentActivity :
}
override fun onDidFinishRenderingFrame(fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double) {
if (initialCameraAnimation && fully && maplibreMap != null) {
if (initialCameraAnimation && fully && this::maplibreMap.isInitialized) {
maplibreMap.animateCamera(
CameraUpdateFactory.newCameraPosition(CameraPosition.Builder().tilt(45.0).build()),
5000

View File

@@ -3,6 +3,8 @@ package org.maplibre.android.testapp.activity.fragment
import android.content.Context
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import org.maplibre.android.camera.CameraPosition
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapLibreMapOptions
@@ -38,7 +40,7 @@ class ViewPagerActivity : AppCompatActivity() {
}
}
internal class MapFragmentAdapter(private val context: Context, fragmentManager: androidx.fragment.app.FragmentManager) : androidx.fragment.app.FragmentStatePagerAdapter(fragmentManager) {
internal class MapFragmentAdapter(private val context: Context, fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
override fun getCount(): Int {
return NUM_ITEMS

View File

@@ -7,12 +7,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.print.PrintHelper
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
/**
* Test activity showcasing using the Snaphot API to print a Map.
* Test activity showcasing using the Snapshot API to print a Map.
*/
class PrintActivity : AppCompatActivity(), MapLibreMap.SnapshotReadyCallback {
private lateinit var mapView: MapView
@@ -22,10 +21,10 @@ class PrintActivity : AppCompatActivity(), MapLibreMap.SnapshotReadyCallback {
setContentView(R.layout.activity_print)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(OnMapReadyCallback { maplibreMap: MapLibreMap -> initMap(maplibreMap) })
mapView.getMapAsync(this::initMap)
val fab = findViewById<View>(R.id.fab)
fab?.setOnClickListener { view: View? ->
if (maplibreMap != null && maplibreMap.style != null) {
fab?.setOnClickListener { _: View? ->
if (this::maplibreMap.isInitialized && maplibreMap.style != null) {
maplibreMap.snapshot(this@PrintActivity)
}
}

View File

@@ -61,13 +61,13 @@ class DynamicInfoWindowAdapterActivity : AppCompatActivity(), OnMapReadyCallback
map.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets"))
// Add info window adapter
addCustomInfoWindowAdapter(maplibreMap!!)
addCustomInfoWindowAdapter(maplibreMap)
// Keep info windows open on click
maplibreMap.uiSettings.isDeselectMarkersOnTap = false
// Add a marker
marker = addMarker(maplibreMap!!)
marker = addMarker(maplibreMap)
maplibreMap.selectMarker(marker!!)
// On map click, change the info window contents
@@ -130,7 +130,7 @@ class DynamicInfoWindowAdapterActivity : AppCompatActivity(), OnMapReadyCallback
override fun onDestroy() {
super.onDestroy()
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.removeOnMapClickListener(mapClickListener)
}
mapView.onDestroy()

View File

@@ -164,7 +164,7 @@ class InfoWindowActivity :
override fun onDestroy() {
super.onDestroy()
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.removeOnMapLongClickListener(mapLongClickListener)
}
mapView.onDestroy()

View File

@@ -32,12 +32,13 @@ class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallba
private var permissionsManager: PermissionsManager? = null
private var locationComponent: LocationComponent? = null
private lateinit var maplibreMap: MapLibreMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_location_layer_basic_pulsing_circle)
mapView = findViewById(R.id.mapView)
if (savedInstanceState != null) {
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION)
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION, Location::class.java)
}
mapView.onCreate(savedInstanceState)
checkPermissions()
@@ -94,35 +95,41 @@ class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallba
return super.onOptionsItemSelected(item)
}
val id = item.itemId
if (id == R.id.action_map_style_change) {
loadNewStyle()
return true
} else if (id == R.id.action_component_disable) {
locationComponent!!.isLocationComponentEnabled = false
return true
} else if (id == R.id.action_component_enabled) {
locationComponent!!.isLocationComponentEnabled = true
return true
} else if (id == R.id.action_stop_pulsing) {
locationComponent!!.applyStyle(
LocationComponentOptions.builder(
this@BasicLocationPulsingCircleActivity
when (id) {
R.id.action_map_style_change -> {
loadNewStyle()
return true
}
R.id.action_component_disable -> {
locationComponent!!.isLocationComponentEnabled = false
return true
}
R.id.action_component_enabled -> {
locationComponent!!.isLocationComponentEnabled = true
return true
}
R.id.action_stop_pulsing -> {
locationComponent!!.applyStyle(
LocationComponentOptions.builder(
this@BasicLocationPulsingCircleActivity
)
.pulseEnabled(false)
.build()
)
.pulseEnabled(false)
.build()
)
return true
} else if (id == R.id.action_start_pulsing) {
locationComponent!!.applyStyle(
LocationComponentOptions.builder(
this@BasicLocationPulsingCircleActivity
return true
}
R.id.action_start_pulsing -> {
locationComponent!!.applyStyle(
LocationComponentOptions.builder(
this@BasicLocationPulsingCircleActivity
)
.pulseEnabled(true)
.build()
)
.pulseEnabled(true)
.build()
)
return true
return true
}
else -> return super.onOptionsItemSelected(item)
}
return super.onOptionsItemSelected(item)
}
private fun loadNewStyle() {
@@ -206,6 +213,5 @@ class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallba
companion object {
private const val SAVED_STATE_LOCATION = "saved_state_location"
private const val TAG = "Mbgl-BasicLocationPulsingCircleActivity"
}
}

View File

@@ -43,6 +43,8 @@ class CustomizedLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyC
private var currentPulseDuration = 0f
//endregion
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_location_layer_customized_pulsing_circle)
@@ -58,12 +60,7 @@ class CustomizedLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyC
)
}
pulsingCircleDurationButton = findViewById(R.id.button_location_circle_duration)
pulsingCircleDurationButton.setText(
String.format(
"%sms",
LOCATION_CIRCLE_PULSE_DURATION.toString()
)
)
pulsingCircleDurationButton.text = "${LOCATION_CIRCLE_PULSE_DURATION}ms"
pulsingCircleDurationButton.setOnClickListener(
View.OnClickListener setOnClickListener@{ v: View? ->
if (locationComponent == null) {
@@ -165,36 +162,42 @@ class CustomizedLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyC
return super.onOptionsItemSelected(item)
}
val id = item.itemId
if (id == R.id.action_map_style_change) {
loadNewStyle()
return true
} else if (id == R.id.action_component_disable) {
locationComponent!!.isLocationComponentEnabled = false
return true
} else if (id == R.id.action_component_enabled) {
locationComponent!!.isLocationComponentEnabled = true
return true
} else if (id == R.id.action_stop_pulsing) {
locationComponent!!.applyStyle(
LocationComponentOptions.builder(
this@CustomizedLocationPulsingCircleActivity
when (id) {
R.id.action_map_style_change -> {
loadNewStyle()
return true
}
R.id.action_component_disable -> {
locationComponent!!.isLocationComponentEnabled = false
return true
}
R.id.action_component_enabled -> {
locationComponent!!.isLocationComponentEnabled = true
return true
}
R.id.action_stop_pulsing -> {
locationComponent!!.applyStyle(
LocationComponentOptions.builder(
this@CustomizedLocationPulsingCircleActivity
)
.pulseEnabled(false)
.build()
)
.pulseEnabled(false)
.build()
)
return true
} else if (id == R.id.action_start_pulsing) {
locationComponent!!.applyStyle(
buildLocationComponentOptions(
LOCATION_CIRCLE_PULSE_COLOR,
LOCATION_CIRCLE_PULSE_DURATION
return true
}
R.id.action_start_pulsing -> {
locationComponent!!.applyStyle(
buildLocationComponentOptions(
LOCATION_CIRCLE_PULSE_COLOR,
LOCATION_CIRCLE_PULSE_DURATION
)
.pulseEnabled(true)
.build()
)
.pulseEnabled(true)
.build()
)
return true
return true
}
else -> return super.onOptionsItemSelected(item)
}
return super.onOptionsItemSelected(item)
}
private fun loadNewStyle() {
@@ -241,7 +244,7 @@ class CustomizedLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyC
listPopup.anchorView = pulsingCircleDurationButton
listPopup.setOnItemClickListener { parent: AdapterView<*>?, itemView: View?, position: Int, id: Long ->
val selectedMode = modes[position]
pulsingCircleDurationButton!!.text = selectedMode
pulsingCircleDurationButton.text = selectedMode
if (selectedMode.contentEquals(
String.format(
"%sms",
@@ -300,7 +303,7 @@ class CustomizedLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyC
listPopup.anchorView = pulsingCircleColorButton
listPopup.setOnItemClickListener { parent: AdapterView<*>?, itemView: View?, position: Int, id: Long ->
val selectedTrackingType = trackingTypes[position]
pulsingCircleColorButton!!.text = selectedTrackingType
pulsingCircleColorButton.text = selectedTrackingType
if (selectedTrackingType.contentEquals("Blue")) {
LOCATION_CIRCLE_PULSE_COLOR = Color.BLUE
setNewLocationComponentOptions(currentPulseDuration, Color.BLUE)

View File

@@ -8,6 +8,7 @@ import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import org.maplibre.android.camera.CameraUpdateFactory
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.location.LocationComponentActivationOptions
@@ -41,7 +42,7 @@ class LocationFragmentActivity : AppCompatActivity() {
.addToBackStack("transaction2")
.commit()
} else {
this.onBackPressed()
finish()
}
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
@@ -85,7 +86,7 @@ class LocationFragmentActivity : AppCompatActivity() {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
class LocationFragment : androidx.fragment.app.Fragment(), LocationEngineCallback<LocationEngineResult> {
class LocationFragment : Fragment(), LocationEngineCallback<LocationEngineResult> {
companion object {
const val TAG = "LFragment"
fun newInstance(): LocationFragment {
@@ -167,7 +168,7 @@ class LocationFragmentActivity : AppCompatActivity() {
}
}
class EmptyFragment : androidx.fragment.app.Fragment() {
class EmptyFragment : Fragment() {
companion object {
const val TAG = "EmptyFragment"
fun newInstance(): EmptyFragment {

View File

@@ -26,7 +26,7 @@ class LocationMapChangeActivity : AppCompatActivity(), OnMapReadyCallback {
mapView = findViewById(R.id.mapView)
val stylesFab = findViewById<FloatingActionButton>(R.id.fabStyles)
stylesFab.setOnClickListener { v: View? ->
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.setStyle(Style.Builder().fromUri(Utils.nextStyle()))
}
}

View File

@@ -54,6 +54,7 @@ class LocationModesActivity :
@RenderMode.Mode
private var renderMode = RenderMode.NORMAL
private var lastLocation: Location? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_location_layer_mode)
@@ -80,7 +81,7 @@ class LocationModesActivity :
if (savedInstanceState != null) {
cameraMode = savedInstanceState.getInt(SAVED_STATE_CAMERA)
renderMode = savedInstanceState.getInt(SAVED_STATE_RENDER)
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION)
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION, Location::class.java)
}
mapView.onCreate(savedInstanceState)
if (PermissionsManager.areLocationPermissionsGranted(this)) {
@@ -230,9 +231,7 @@ class LocationModesActivity :
if (defaultStyle) R.style.maplibre_LocationComponent else R.style.CustomLocationComponent
)
if (defaultStyle) {
val padding: IntArray
padding =
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
val padding: IntArray = if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
intArrayOf(0, 750, 0, 0)
} else {
intArrayOf(0, 250, 0, 0)

View File

@@ -4,6 +4,7 @@ import android.content.Context
import android.os.Bundle
import android.view.*
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.google.android.material.bottomsheet.BottomSheetBehavior
@@ -13,6 +14,8 @@ import org.maplibre.android.maps.*
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
import org.maplibre.android.utils.MapFragmentUtils
import kotlin.math.max
import kotlin.math.min
/**
* Test activity showcasing using a bottomView with a MapView and stacking map fragments below.
@@ -22,6 +25,16 @@ class BottomSheetActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bottom_sheet)
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
val fragmentManager = supportFragmentManager
if (fragmentManager.backStackEntryCount > 0) {
fragmentManager.popBackStack()
} else {
finish()
}
}
})
val actionBar = supportActionBar
actionBar?.setDisplayHomeAsUpEnabled(true)
findViewById<View>(R.id.fabFragment).setOnClickListener { v: View? -> addMapFragment() }
@@ -35,20 +48,11 @@ class BottomSheetActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
}
return super.onOptionsItemSelected(item)
}
override fun onBackPressed() {
val fragmentManager = supportFragmentManager
if (fragmentManager.backStackEntryCount > 0) {
fragmentManager.popBackStack()
} else {
super.onBackPressed()
}
}
private fun addMapFragment() {
val fragmentManager = supportFragmentManager
val fragmentCount = fragmentManager.backStackEntryCount
@@ -124,8 +128,8 @@ class BottomSheetActivity : AppCompatActivity() {
maplibreMap.setStyle(
Style.Builder().fromUri(
STYLES[
Math.min(
Math.max(arguments!!.getInt("mapcounter"), 0),
min(
max(requireArguments().getInt("mapcounter"), 0),
STYLES.size - 1
)
]

View File

@@ -61,7 +61,7 @@ open class DebugModeActivity : AppCompatActivity(), OnMapReadyCallback, OnFpsCha
mapView = MapView(this, maplibreMapOptions)
(findViewById<View>(R.id.coordinator_layout) as ViewGroup).addView(mapView, 0)
mapView.addOnDidFinishLoadingStyleListener {
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
setupNavigationView(maplibreMap.style!!.layers)
}
}
@@ -137,7 +137,7 @@ open class DebugModeActivity : AppCompatActivity(), OnMapReadyCallback, OnFpsCha
private fun setupDebugChangeView() {
val fabDebug = findViewById<FloatingActionButton>(R.id.fabDebug)
fabDebug.setOnClickListener { view: View? ->
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.isDebugActive = !maplibreMap.isDebugActive
Timber.d("Debug FAB: isDebug Active? %s", maplibreMap.isDebugActive)
}
@@ -147,7 +147,7 @@ open class DebugModeActivity : AppCompatActivity(), OnMapReadyCallback, OnFpsCha
private fun setupStyleChangeView() {
val fabStyles = findViewById<FloatingActionButton>(R.id.fabStyles)
fabStyles.setOnClickListener { view: View? ->
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
currentStyleIndex++
if (currentStyleIndex == STYLES.size) {
currentStyleIndex = 0
@@ -205,7 +205,7 @@ open class DebugModeActivity : AppCompatActivity(), OnMapReadyCallback, OnFpsCha
override fun onDestroy() {
super.onDestroy()
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.removeOnCameraMoveListener(cameraMoveListener!!)
}
mapView.onDestroy()

View File

@@ -7,7 +7,6 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.Style
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.databinding.ActivityRecyclerviewBinding
@@ -49,7 +48,7 @@ open class GLSurfaceRecyclerViewActivity : AppCompatActivity() {
class ItemAdapter(private val activity: GLSurfaceRecyclerViewActivity, private val inflater: LayoutInflater) : androidx.recyclerview.widget.RecyclerView.Adapter<androidx.recyclerview.widget.RecyclerView.ViewHolder>() {
private val items = listOf(
private val items: List<Any> = listOf(
"one", "two", "three", "four", "five", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
"nineteen", "twenty", "twenty-one"

View File

@@ -40,13 +40,11 @@ class MapInDialogActivity : AppCompatActivity() {
super.onViewCreated(view, savedInstanceState)
mapView = view.findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { maplibreMap: MapLibreMap ->
maplibreMap.setStyle(
TestStyles.getPredefinedStyleWithFallback("Outdoor")
)
}
)
mapView.getMapAsync {
it.setStyle(
TestStyles.getPredefinedStyleWithFallback("Outdoor")
)
}
}
override fun onStart() {
@@ -76,14 +74,14 @@ class MapInDialogActivity : AppCompatActivity() {
override fun onLowMemory() {
super.onLowMemory()
if (mapView != null) {
if (this::mapView.isInitialized) {
mapView.onLowMemory()
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
if (mapView != null) {
if (this::mapView.isInitialized) {
mapView.onSaveInstanceState(outState)
}
}

View File

@@ -24,22 +24,20 @@ class MapPaddingActivity : AppCompatActivity() {
mapView = findViewById(R.id.mapView)
mapView.setTag(true)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { maplibreMap: MapLibreMap ->
this@MapPaddingActivity.maplibreMap = maplibreMap
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets"))
val paddingLeft = resources.getDimension(R.dimen.map_padding_left).toInt()
val paddingBottom = resources.getDimension(R.dimen.map_padding_bottom).toInt()
val paddingRight = resources.getDimension(R.dimen.map_padding_right).toInt()
val paddingTop = resources.getDimension(R.dimen.map_padding_top).toInt()
maplibreMap.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
val settings = maplibreMap.uiSettings
settings.setLogoMargins(paddingLeft, 0, 0, paddingBottom)
settings.setCompassMargins(0, paddingTop, paddingRight, 0)
settings.isAttributionEnabled = false
moveToBangalore()
}
)
mapView.getMapAsync {
maplibreMap = it
it.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets"))
val paddingLeft = resources.getDimension(R.dimen.map_padding_left).toInt()
val paddingBottom = resources.getDimension(R.dimen.map_padding_bottom).toInt()
val paddingRight = resources.getDimension(R.dimen.map_padding_right).toInt()
val paddingTop = resources.getDimension(R.dimen.map_padding_top).toInt()
it.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
val settings = it.uiSettings
settings.setLogoMargins(paddingLeft, 0, 0, paddingBottom)
settings.setCompassMargins(0, paddingTop, paddingRight, 0)
settings.isAttributionEnabled = false
moveToBangalore()
}
}
override fun onStart() {
@@ -97,7 +95,7 @@ class MapPaddingActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_bangalore -> {
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
moveToBangalore()
}
true

View File

@@ -2,6 +2,7 @@ package org.maplibre.android.testapp.activity.maplayout
import android.os.Bundle
import android.view.MenuItem
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import org.maplibre.android.maps.*
import org.maplibre.android.testapp.R
@@ -15,23 +16,30 @@ class SimpleMapActivity : AppCompatActivity() {
private lateinit var mapView: MapView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
onBackPressedDispatcher.addCallback(this, object: OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
NavUtils.navigateHome(this@SimpleMapActivity)
}
})
setContentView(R.layout.activity_map_simple)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { maplibreMap: MapLibreMap ->
var key = ApiKeyUtils.getApiKey(applicationContext)
if (key == null || key == "YOUR_API_KEY_GOES_HERE") {
maplibreMap.setStyle(Style.Builder().fromUri("https://demotiles.maplibre.org/style.json"))
} else {
val styles = Style.getPredefinedStyles()
if (styles != null && styles.size > 0) {
val styleUrl = styles[0].url
maplibreMap.setStyle(Style.Builder().fromUri(styleUrl))
}
mapView.getMapAsync {
val key = ApiKeyUtils.getApiKey(applicationContext)
if (key == null || key == "YOUR_API_KEY_GOES_HERE") {
it.setStyle(
Style.Builder().fromUri("https://demotiles.maplibre.org/style.json")
)
} else {
val styles = Style.getPredefinedStyles()
if (styles.isNotEmpty()) {
val styleUrl = styles[0].url
it.setStyle(Style.Builder().fromUri(styleUrl))
}
}
)
}
}
override fun onStart() {
@@ -74,16 +82,10 @@ class SimpleMapActivity : AppCompatActivity() {
android.R.id.home -> {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
onBackPressed()
onBackPressedDispatcher.onBackPressed()
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onBackPressed() {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
NavUtils.navigateHome(this)
}
}

View File

@@ -3,6 +3,10 @@ package org.maplibre.android.testapp.activity.offline
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.maplibre.android.MapLibre
import org.maplibre.android.log.Logger
import org.maplibre.android.maps.Style
@@ -12,6 +16,7 @@ import org.maplibre.android.storage.FileSource
import org.maplibre.android.testapp.databinding.ActivityMergeOfflineRegionsBinding
import org.maplibre.android.testapp.styles.TestStyles
import org.maplibre.android.testapp.utils.FileUtils
import java.util.Locale
class MergeOfflineRegionsActivity : AppCompatActivity() {
@@ -23,25 +28,6 @@ class MergeOfflineRegionsActivity : AppCompatActivity() {
private var TEST_STYLE = TestStyles.getPredefinedStyleWithFallback("Satellite Hybrid")
}
private val onFileCopiedListener = object : FileUtils.OnFileCopiedFromAssetsListener {
override fun onFileCopiedFromAssets() {
Toast.makeText(
this@MergeOfflineRegionsActivity,
String.format("OnFileCopied."),
Toast.LENGTH_LONG
).show()
mergeDb()
}
override fun onError() {
Toast.makeText(
this@MergeOfflineRegionsActivity,
String.format("Error copying DB file."),
Toast.LENGTH_LONG
).show()
}
}
private val onRegionMergedListener = object : OfflineManager.MergeOfflineRegionsCallback {
override fun onMerge(offlineRegions: Array<OfflineRegion>?) {
binding.mapView.getMapAsync {
@@ -49,7 +35,7 @@ class MergeOfflineRegionsActivity : AppCompatActivity() {
}
Toast.makeText(
this@MergeOfflineRegionsActivity,
String.format("Merged %d regions.", offlineRegions?.size ?: 0),
String.format(Locale.ENGLISH, "Merged %d regions.", offlineRegions?.size ?: 0),
Toast.LENGTH_LONG
).show()
}
@@ -105,7 +91,29 @@ class MergeOfflineRegionsActivity : AppCompatActivity() {
private fun copyAsset() {
// copy db asset to internal memory
FileUtils.CopyFileFromAssetsTask(this, onFileCopiedListener).execute(TEST_DB_FILE_NAME, FileSource.getResourcesCachePath(this))
lifecycleScope.launch(Dispatchers.IO) {
val copied = FileUtils.copyFileFromAssetsTask(
this@MergeOfflineRegionsActivity,
TEST_DB_FILE_NAME,
FileSource.getResourcesCachePath(this@MergeOfflineRegionsActivity)
)
withContext(Dispatchers.Main) {
if (copied) {
Toast.makeText(
this@MergeOfflineRegionsActivity,
String.format("OnFileCopied."),
Toast.LENGTH_LONG
).show()
mergeDb()
} else {
Toast.makeText(
this@MergeOfflineRegionsActivity,
String.format("Error copying DB file."),
Toast.LENGTH_LONG
).show()
}
}
}
}
private fun mergeDb() {

View File

@@ -47,7 +47,7 @@ class UpdateMetadataActivity :
val input = EditText(this)
input.setText(metadata)
input.inputType = InputType.TYPE_CLASS_TEXT
if (metadata != null) {
if (metadata.isNotEmpty()) {
input.setSelection(metadata.length)
}
builder.setView(input)
@@ -113,7 +113,7 @@ class UpdateMetadataActivity :
OfflineManager.getInstance(this).listOfflineRegions(object : ListOfflineRegionsCallback {
override fun onList(offlineRegions: Array<OfflineRegion>?) {
if (offlineRegions != null && offlineRegions.size > 0) {
adapter!!.setOfflineRegions(Arrays.asList(*offlineRegions))
adapter!!.setOfflineRegions(listOf(*offlineRegions))
}
}
@@ -129,7 +129,7 @@ class UpdateMetadataActivity :
override fun onDestroy() {
super.onDestroy()
if (mapView != null) {
if (this::mapView.isInitialized) {
mapView.onPause()
mapView.onStop()
mapView.onDestroy()
@@ -172,7 +172,7 @@ class UpdateMetadataActivity :
return convertView!!
}
internal class ViewHolder {
class ViewHolder {
var text: TextView? = null
}

View File

@@ -2,7 +2,6 @@ package org.maplibre.android.testapp.activity.render
import android.content.res.AssetManager
import android.graphics.Bitmap
import android.os.AsyncTask
import android.os.Bundle
import android.os.Environment
import android.view.Gravity
@@ -10,8 +9,12 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.google.gson.Gson
import com.google.gson.JsonObject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.maplibre.android.snapshotter.MapSnapshot
import org.maplibre.android.snapshotter.MapSnapshotter
import okio.buffer
@@ -20,7 +23,6 @@ import timber.log.Timber
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.lang.ref.WeakReference
import java.nio.charset.Charset
/**
@@ -50,91 +52,58 @@ class RenderTestActivity : AppCompatActivity() {
//
// Loads the ignore tests from assets folder
//
private class LoadRenderIgnoreTask internal constructor(renderTestActivity: RenderTestActivity?) :
AsyncTask<Void?, Void?, List<String>>() {
private val renderTestActivityWeakReference: WeakReference<RenderTestActivity?>
protected override fun doInBackground(vararg p0: Void?): List<String>? {
return loadIgnoreList(
renderTestActivityWeakReference.get()!!.assets
)
}
override fun onPostExecute(strings: List<String>) {
super.onPostExecute(strings)
if (renderTestActivityWeakReference.get() != null) {
renderTestActivityWeakReference.get()!!.onLoadIgnoreList(strings)
}
}
init {
renderTestActivityWeakReference = WeakReference(renderTestActivity)
}
}
private fun loadRenderIgnoreTask(renderTestActivity: RenderTestActivity) : List<String> = loadIgnoreList(renderTestActivity.assets)
//
// Loads the render test definitions from assets folder
//
private class LoadRenderDefinitionTask internal constructor(renderTestActivity: RenderTestActivity) :
AsyncTask<Void?, Void?, List<RenderTestDefinition>>() {
private val renderTestActivityWeakReference: WeakReference<RenderTestActivity>
protected override fun doInBackground(vararg p0: Void?): List<RenderTestDefinition>? {
val definitions: MutableList<RenderTestDefinition> = ArrayList()
val assetManager = renderTestActivityWeakReference.get()!!.assets
val categories =
try {
assetManager.list(RENDER_TEST_BASE_PATH)
} catch (exception: IOException) {
Timber.e(exception)
throw exception
}
private fun loadRenderDefinitionTask(renderTestActivity: RenderTestActivity) : List<RenderTestDefinition> {
val definitions: MutableList<RenderTestDefinition> = ArrayList()
val assetManager = renderTestActivity.assets
val categories =
try {
assetManager.list(RENDER_TEST_BASE_PATH)
} catch (exception: IOException) {
Timber.e(exception)
throw exception
}
for (counter in categories!!.indices.reversed()) {
try {
val tests = assetManager.list(
String.format(
"%s/%s",
RENDER_TEST_BASE_PATH,
for (counter in categories!!.indices.reversed()) {
try {
val tests = assetManager.list(
String.format(
"%s/%s",
RENDER_TEST_BASE_PATH,
categories[counter]
)
)
for (test in tests!!) {
val styleJson = loadStyleJson(assetManager, categories[counter], test)
val renderTestStyleDefinition = Gson()
.fromJson(styleJson, RenderTestStyleDefinition::class.java)
val definition = RenderTestDefinition(
categories[counter],
test,
styleJson,
renderTestStyleDefinition
)
if (!definition.hasOperations()) {
if (!EXCLUDED_TESTS.contains(definition.name + "," + definition.category)) {
definitions.add(definition)
}
} else {
Timber.e(
"could not add test, test requires operations: %s from %s",
test,
categories[counter]
)
)
for (test in tests!!) {
val styleJson = loadStyleJson(assetManager, categories[counter], test)
val renderTestStyleDefinition = Gson()
.fromJson(styleJson, RenderTestStyleDefinition::class.java)
val definition = RenderTestDefinition(
categories[counter],
test,
styleJson,
renderTestStyleDefinition
)
if (!definition.hasOperations()) {
if (!EXCLUDED_TESTS.contains(definition.name + "," + definition.category)) {
definitions.add(definition)
}
} else {
Timber.e(
"could not add test, test requires operations: %s from %s",
test,
categories[counter]
)
}
}
} catch (exception: Exception) {
Timber.e(exception)
}
} catch (exception: Exception) {
Timber.e(exception)
}
return definitions
}
override fun onPostExecute(renderTestDefinitions: List<RenderTestDefinition>) {
super.onPostExecute(renderTestDefinitions)
val renderTestActivity = renderTestActivityWeakReference.get()
renderTestActivity?.startRenderTests(renderTestDefinitions)
}
init {
renderTestActivityWeakReference = WeakReference(renderTestActivity)
}
return definitions
}
private fun startRenderTests(renderTestDefinitions: List<RenderTestDefinition>) {
@@ -177,53 +146,49 @@ class RenderTestActivity : AppCompatActivity() {
}
private fun finishTesting() {
SaveResultToDiskTask(onRenderTestCompletionListener, renderResultMap).execute()
lifecycleScope.launch(Dispatchers.IO) {
saveResultToDiskTask(renderResultMap)
withContext(Dispatchers.Main) {
onRenderTestCompletionListener?.onFinish()
}
}
}
//
// Save tests results to disk
//
private class SaveResultToDiskTask internal constructor(
private val onRenderTestCompletionListener: OnRenderTestCompletionListener?,
private val renderResultMap: Map<RenderTestDefinition, Bitmap>
) : AsyncTask<Void?, Void?, Void?>() {
protected override fun doInBackground(vararg p0: Void?): Void? {
if (isExternalStorageWritable) {
try {
val testResultDir = FileUtils.createTestResultRootFolder()
val basePath = testResultDir.absolutePath
for (testResult in renderResultMap.entries) {
writeResultToDisk(basePath, testResult)
}
} catch (exception: Exception) {
Timber.e(exception)
private fun saveResultToDiskTask(
renderResultMap: Map<RenderTestDefinition, Bitmap>
) {
if (isExternalStorageWritable) {
try {
val testResultDir = FileUtils.createTestResultRootFolder()
val basePath = testResultDir.absolutePath
for (testResult in renderResultMap.entries) {
writeResultToDisk(basePath, testResult)
}
} catch (exception: Exception) {
Timber.e(exception)
}
return null
}
private fun writeResultToDisk(
path: String,
result: Map.Entry<RenderTestDefinition, Bitmap>
) {
val definition = result.key
val categoryName = definition.category
val categoryPath = String.format("%s/%s", path, categoryName)
FileUtils.createCategoryDirectory(categoryPath)
val testName = result.key.name
val testDir = FileUtils.createTestDirectory(categoryPath, testName)
FileUtils.writeTestResultToDisk(testDir, result.value)
}
private val isExternalStorageWritable: Boolean
private get() = Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()
override fun onPostExecute(aVoid: Void?) {
super.onPostExecute(aVoid)
onRenderTestCompletionListener?.onFinish()
}
}
private fun writeResultToDisk(
path: String,
result: Map.Entry<RenderTestDefinition, Bitmap>
) {
val definition = result.key
val categoryName = definition.category
val categoryPath = String.format("%s/%s", path, categoryName)
FileUtils.createCategoryDirectory(categoryPath)
val testName = result.key.name
val testDir = FileUtils.createTestDirectory(categoryPath, testName)
FileUtils.writeTestResultToDisk(testDir, result.value)
}
private val isExternalStorageWritable: Boolean
get() = Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()
//
// Callback configuration to notify test executor of test finishing
//
@@ -233,13 +198,23 @@ class RenderTestActivity : AppCompatActivity() {
fun setOnRenderTestCompletionListener(listener: OnRenderTestCompletionListener?) {
onRenderTestCompletionListener = listener
LoadRenderIgnoreTask(this).execute()
lifecycleScope.launch(Dispatchers.IO) {
val ignored = loadRenderIgnoreTask(this@RenderTestActivity)
withContext(Dispatchers.Main) {
onLoadIgnoreList(ignored)
}
}
}
fun onLoadIgnoreList(ignoreList: List<String>) {
Timber.e("We loaded %s of tests to be ignored", ignoreList.size)
EXCLUDED_TESTS.addAll(ignoreList)
LoadRenderDefinitionTask(this).execute()
lifecycleScope.launch(Dispatchers.IO) {
val definitions = loadRenderDefinitionTask(this@RenderTestActivity)
withContext(Dispatchers.Main) {
startRenderTests(definitions)
}
}
}
//

View File

@@ -141,7 +141,7 @@ class MapSnapshotterActivity : AppCompatActivity() {
builder.withSource(source)
} else if (row == 0 && column == 2) {
val carBitmap = BitmapUtils.getBitmapFromDrawable(
ResourcesCompat.getDrawable(resources, R.drawable.ic_directions_car_black, null)
ResourcesCompat.getDrawable(resources, R.drawable.ic_directions_car_black, theme)
)
// marker source
@@ -207,7 +207,7 @@ class MapSnapshotterActivity : AppCompatActivity() {
override fun onStyleImageMissing(imageName: String) {
val androidIcon =
BitmapUtils.getBitmapFromDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_android_2, null))
BitmapUtils.getBitmapFromDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_android_2, theme))
snapshotter.addImage(imageName, androidIcon!!, false)
}
})

View File

@@ -18,7 +18,6 @@ import org.maplibre.geojson.Point
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.style.expressions.Expression
import org.maplibre.android.style.layers.PropertyFactory
@@ -48,17 +47,15 @@ class AnimatedSymbolLayerActivity : AppCompatActivity() {
setContentView(R.layout.activity_animated_marker)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { map: MapLibreMap ->
maplibreMap = map
map.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style? ->
this.style = style
setupCars()
animateRandomRoutes()
animateTaxi()
}
mapView.getMapAsync {
maplibreMap = it
it.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style? ->
this.style = style
setupCars()
animateRandomRoutes()
animateTaxi()
}
)
}
}
private fun setupCars() {
@@ -171,7 +168,7 @@ class AnimatedSymbolLayerActivity : AppCompatActivity() {
}
private val longestDrive: Car?
private get() {
get() {
var longestDrive: Car? = null
for (randomCar in randomCars) {
if (longestDrive == null) {
@@ -199,7 +196,7 @@ class AnimatedSymbolLayerActivity : AppCompatActivity() {
}
private val duration: Long
private get() = (random.nextInt(DURATION_RANDOM_MAX) + DURATION_BASE).toLong()
get() = (random.nextInt(DURATION_RANDOM_MAX) + DURATION_BASE).toLong()
private fun addRandomCars() {
var latLng: LatLng
@@ -224,7 +221,7 @@ class AnimatedSymbolLayerActivity : AppCompatActivity() {
style!!.addSource(randomCarSource!!)
style!!.addImage(
RANDOM_CAR_IMAGE_ID,
(ResourcesCompat.getDrawable(resources, R.drawable.ic_car_top, null) as BitmapDrawable).bitmap
(ResourcesCompat.getDrawable(resources, R.drawable.ic_car_top, theme) as BitmapDrawable).bitmap
)
val symbolLayer = SymbolLayer(RANDOM_CAR_LAYER, RANDOM_CAR_SOURCE)
symbolLayer.withProperties(
@@ -250,7 +247,7 @@ class AnimatedSymbolLayerActivity : AppCompatActivity() {
)
style!!.addImage(
PASSENGER,
(ResourcesCompat.getDrawable(resources, R.drawable.icon_burned, null) as BitmapDrawable).bitmap
(ResourcesCompat.getDrawable(resources, R.drawable.icon_burned, theme) as BitmapDrawable).bitmap
)
val geoJsonSource = GeoJsonSource(PASSENGER_SOURCE, featureCollection)
style!!.addSource(geoJsonSource)
@@ -278,7 +275,7 @@ class AnimatedSymbolLayerActivity : AppCompatActivity() {
taxi = Car(feature, passenger, duration)
style!!.addImage(
TAXI,
(ResourcesCompat.getDrawable(resources, R.drawable.ic_taxi_top, null) as BitmapDrawable).bitmap
(ResourcesCompat.getDrawable(resources, R.drawable.ic_taxi_top, theme) as BitmapDrawable).bitmap
)
taxiSource = GeoJsonSource(TAXI_SOURCE, featureCollection)
style!!.addSource(taxiSource!!)
@@ -328,11 +325,9 @@ class AnimatedSymbolLayerActivity : AppCompatActivity() {
override fun onDestroy() {
super.onDestroy()
for (animator in animators) {
if (animator != null) {
animator.removeAllListeners()
animator.cancel()
}
animators.forEach {
it.removeAllListeners()
it.cancel()
}
mapView.onDestroy()
}
@@ -354,7 +349,7 @@ class AnimatedSymbolLayerActivity : AppCompatActivity() {
}
}
private class Car internal constructor(var feature: Feature, next: LatLng?, duration: Long) {
private class Car(var feature: Feature, next: LatLng?, duration: Long) {
var next: LatLng?
var current: LatLng?
val duration: Long

View File

@@ -13,7 +13,6 @@ import org.maplibre.android.camera.CameraUpdateFactory
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.style.layers.Layer
import org.maplibre.android.style.layers.PropertyFactory
@@ -36,81 +35,79 @@ class CustomSpriteActivity : AppCompatActivity() {
setContentView(R.layout.activity_add_sprite)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { map: MapLibreMap ->
maplibreMap = map
map.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style ->
val fab = findViewById<FloatingActionButton>(R.id.fab)
fab.setColorFilter(
ContextCompat.getColor(
this@CustomSpriteActivity,
R.color.primary
)
mapView.getMapAsync {
maplibreMap = it
it.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style ->
val fab = findViewById<FloatingActionButton>(R.id.fab)
fab.setColorFilter(
ContextCompat.getColor(
this@CustomSpriteActivity,
R.color.primary
)
fab.setOnClickListener(object : View.OnClickListener {
private lateinit var point: Point
override fun onClick(view: View) {
if (point == null) {
Timber.i("First click -> Car")
// Add an icon to reference later
style.addImage(
CUSTOM_ICON,
BitmapFactory.decodeResource(
resources,
R.drawable.ic_car_top
)
)
fab.setOnClickListener(object : View.OnClickListener {
private lateinit var point: Point
override fun onClick(view: View) {
if (!this::point.isInitialized) {
Timber.i("First click -> Car")
// Add an icon to reference later
style.addImage(
CUSTOM_ICON,
BitmapFactory.decodeResource(
resources,
R.drawable.ic_car_top
)
)
// Add a source with a geojson point
point = Point.fromLngLat(13.400972, 52.519003)
source = GeoJsonSource(
"point",
FeatureCollection.fromFeatures(arrayOf(Feature.fromGeometry(point)))
)
maplibreMap.style!!.addSource(source!!)
// Add a source with a geojson point
point = Point.fromLngLat(13.400972, 52.519003)
source = GeoJsonSource(
"point",
FeatureCollection.fromFeatures(arrayOf(Feature.fromGeometry(point)))
)
maplibreMap.style!!.addSource(source!!)
// Add a symbol layer that references that point source
layer = SymbolLayer("layer", "point")
layer.setProperties( // Set the id of the sprite to use
PropertyFactory.iconImage(CUSTOM_ICON),
PropertyFactory.iconAllowOverlap(true),
PropertyFactory.iconIgnorePlacement(true)
)
// Add a symbol layer that references that point source
layer = SymbolLayer("layer", "point")
layer.setProperties( // Set the id of the sprite to use
PropertyFactory.iconImage(CUSTOM_ICON),
PropertyFactory.iconAllowOverlap(true),
PropertyFactory.iconIgnorePlacement(true)
)
// lets add a circle below labels!
maplibreMap.style!!.addLayerBelow(layer, "water_intermittent")
fab.setImageResource(R.drawable.ic_directions_car_black)
} else {
// Update point
point = Point.fromLngLat(
point!!.longitude() + 0.001,
point!!.latitude() + 0.001
)
source!!.setGeoJson(
FeatureCollection.fromFeatures(
arrayOf(
Feature.fromGeometry(
point
)
// lets add a circle below labels!
maplibreMap.style!!.addLayerBelow(layer, "water_intermittent")
fab.setImageResource(R.drawable.ic_directions_car_black)
} else {
// Update point
point = Point.fromLngLat(
point.longitude() + 0.001,
point.latitude() + 0.001
)
source!!.setGeoJson(
FeatureCollection.fromFeatures(
arrayOf(
Feature.fromGeometry(
point
)
)
)
)
// Move the camera as well
maplibreMap.moveCamera(
CameraUpdateFactory.newLatLng(
LatLng(
point.latitude(),
point.longitude()
)
// Move the camera as well
maplibreMap.moveCamera(
CameraUpdateFactory.newLatLng(
LatLng(
point.latitude(),
point.longitude()
)
)
}
)
}
})
}
}
})
}
)
}
}
override fun onStart() {

View File

@@ -12,7 +12,6 @@ import org.maplibre.android.camera.CameraUpdateFactory
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.style.expressions.Expression
import org.maplibre.android.style.layers.FillLayer
@@ -40,29 +39,25 @@ class DataDrivenStyleActivity : AppCompatActivity() {
// Initialize map as normal
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { map: MapLibreMap? ->
// Store for later
if (map != null) {
maplibreMap = map
}
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style? ->
// Add a parks layer
addParksLayer()
mapView.getMapAsync {
// Store for later
maplibreMap = it
it.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style? ->
// Add a parks layer
addParksLayer()
// Add debug overlay
setupDebugZoomView()
}
// Center and Zoom (Amsterdam, zoomed to streets)
maplibreMap.animateCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(52.379189, 4.899431),
14.0
)
)
// Add debug overlay
setupDebugZoomView()
}
)
// Center and Zoom (Amsterdam, zoomed to streets)
it.animateCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(52.379189, 4.899431),
14.0
)
)
}
}
private fun setupDebugZoomView() {
@@ -107,7 +102,7 @@ class DataDrivenStyleActivity : AppCompatActivity() {
override fun onDestroy() {
super.onDestroy()
if (maplibreMap != null && idleListener != null) {
if (this::maplibreMap.isInitialized && idleListener != null) {
maplibreMap.removeOnCameraIdleListener(idleListener!!)
}
mapView.onDestroy()

View File

@@ -336,9 +336,7 @@ class DraggableMarkerActivity : AppCompatActivity() {
override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
super.onSaveInstanceState(outState, outPersistentState)
outState?.let {
mapView.onSaveInstanceState(it)
}
mapView.onSaveInstanceState(outState)
}
}

View File

@@ -13,7 +13,6 @@ import org.maplibre.android.camera.CameraUpdateFactory
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.style.expressions.Expression
import org.maplibre.android.style.layers.CircleLayer
@@ -27,7 +26,6 @@ import org.maplibre.android.utils.BitmapUtils
import timber.log.Timber
import java.net.URI
import java.net.URISyntaxException
import java.util.Objects
/**
* Test activity showcasing using a geojson source and visualise that source as a cluster by using filters.
@@ -45,68 +43,68 @@ class GeoJsonClusteringActivity : AppCompatActivity() {
mapView = findViewById(R.id.mapView)
// noinspection ConstantConditions
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { map: MapLibreMap? ->
if (map != null) {
maplibreMap = map
}
maplibreMap.animateCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(37.7749, 122.4194),
0.0
mapView.getMapAsync {
maplibreMap = it
maplibreMap.animateCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(37.7749, 122.4194),
0.0
)
)
val clusterLayers = arrayOf(
intArrayOf(
150,
ResourcesCompat.getColor(
resources,
R.color.redAccent,
theme
)
),
intArrayOf(20, ResourcesCompat.getColor(resources, R.color.greenAccent, theme)),
intArrayOf(
0,
ResourcesCompat.getColor(
resources,
R.color.blueAccent,
theme
)
)
val clusterLayers = arrayOf(
intArrayOf(
150,
ResourcesCompat.getColor(
resources,
R.color.redAccent,
theme
)
try {
maplibreMap.setStyle(
Style.Builder()
.fromUri(TestStyles.getPredefinedStyleWithFallback("Bright"))
.withSource(createClusterSource().also { clusterSource = it })
.withLayer(createSymbolLayer())
.withLayer(createClusterLevelLayer(0, clusterLayers))
.withLayer(createClusterLevelLayer(1, clusterLayers))
.withLayer(createClusterLevelLayer(2, clusterLayers))
.withLayer(createClusterTextLayer())
.withImage(
"icon-id",
BitmapUtils.getBitmapFromDrawable(
ResourcesCompat.getDrawable(
resources,
R.drawable.ic_hearing_black_24dp,
theme
)
)!!,
true
)
),
intArrayOf(20, ResourcesCompat.getColor(resources, R.color.greenAccent, theme)),
intArrayOf(
0,
ResourcesCompat.getColor(
resources,
R.color.blueAccent,
theme
)
)
)
try {
maplibreMap.setStyle(
Style.Builder()
.fromUri(TestStyles.getPredefinedStyleWithFallback("Bright"))
.withSource(createClusterSource().also { clusterSource = it })
.withLayer(createSymbolLayer())
.withLayer(createClusterLevelLayer(0, clusterLayers))
.withLayer(createClusterLevelLayer(1, clusterLayers))
.withLayer(createClusterLevelLayer(2, clusterLayers))
.withLayer(createClusterTextLayer())
.withImage(
"icon-id",
Objects.requireNonNull(
BitmapUtils.getBitmapFromDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_hearing_black_24dp, null))
)!!,
true
)
)
} catch (exception: URISyntaxException) {
Timber.e(exception)
}
maplibreMap.addOnMapClickListener { latLng: LatLng? ->
val point = maplibreMap.projection.toScreenLocation(latLng!!)
val features =
maplibreMap.queryRenderedFeatures(point, "cluster-0", "cluster-1", "cluster-2")
if (!features.isEmpty()) {
onClusterClick(features[0], Point(point.x.toInt(), point.y.toInt()))
}
true
}
} catch (exception: URISyntaxException) {
Timber.e(exception)
}
)
maplibreMap.addOnMapClickListener { latLng: LatLng? ->
val point = maplibreMap.projection.toScreenLocation(latLng!!)
val features =
maplibreMap.queryRenderedFeatures(point, "cluster-0", "cluster-1", "cluster-2")
if (!features.isEmpty()) {
onClusterClick(features[0], Point(point.x.toInt(), point.y.toInt()))
}
true
}
}
findViewById<View>(R.id.fab).setOnClickListener { v: View? ->
updateClickOptionCounter()
notifyClickOptionUpdate()
@@ -266,7 +264,7 @@ class GeoJsonClusteringActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
true
}

View File

@@ -17,6 +17,8 @@ import org.maplibre.android.style.sources.CustomGeometrySource
import org.maplibre.android.style.sources.GeometryTileProvider
import org.maplibre.android.testapp.R
import java.util.*
import kotlin.math.ceil
import kotlin.math.floor
/**
* Test activity showcasing using CustomGeometrySource to create a grid overlay on the map.
@@ -56,30 +58,30 @@ class GridSourceActivity : AppCompatActivity(), OnMapReadyCallback {
} else {
20.0
}
var gridLines: MutableList<Any?> = ArrayList<Any?>()
var y = Math.ceil(bounds.latitudeNorth / gridSpacing) * gridSpacing
while (y >= Math.floor(bounds.latitudeSouth / gridSpacing) * gridSpacing) {
var gridLines: MutableList<List<Point>> = mutableListOf()
var y = ceil(bounds.latitudeNorth / gridSpacing) * gridSpacing
while (y >= floor(bounds.latitudeSouth / gridSpacing) * gridSpacing) {
gridLines.add(
Arrays.asList(
listOf(
Point.fromLngLat(bounds.longitudeWest, y),
Point.fromLngLat(bounds.longitudeEast, y)
)
)
y -= gridSpacing
}
features.add(Feature.fromGeometry(MultiLineString.fromLngLats(gridLines as MutableList<MutableList<Point>>)))
gridLines = ArrayList<Any?>()
var x = Math.floor(bounds.longitudeWest / gridSpacing) * gridSpacing
while (x <= Math.ceil(bounds.longitudeEast / gridSpacing) * gridSpacing) {
features.add(Feature.fromGeometry(MultiLineString.fromLngLats(gridLines)))
gridLines = mutableListOf()
var x = floor(bounds.longitudeWest / gridSpacing) * gridSpacing
while (x <= ceil(bounds.longitudeEast / gridSpacing) * gridSpacing) {
gridLines.add(
Arrays.asList(
listOf(
Point.fromLngLat(x, bounds.latitudeSouth),
Point.fromLngLat(x, bounds.latitudeNorth)
)
)
x += gridSpacing
}
features.add(Feature.fromGeometry(MultiLineString.fromLngLats(gridLines as MutableList<MutableList<Point>>)))
features.add(Feature.fromGeometry(MultiLineString.fromLngLats(gridLines)))
return FeatureCollection.fromFeatures(features)
}
}

View File

@@ -3,6 +3,7 @@ package org.maplibre.android.testapp.activity.style
import android.graphics.Color
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
import org.maplibre.geojson.Feature
import org.maplibre.geojson.FeatureCollection
import org.maplibre.geojson.Point
@@ -35,10 +36,11 @@ class ImageInLabelActivity : AppCompatActivity(), OnMapReadyCallback {
override fun onMapReady(maplibreMap: MapLibreMap) {
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style ->
val us = BitmapUtils.getBitmapFromDrawable(
resources.getDrawable(R.drawable.ic_us)
ResourcesCompat.getDrawable(resources, R.drawable.ic_us, theme)
)
val android = BitmapUtils.getBitmapFromDrawable(
ResourcesCompat.getDrawable(resources, R.drawable.ic_android, theme)
)
val android =
BitmapUtils.getBitmapFromDrawable(resources.getDrawable(R.drawable.ic_android))
style.addImage("us", us!!)
style.addImage("android", android!!)
val point = Point.fromLngLat(-10.0, 0.0)

View File

@@ -16,7 +16,6 @@ import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.MapLibreMap.CancelableCallback
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.style.expressions.Expression
import org.maplibre.android.style.layers.CircleLayer
@@ -38,8 +37,6 @@ import org.maplibre.android.testapp.styles.TestStyles
import org.maplibre.android.testapp.utils.ResourceUtils
import timber.log.Timber
import java.io.IOException
import java.util.Arrays
import java.util.Collections
/**
* Test activity showcasing the runtime style API.
@@ -48,8 +45,8 @@ class RuntimeStyleActivity : AppCompatActivity() {
private lateinit var mapView: MapView
private lateinit var maplibreMap: MapLibreMap
private var styleLoaded = false
var lngLats = listOf(
Arrays.asList(
private var lngLats = listOf(
listOf(
Point.fromLngLat(
-15.468749999999998,
41.77131167976407
@@ -80,39 +77,34 @@ class RuntimeStyleActivity : AppCompatActivity() {
// Initialize map as normal
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { map: MapLibreMap? ->
// Store for later
if (map != null) {
maplibreMap = map
}
mapView.getMapAsync {
// Store for later
maplibreMap = it
// Center and Zoom (Amsterdam, zoomed to streets)
maplibreMap.animateCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(52.379189, 4.899431),
1.0
)
// Center and Zoom (Amsterdam, zoomed to streets)
maplibreMap.animateCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(52.379189, 4.899431),
1.0
)
maplibreMap.setStyle(
Style.Builder()
.fromUri(TestStyles.getPredefinedStyleWithFallback("Streets")) // set custom transition
.withTransition(TransitionOptions(250, 50))
) { style: Style ->
styleLoaded = true
val laber = style.getLayer("country_1") as SymbolLayer?
laber!!.setProperties(
PropertyFactory.textOpacity(
Expression.switchCase(
Expression.within(polygon),
Expression.literal(1.0f),
Expression.literal(0.5f)
)
)
maplibreMap.setStyle(
Style.Builder()
.fromUri(TestStyles.getPredefinedStyleWithFallback("Streets")) // set custom transition
.withTransition(TransitionOptions(250, 50))
) { style: Style ->
styleLoaded = true
style.getLayer("country_1")?.setProperties(
PropertyFactory.textOpacity(
Expression.switchCase(
Expression.within(polygon),
Expression.literal(1.0f),
Expression.literal(0.5f)
)
)
}
)
}
)
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@@ -337,8 +329,7 @@ class RuntimeStyleActivity : AppCompatActivity() {
private fun addParksLayer() {
// Add a source
val source: Source
source = try {
val source: Source = try {
GeoJsonSource("amsterdam-spots", ResourceUtils.readRawResource(this, R.raw.amsterdam))
} catch (ioException: IOException) {
Toast.makeText(
@@ -391,8 +382,7 @@ class RuntimeStyleActivity : AppCompatActivity() {
private fun addDynamicParksLayer() {
// Load some data
val parks: FeatureCollection
parks = try {
val parks: FeatureCollection = try {
val json = ResourceUtils.readRawResource(this, R.raw.amsterdam)
FeatureCollection.fromJson(json)
} catch (ioException: IOException) {
@@ -436,7 +426,7 @@ class RuntimeStyleActivity : AppCompatActivity() {
val handler = Handler(mainLooper)
handler.postDelayed(
{
if (maplibreMap == null) {
if (!this::maplibreMap.isInitialized) {
return@postDelayed
}
Timber.d("Updating parks source")
@@ -477,7 +467,7 @@ class RuntimeStyleActivity : AppCompatActivity() {
val layers = maplibreMap.style!!
.layers
var latestLayer: Layer? = null
Collections.reverse(layers)
layers.reverse()
for (currentLayer in layers) {
if (currentLayer is FillLayer && currentLayer.sourceLayer == "road") {
latestLayer = currentLayer
@@ -584,7 +574,7 @@ class RuntimeStyleActivity : AppCompatActivity() {
val handler = Handler(mainLooper)
handler.postDelayed(
{
if (maplibreMap == null) {
if (!this::maplibreMap.isInitialized) {
return@postDelayed
}
Timber.d("Styling filtered fill layer")
@@ -620,7 +610,7 @@ class RuntimeStyleActivity : AppCompatActivity() {
val handler = Handler(mainLooper)
handler.postDelayed(
{
if (maplibreMap == null) {
if (!this::maplibreMap.isInitialized) {
return@postDelayed
}
Timber.d("Styling text size fill layer")
@@ -658,7 +648,7 @@ class RuntimeStyleActivity : AppCompatActivity() {
val handler = Handler(mainLooper)
handler.postDelayed(
{
if (maplibreMap == null) {
if (!this::maplibreMap.isInitialized) {
return@postDelayed
}
Timber.d("Styling filtered line layer")
@@ -688,7 +678,7 @@ class RuntimeStyleActivity : AppCompatActivity() {
val handler = Handler(mainLooper)
handler.postDelayed(
{
if (maplibreMap == null) {
if (!this::maplibreMap.isInitialized) {
return@postDelayed
}
Timber.d("Styling numeric fill layer")

View File

@@ -1,8 +1,12 @@
package org.maplibre.android.testapp.activity.style
import android.os.AsyncTask
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.maplibre.geojson.Feature
import org.maplibre.geojson.FeatureCollection
import org.maplibre.geojson.Point
@@ -16,7 +20,6 @@ import org.maplibre.android.testapp.utils.GeoParseUtil
import org.maplibre.android.utils.BitmapUtils
import timber.log.Timber
import java.io.IOException
import java.lang.ref.WeakReference
import java.util.ArrayList
/**
@@ -37,10 +40,11 @@ class StretchableImageActivity : AppCompatActivity(), OnMapReadyCallback {
this.maplibreMap = maplibreMap
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style ->
val popup = BitmapUtils.getBitmapFromDrawable(
resources.getDrawable(R.drawable.popup)
ResourcesCompat.getDrawable(resources, R.drawable.popup, theme)
)
val popupDebug = BitmapUtils.getBitmapFromDrawable(
ResourcesCompat.getDrawable(resources, R.drawable.popup_debug, theme)
)
val popupDebug =
BitmapUtils.getBitmapFromDrawable(resources.getDrawable(R.drawable.popup_debug))
// The two (blue) columns of pixels that can be stretched horizontally:
// - the pixels between x: 25 and x: 55 can be stretched
@@ -58,7 +62,12 @@ class StretchableImageActivity : AppCompatActivity(), OnMapReadyCallback {
val content = ImageContent(25F, 25F, 115F, 100F)
style.addImage(NAME_POPUP, popup!!, stretchX, stretchY, content)
style.addImage(NAME_POPUP_DEBUG, popupDebug!!, stretchX, stretchY, content)
LoadFeatureTask(this@StretchableImageActivity).execute()
lifecycleScope.launch(Dispatchers.IO) {
val feature = loadFeatureTask(this@StretchableImageActivity)
withContext(Dispatchers.Main) {
onFeatureLoaded(feature)
}
}
}
}
@@ -93,35 +102,16 @@ class StretchableImageActivity : AppCompatActivity(), OnMapReadyCallback {
}
}
private class LoadFeatureTask(activity: StretchableImageActivity) :
AsyncTask<Void?, Int?, String?>() {
private val activity: WeakReference<StretchableImageActivity>
protected override fun doInBackground(vararg p0: Void?): String? {
val activity = activity.get()
if (activity != null) {
var json: String? = null
try {
json = GeoParseUtil.loadStringFromAssets(
activity.applicationContext,
"stretchable_image.geojson"
)
} catch (exception: IOException) {
Timber.e(exception, "Could not read feature")
}
return json
}
return null
}
override fun onPostExecute(json: String?) {
super.onPostExecute(json)
val activity = activity.get()
activity?.onFeatureLoaded(json)
}
init {
this.activity = WeakReference(activity)
private fun loadFeatureTask(activity: StretchableImageActivity) : String? {
try {
return GeoParseUtil.loadStringFromAssets(
activity.applicationContext,
"stretchable_image.geojson"
)
} catch (exception: IOException) {
Timber.e(exception, "Could not read feature")
}
return null
}
override fun onStart() {

View File

@@ -1,16 +1,18 @@
package org.maplibre.android.testapp.activity.style
import android.content.Context
import android.os.AsyncTask
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.google.android.material.floatingactionbutton.FloatingActionButton
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
@@ -19,7 +21,6 @@ import timber.log.Timber
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.lang.ref.WeakReference
/**
* Test activity showcasing how to use a file:// resource for the style.json and how to use MapLibreMap#setStyleJson.
@@ -32,121 +33,86 @@ class StyleFileActivity : AppCompatActivity() {
setContentView(R.layout.activity_style_file)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { map: MapLibreMap? ->
if (map != null) {
maplibreMap = map
}
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style? ->
val fab = findViewById<FloatingActionButton>(R.id.fab_file)
fab.setColorFilter(ContextCompat.getColor(this@StyleFileActivity, R.color.primary))
fab.setOnClickListener { view: View ->
CreateStyleFileTask(
view.context,
maplibreMap
).execute()
mapView.getMapAsync {
maplibreMap = it
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style? ->
val fab = findViewById<FloatingActionButton>(R.id.fab_file)
fab.setColorFilter(ContextCompat.getColor(this@StyleFileActivity, R.color.primary))
fab.setOnClickListener { view: View ->
lifecycleScope.launch(Dispatchers.IO) {
val cacheStylePath = createStyleFileTask(view.context)
withContext(Dispatchers.Main) {
cacheStylePath?.let {
maplibreMap.setStyle(
Style.Builder().fromUri("file://$it")
)
}
}
}
val fabStyleJson = findViewById<FloatingActionButton>(R.id.fab_style_json)
fabStyleJson.setColorFilter(
ContextCompat.getColor(
this@StyleFileActivity,
R.color.primary
)
}
val fabStyleJson = findViewById<FloatingActionButton>(R.id.fab_style_json)
fabStyleJson.setColorFilter(
ContextCompat.getColor(
this@StyleFileActivity,
R.color.primary
)
fabStyleJson.setOnClickListener { view: View ->
LoadStyleFileTask(
view.context,
maplibreMap
).execute()
)
fabStyleJson.setOnClickListener { view: View ->
lifecycleScope.launch(Dispatchers.IO) {
val json = loadStyleFileTask(view.context)
withContext(Dispatchers.Main) {
Timber.d("Read json, %s", json)
maplibreMap.setStyle(Style.Builder().fromJson(json))
}
}
}
}
)
}
}
/**
* Task to read a style file from the raw folder
*/
private class LoadStyleFileTask internal constructor(context: Context, maplibreMap: MapLibreMap?) :
AsyncTask<Void?, Void?, String>() {
private val context: WeakReference<Context>
private val maplibreMap: WeakReference<MapLibreMap?>
protected override fun doInBackground(vararg p0: Void?): String? {
var styleJson = ""
try {
styleJson = ResourceUtils.readRawResource(context.get(), R.raw.sat_style)
} catch (exception: Exception) {
Timber.e(exception, "Can't load local file style")
}
return styleJson
private fun loadStyleFileTask(context: Context): String =
try {
ResourceUtils.readRawResource(context, R.raw.sat_style)
} catch (exception: Exception) {
Timber.e(exception, "Can't load local file style")
""
}
override fun onPostExecute(json: String) {
super.onPostExecute(json)
Timber.d("Read json, %s", json)
val maplibreMap = maplibreMap.get()
maplibreMap?.setStyle(Style.Builder().fromJson(json))
}
init {
this.context = WeakReference(context)
this.maplibreMap = WeakReference(maplibreMap)
}
}
/**
* Task to write a style file to local disk and load it in the map view
*/
private class CreateStyleFileTask internal constructor(
private fun createStyleFileTask(
context: Context,
maplibreMap: MapLibreMap?
) : AsyncTask<Void?, Int?, Long>() {
private lateinit var cacheStyleFile: File
private val context: WeakReference<Context>
private val maplibreMap: WeakReference<MapLibreMap?>
protected override fun doInBackground(vararg p0: Void?): Long? {
try {
cacheStyleFile = File.createTempFile("my-", ".style.json")
cacheStyleFile.createNewFile()
Timber.i("Writing style file to: %s", cacheStyleFile.getAbsolutePath())
val context = context.get()
if (context != null) {
writeToFile(
cacheStyleFile,
ResourceUtils.readRawResource(context, R.raw.local_style)
)
}
} catch (exception: Exception) {
Toast.makeText(
context.get(),
"Could not create style file in cache dir",
Toast.LENGTH_SHORT
).show()
}
return 1L
}
override fun onPostExecute(result: Long) {
// Actual file:// usage
val maplibreMap = maplibreMap.get()
maplibreMap?.setStyle(
Style.Builder().fromUri("file://" + cacheStyleFile!!.absolutePath)
): String? {
return try {
val cacheStyleFile = File.createTempFile("my-", ".style.json")
cacheStyleFile.createNewFile()
Timber.i("Writing style file to: %s", cacheStyleFile.getAbsolutePath())
writeToFile(
cacheStyleFile,
ResourceUtils.readRawResource(context, R.raw.local_style)
)
cacheStyleFile.absolutePath
} catch (exception: Exception) {
Toast.makeText(
context,
"Could not create style file in cache dir",
Toast.LENGTH_SHORT
).show()
null
}
}
private fun writeToFile(file: File?, contents: String) {
var writer: BufferedWriter? = null
try {
writer = BufferedWriter(FileWriter(file))
writer.write(contents)
} finally {
writer?.close()
}
}
init {
this.context = WeakReference(context)
this.maplibreMap = WeakReference(maplibreMap)
private fun writeToFile(file: File?, contents: String) {
var writer: BufferedWriter? = null
try {
writer = BufferedWriter(FileWriter(file))
writer.write(contents)
} finally {
writer?.close()
}
}

View File

@@ -4,14 +4,19 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.maplibre.geojson.FeatureCollection
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView
@@ -28,7 +33,6 @@ import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.styles.TestStyles
import org.maplibre.android.testapp.utils.ResourceUtils.readRawResource
import timber.log.Timber
import java.lang.ref.WeakReference
/**
* Test activity showcasing using a symbol generator that generates Bitmaps from Android SDK Views.
@@ -44,11 +48,17 @@ class SymbolGeneratorActivity : AppCompatActivity(), OnMapReadyCallback {
mapView.getMapAsync(this)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onMapReady(map: MapLibreMap) {
maplibreMap = map
map.setStyle(TestStyles.getPredefinedStyleWithFallback("Outdoor")) { style: Style? ->
addSymbolClickListener()
LoadDataTask(this@SymbolGeneratorActivity).execute()
lifecycleScope.launch(Dispatchers.IO) {
val featureCollection = loadDataTask(this@SymbolGeneratorActivity)
withContext(Dispatchers.Main) {
featureCollection?.let { onDataLoaded(it) }
}
}
}
}
@@ -164,34 +174,13 @@ class SymbolGeneratorActivity : AppCompatActivity(), OnMapReadyCallback {
}
}
private class LoadDataTask internal constructor(activity: SymbolGeneratorActivity) :
AsyncTask<Void?, Void?, FeatureCollection?>() {
private val activity: WeakReference<SymbolGeneratorActivity>
init {
this.activity = WeakReference(activity)
}
override fun doInBackground(vararg p0: Void?): FeatureCollection? {
val context: Context? = activity.get()
if (context != null) {
// read local geojson from raw folder
val tinyCountriesJson = readRawResource(context, R.raw.tiny_countries)
return FeatureCollection.fromJson(tinyCountriesJson)
}
return null
}
override fun onPostExecute(featureCollection: FeatureCollection?) {
super.onPostExecute(featureCollection)
val activity = activity.get()
if (featureCollection == null || activity == null) {
return
}
activity.onDataLoaded(featureCollection)
}
private fun loadDataTask(context: SymbolGeneratorActivity) : FeatureCollection? {
// read local geojson from raw folder
val tinyCountriesJson = readRawResource(context, R.raw.tiny_countries)
return FeatureCollection.fromJson(tinyCountriesJson)
}
@RequiresApi(Build.VERSION_CODES.M)
fun onDataLoaded(featureCollection: FeatureCollection) {
if (mapView.isDestroyed) {
return
@@ -298,41 +287,30 @@ class SymbolGeneratorActivity : AppCompatActivity(), OnMapReadyCallback {
PropertyFactory.textField(textFieldExpressionResult),
PropertyFactory.textColor(textColorExpressionResult)
)
GenerateSymbolTask(maplibreMap, this).execute(featureCollection)
lifecycleScope.launch(Dispatchers.IO) {
val bitmapHashMap = generateSymbolTask(this@SymbolGeneratorActivity, featureCollection)
withContext(Dispatchers.Main) {
maplibreMap.getStyle { style -> style.addImagesAsync(bitmapHashMap) }
}
}
}
private class GenerateSymbolTask internal constructor(
private val maplibreMap: MapLibreMap?,
context: Context
) : AsyncTask<FeatureCollection?, Void?, HashMap<String, Bitmap>>() {
private val context: WeakReference<Context>
init {
this.context = WeakReference(context)
}
override fun doInBackground(vararg p0: FeatureCollection?): HashMap<String, Bitmap>? {
val imagesMap = HashMap<String, Bitmap>()
val context = context.get()
val features = p0[0]?.features()
if (context != null && features != null) {
for (feature in features) {
val countryName = feature.getStringProperty(FEATURE_ID)
val textView = TextView(context)
textView.setBackgroundColor(context.resources.getColor(R.color.blueAccent))
textView.setPadding(10, 5, 10, 5)
textView.setTextColor(Color.WHITE)
textView.text = countryName
imagesMap[countryName] = SymbolGenerator.generate(textView)
}
}
return imagesMap
}
override fun onPostExecute(bitmapHashMap: HashMap<String, Bitmap>) {
super.onPostExecute(bitmapHashMap)
maplibreMap?.getStyle { style -> style.addImagesAsync(bitmapHashMap) }
@RequiresApi(Build.VERSION_CODES.M)
private fun generateSymbolTask(
context: Context,
featureCollection: FeatureCollection?
) : HashMap<String, Bitmap> {
val imagesMap = HashMap<String, Bitmap>()
featureCollection?.features()?.forEach {
val countryName = it.getStringProperty(FEATURE_ID)
val textView = TextView(context)
textView.setBackgroundColor(context.resources.getColor(R.color.blueAccent, null))
textView.setPadding(10, 5, 10, 5)
textView.setTextColor(Color.WHITE)
textView.text = countryName
imagesMap[countryName] = SymbolGenerator.generate(textView)
}
return imagesMap
}
companion object {

View File

@@ -33,8 +33,6 @@ import org.maplibre.android.style.sources.Source
import org.maplibre.android.testapp.R
import org.maplibre.android.utils.BitmapUtils
import timber.log.Timber
import java.util.Arrays
import java.util.Objects
import java.util.Random
/**
@@ -80,7 +78,7 @@ class SymbolLayerActivity : AppCompatActivity(), OnMapClickListener, OnMapReadyC
Timber.e("Adding image with id: %s", id)
val androidIcon =
BitmapUtils.getBitmapFromDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_android_2, null))
style.addImage(id!!, Objects.requireNonNull(androidIcon)!!)
style.addImage(id!!, androidIcon!!)
}
}
}
@@ -156,7 +154,7 @@ class SymbolLayerActivity : AppCompatActivity(), OnMapClickListener, OnMapReadyC
maplibreMap.setStyle(
Style.Builder()
.fromUri("asset://streets.json")
.withImage("Car", Objects.requireNonNull(carBitmap)!!, false)
.withImage("Car", carBitmap!!, false)
.withSources(markerSource, mapboxSignSource, numberFormatSource)
.withLayers(markerSymbolLayer, mapboxSignSymbolLayer, numberFormatSymbolLayer)
)
@@ -170,7 +168,7 @@ class SymbolLayerActivity : AppCompatActivity(), OnMapClickListener, OnMapReadyC
val screenLoc = maplibreMap.projection.toScreenLocation(point)
val markerFeatures = maplibreMap.queryRenderedFeatures(screenLoc, MARKER_LAYER)
if (!markerFeatures.isEmpty()) {
for (feature in Objects.requireNonNull(markerCollection!!.features())!!) {
for (feature in markerCollection!!.features()!!) {
if (feature.getStringProperty(ID_FEATURE_PROPERTY)
== markerFeatures[0].getStringProperty(ID_FEATURE_PROPERTY)
) {
@@ -230,7 +228,7 @@ class SymbolLayerActivity : AppCompatActivity(), OnMapClickListener, OnMapReadyC
private fun toggleTextFont() {
if (markerSymbolLayer != null) {
if (Arrays.equals(markerSymbolLayer!!.textFont.getValue(), NORMAL_FONT_STACK)) {
if (markerSymbolLayer!!.textFont.getValue().contentEquals(NORMAL_FONT_STACK)) {
markerSymbolLayer!!.setProperties(PropertyFactory.textFont(BOLD_FONT_STACK))
} else {
markerSymbolLayer!!.setProperties(PropertyFactory.textFont(NORMAL_FONT_STACK))
@@ -312,7 +310,7 @@ class SymbolLayerActivity : AppCompatActivity(), OnMapClickListener, OnMapReadyC
public override fun onDestroy() {
super.onDestroy()
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
maplibreMap.removeOnMapClickListener(this)
}
mapView.onDestroy()

View File

@@ -11,7 +11,6 @@ import org.maplibre.geojson.Point
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.MapLibreMap.OnMapClickListener
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.style.expressions.Expression
import org.maplibre.android.style.layers.Property
@@ -52,16 +51,14 @@ class ZoomFunctionSymbolLayerActivity : AppCompatActivity() {
setContentView(R.layout.activity_zoom_symbol_layer)
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(
OnMapReadyCallback { map: MapLibreMap ->
maplibreMap = map
map.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style ->
updateSource(style)
addLayer(style)
map.addOnMapClickListener(mapClickListener)
}
mapView.getMapAsync { map: MapLibreMap ->
maplibreMap = map
map.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style ->
updateSource(style)
addLayer(style)
map.addOnMapClickListener(mapClickListener)
}
)
}
}
private fun updateSource(style: Style?) {
@@ -121,7 +118,7 @@ class ZoomFunctionSymbolLayerActivity : AppCompatActivity() {
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (maplibreMap != null) {
if (this::maplibreMap.isInitialized) {
if (item.itemId == R.id.menu_action_change_location) {
isInitialPosition = !isInitialPosition
updateSource(maplibreMap.style)

View File

@@ -10,8 +10,6 @@ import com.google.gson.Gson
import com.google.gson.JsonObject
import org.maplibre.android.MapLibre
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.maps.Style
import org.maplibre.android.module.http.HttpRequestUtil
import org.maplibre.android.testapp.R
@@ -37,49 +35,47 @@ class PerformanceMeasurementActivity : AppCompatActivity() {
.eventListener(eventListener)
.build()
HttpRequestUtil.setOkHttpClient(okHttpClient)
mapView.getMapAsync(
OnMapReadyCallback { maplibreMap: MapLibreMap ->
maplibreMap.setStyle(
Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Streets"))
)
}
)
mapView.getMapAsync {
it.setStyle(
Style.Builder().fromUri(TestStyles.getPredefinedStyleWithFallback("Streets"))
)
}
}
override fun onStart() {
super.onStart()
mapView!!.onStart()
mapView.onStart()
}
override fun onResume() {
super.onResume()
mapView!!.onResume()
mapView.onResume()
}
override fun onPause() {
super.onPause()
mapView!!.onPause()
mapView.onPause()
}
override fun onStop() {
super.onStop()
mapView!!.onStop()
mapView.onStop()
}
override fun onLowMemory() {
super.onLowMemory()
mapView!!.onLowMemory()
mapView.onLowMemory()
}
override fun onDestroy() {
HttpRequestUtil.setOkHttpClient(null)
super.onDestroy()
mapView!!.onDestroy()
mapView.onDestroy()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapView!!.onSaveInstanceState(outState)
mapView.onSaveInstanceState(outState)
}
private class EventListener : okhttp3.EventListener() {
@@ -105,7 +101,7 @@ class PerformanceMeasurementActivity : AppCompatActivity() {
}
}
private class Attribute<T> internal constructor(private val name: String, private val value: T)
private class Attribute<T>(private val name: String, private val value: T)
companion object {
private fun triggerPerformanceEvent(style: String, elapsed: Long) {
val attributes: MutableList<Attribute<String>> = ArrayList()
@@ -123,7 +119,7 @@ class PerformanceMeasurementActivity : AppCompatActivity() {
metaData.addProperty("brand", Build.BRAND)
metaData.addProperty("device", Build.MODEL)
metaData.addProperty("version", Build.VERSION.RELEASE)
metaData.addProperty("abi", Build.CPU_ABI)
metaData.addProperty("abi", Build.SUPPORTED_ABIS[0])
metaData.addProperty("country", Locale.getDefault().isO3Country)
metaData.addProperty("ram", ram)
metaData.addProperty("screenSize", windowSize)
@@ -135,7 +131,7 @@ class PerformanceMeasurementActivity : AppCompatActivity() {
}
private val ram: String
private get() {
get() {
val actManager = MapLibre.getApplicationContext()
.getSystemService(ACTIVITY_SERVICE) as ActivityManager
val memInfo = ActivityManager.MemoryInfo()
@@ -143,7 +139,7 @@ class PerformanceMeasurementActivity : AppCompatActivity() {
return memInfo.totalMem.toString()
}
private val windowSize: String
private get() {
get() {
val windowManager =
MapLibre.getApplicationContext().getSystemService(WINDOW_SERVICE) as WindowManager
val display = windowManager.defaultDisplay

View File

@@ -1,5 +1,7 @@
package org.maplibre.android.testapp.activity.textureview
import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import org.maplibre.android.maps.MapLibreMapOptions
import org.maplibre.android.maps.OnMapReadyCallback
import org.maplibre.android.testapp.activity.maplayout.DebugModeActivity
@@ -9,15 +11,20 @@ import org.maplibre.android.testapp.utils.NavUtils
* Test activity showcasing the different debug modes and allows to cycle between the default map styles.
*/
class TextureViewDebugModeActivity : DebugModeActivity(), OnMapReadyCallback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
NavUtils.navigateHome(this@TextureViewDebugModeActivity)
}
})
}
override fun setupMapLibreMapOptions(): MapLibreMapOptions {
val maplibreMapOptions = super.setupMapLibreMapOptions()
maplibreMapOptions.textureMode(true)
return maplibreMapOptions
}
override fun onBackPressed() {
// activity uses singleInstance for testing purposes
// code below provides a default navigation when using the app
NavUtils.navigateHome(this)
}
}

View File

@@ -33,7 +33,7 @@ class TextureViewResizeActivity : AppCompatActivity() {
private fun setupMapView(savedInstanceState: Bundle?) {
mapView = findViewById(R.id.mapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(OnMapReadyCallback { maplibreMap: MapLibreMap -> setupMap(maplibreMap) })
mapView.getMapAsync { setupMap(it) }
}
private fun setupMap(maplibreMap: MapLibreMap) {
@@ -43,7 +43,7 @@ class TextureViewResizeActivity : AppCompatActivity() {
private fun setupFab() {
val fabDebug = findViewById<FloatingActionButton>(R.id.fabResize)
fabDebug.setOnClickListener { view: View? ->
if (mapView != null) {
if (this::mapView.isInitialized) {
val parent = findViewById<View>(R.id.coordinator_layout)
val width = if (parent.width == mapView.width) parent.width / 2 else parent.width
val height =

View File

@@ -14,7 +14,8 @@ class CityStateMarkerOptions : BaseMarkerOptions<CityStateMarker?, CityStateMark
return getThis()
}
constructor() {}
constructor()
private constructor(`in`: Parcel) {
position(`in`.readParcelable<Parcelable>(LatLng::class.java.classLoader) as LatLng)
snippet(`in`.readString())

View File

@@ -1,14 +1,13 @@
package org.maplibre.android.testapp.model.other
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.widget.EditText
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import org.maplibre.android.testapp.R
import org.maplibre.android.testapp.model.other.OfflineDownloadRegionDialog.DownloadRegionDialogListener
import timber.log.Timber
class OfflineDownloadRegionDialog : DialogFragment() {
@@ -17,9 +16,10 @@ class OfflineDownloadRegionDialog : DialogFragment() {
}
var listener: DownloadRegionDialogListener? = null
override fun onAttach(activity: Activity) {
super.onAttach(activity)
listener = activity as DownloadRegionDialogListener
override fun onAttach(context: Context) {
super.onAttach(context)
listener = context as? DownloadRegionDialogListener
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
@@ -34,7 +34,7 @@ class OfflineDownloadRegionDialog : DialogFragment() {
.setView(regionNameEdit)
.setPositiveButton("Start") { dialog: DialogInterface?, which: Int ->
val regionName = regionNameEdit.text.toString()
listener!!.onDownloadRegionDialogPositiveClick(regionName)
listener?.onDownloadRegionDialogPositiveClick(regionName)
}
.setNegativeButton("Cancel") { dialog: DialogInterface?, which: Int -> Timber.d("Download cancelled.") }
return builder.create()

View File

@@ -1,64 +1,38 @@
package org.maplibre.android.testapp.utils
import android.content.Context
import android.os.AsyncTask
import java.io.File
import java.io.FileOutputStream
import java.lang.ref.WeakReference
class FileUtils {
object FileUtils {
/**
* Task that copies a file from the assets directory to a provided directory.
* The asset's name is going to be kept in the new directory.
*/
class CopyFileFromAssetsTask(context: Context, listener: OnFileCopiedFromAssetsListener) : AsyncTask<String, Void, Boolean>() {
private val contextWeakReference: WeakReference<Context> = WeakReference(context)
private val listenerWeakReference: WeakReference<OnFileCopiedFromAssetsListener> = WeakReference(listener)
override fun doInBackground(vararg strings: String): Boolean? {
val assetName = strings[0]
val destinationPath = strings[1]
contextWeakReference.get()?.let {
try {
copyAsset(it, assetName, destinationPath)
} catch (ex: Exception) {
return false
}
}
return true
fun copyFileFromAssetsTask(
context: Context,
assetName: String,
destinationPath: String
) : Boolean =
try {
copyAsset(context, assetName, destinationPath)
true
} catch (ex: Exception) {
false
}
override fun onCancelled() {
listenerWeakReference.get()?.onError()
private fun copyAsset(context: Context, assetName: String, destinationPath: String) {
val bufferSize = 1024
val assetManager = context.assets
val inputStream = assetManager.open(assetName)
val outputStream = FileOutputStream(File(destinationPath, assetName))
try {
inputStream.copyTo(outputStream, bufferSize)
} finally {
inputStream.close()
outputStream.flush()
outputStream.close()
}
override fun onPostExecute(result: Boolean) {
if (result) {
listenerWeakReference.get()?.onFileCopiedFromAssets()
} else {
listenerWeakReference.get()?.onError()
}
}
private fun copyAsset(context: Context, assetName: String, destinationPath: String) {
val bufferSize = 1024
val assetManager = context.assets
val inputStream = assetManager.open(assetName)
val outputStream = FileOutputStream(File(destinationPath, assetName))
try {
inputStream.copyTo(outputStream, bufferSize)
} finally {
inputStream.close()
outputStream.flush()
outputStream.close()
}
}
}
interface OnFileCopiedFromAssetsListener {
fun onFileCopiedFromAssets()
fun onError()
}
}

View File

@@ -10,13 +10,13 @@ class ItemClickSupport private constructor(private val recyclerView: RecyclerVie
private val onClickListener = View.OnClickListener { view ->
onItemClickListener?.let {
val holder = recyclerView.getChildViewHolder(view)
it.onItemClicked(recyclerView, holder.adapterPosition, view)
it.onItemClicked(recyclerView, holder.bindingAdapterPosition, view)
}
}
private val onLongClickListener = View.OnLongClickListener { view ->
onItemLongClickListener?.let {
val holder = recyclerView.getChildViewHolder(view)
it.onItemLongClicked(recyclerView, holder.adapterPosition, view)
it.onItemLongClicked(recyclerView, holder.bindingAdapterPosition, view)
}
false
}
@@ -61,9 +61,7 @@ class ItemClickSupport private constructor(private val recyclerView: RecyclerVie
fun removeFrom(view: RecyclerView): ItemClickSupport? {
val support = view.getTag(R.id.item_click_support) as ItemClickSupport?
support?.let {
it.detach(view)
}
support?.detach(view)
return support
}
}

View File

@@ -7,8 +7,7 @@ import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.annotation.RequiresApi
import androidx.annotation.StringDef
import com.google.gson.Gson
import com.google.gson.JsonObject
@@ -26,11 +25,11 @@ import timber.log.Timber
import java.io.IOException
import java.util.*
@RequiresApi(Build.VERSION_CODES.M)
class TileLoadingMeasurementUtils {
companion object {
private const val ATTRIBUTE_REQUEST_URL = "requestUrl"
fun setUpTileLoadingMeasurement() {
if (isTileLoadingMeasurementOn) {
val okHttpClient: OkHttpClient = Builder()
@@ -41,7 +40,7 @@ class TileLoadingMeasurementUtils {
}
private val isTileLoadingMeasurementOn: Boolean
private get() = isBooleanMetaDataValueOn(
get() = isBooleanMetaDataValueOn(
MapLibreConstants.KEY_META_DATA_MEASURE_TILE_DOWNLOAD_ON,
MapLibreConstants.DEFAULT_MEASURE_TILE_DOWNLOAD_ON
)
@@ -76,7 +75,7 @@ class TileLoadingMeasurementUtils {
*/
internal class TileLoadingInterceptor : Interceptor {
@StringDef(*[CONNECTION_NONE, CONNECTION_CELLULAR, CONNECTION_WIFI])
@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
@Retention(AnnotationRetention.SOURCE)
internal annotation class ConnectionState
@Throws(IOException::class)
@@ -108,7 +107,7 @@ class TileLoadingMeasurementUtils {
companion object {
private var metadata: String? = null
private get() {
get() {
if (field == null) {
val metaData = JsonObject()
metaData.addProperty("os", "android")
@@ -116,7 +115,7 @@ class TileLoadingMeasurementUtils {
metaData.addProperty("brand", Build.BRAND)
metaData.addProperty("device", Build.MODEL)
metaData.addProperty("version", Build.VERSION.RELEASE)
metaData.addProperty("abi", Build.CPU_ABI)
metaData.addProperty("abi", Build.SUPPORTED_ABIS[0])
metaData.addProperty("country", Locale.getDefault().isO3Country)
metaData.addProperty("ram", ram)
metaData.addProperty("screenSize", windowSize)
@@ -133,7 +132,7 @@ class TileLoadingMeasurementUtils {
}
private val ram: String
private get() {
get() {
val actManager = MapLibre.getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val memInfo = ActivityManager.MemoryInfo()
@@ -141,44 +140,33 @@ class TileLoadingMeasurementUtils {
return memInfo.totalMem.toString()
}
private val windowSize: String
private get() {
val windowManager = MapLibre.getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val display = windowManager.defaultDisplay
val metrics = DisplayMetrics()
display.getMetrics(metrics)
val width = metrics.widthPixels
val height = metrics.heightPixels
return "{$width,$height}"
get() {
val metrics = MapLibre.getApplicationContext().resources.displayMetrics
return "{${metrics.widthPixels},${metrics.heightPixels}}"
}
@get:ConnectionState
private val connectionState: String
private get() {
get() {
val appContext = MapLibre.getApplicationContext()
val connectivityManager =
appContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (connectivityManager != null) {
val capabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return CONNECTION_WIFI
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return CONNECTION_CELLULAR
}
val capabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return CONNECTION_WIFI
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return CONNECTION_CELLULAR
}
}
} else {
if (connectivityManager != null) {
val activeNetwork = connectivityManager.activeNetworkInfo
if (activeNetwork != null) {
if (activeNetwork.type == ConnectivityManager.TYPE_WIFI) {
return CONNECTION_WIFI
} else if (activeNetwork.type == ConnectivityManager.TYPE_MOBILE) {
return CONNECTION_CELLULAR
}
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)?.let {
if (it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return CONNECTION_WIFI
} else if (it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return CONNECTION_CELLULAR
}
}
}
@@ -187,6 +175,6 @@ class TileLoadingMeasurementUtils {
}
}
private class Attribute<T> internal constructor(private val name: String, private val value: T)
private class Attribute<T>(private val name: String, private val value: T)
}
}

View File

@@ -31,10 +31,12 @@ multidex = "2.0.1"
androidxTestExtJUnit = "1.1.5"
androidxTestCoreKtx = "1.5.0"
kotlinxSerializationJson = "1.6.0"
kotlinxCoroutinesTest = "1.6.4"
androidGradlePlugin = "8.5.1"
[libraries]
kotlinxCoroutinesTest = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutinesTest" }
maplibreJavaGeoJSON = { group = "org.maplibre.gl", name = "android-sdk-geojson", version.ref = "mapLibreServices" }
mapboxAndroidGestures = { group = "com.mapbox.mapboxsdk", name = "mapbox-android-gestures", version.ref = "mapboxGestures" }
maplibreJavaTurf = { group = "org.maplibre.gl", name = "android-sdk-turf", version.ref = "mapLibreServices" }