Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add isMock property to extended location #39

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This is a Kotlin Multiplatform library that provides geolocation to common code.

## Features
- **Geolocation tracking** - track user geolocation from common code;
- **Compose Multiplatform** support;

## Requirements
- Gradle version 6.0+
Expand All @@ -35,7 +36,10 @@ allprojects {
project build.gradle
```groovy
dependencies {
commonMainApi("dev.icerock.moko:geo:0.5.0")
commonMainApi("dev.icerock.moko:geo:0.6.0")

// Compose Multiplatform
commonMainApi("dev.icerock.moko:geo-compose:0.6.0")
}
```

Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ buildscript {
classpath(libs.mokoGradlePlugin)
classpath(libs.mobileMultiplatformGradlePlugin)
classpath(libs.kotlinSerializationGradlePlugin)
classpath(libs.composeJetBrainsGradlePlugin)
classpath(libs.detektGradlePlugin)
}
}

Expand Down
27 changes: 27 additions & 0 deletions geo-compose/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2023 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

plugins {
id("dev.icerock.moko.gradle.multiplatform.mobile")
id("dev.icerock.moko.gradle.publication")
id("dev.icerock.moko.gradle.stub.javadoc")
id("dev.icerock.moko.gradle.detekt")
id("org.jetbrains.compose")
}

android {
namespace = "dev.icerock.moko.geo.compose"

defaultConfig {
minSdk = 21
}
}

dependencies {
commonMainApi(projects.geo)
commonMainApi(compose.runtime)

androidMainImplementation(libs.appCompat)
androidMainImplementation(compose.foundation)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2023 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.geo.compose

import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import dev.icerock.moko.geo.LocationTracker

@Suppress("FunctionNaming")
@Composable
actual fun BindLocationTrackerEffect(locationTracker: LocationTracker) {
val lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current
val context: Context = LocalContext.current

LaunchedEffect(locationTracker, lifecycleOwner, context) {
val fragmentManager: FragmentManager = (context as FragmentActivity).supportFragmentManager

locationTracker.bind(lifecycleOwner.lifecycle, context, fragmentManager)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2023 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.geo.compose

import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import com.google.android.gms.location.LocationRequest
import dev.icerock.moko.geo.LocationTracker
import dev.icerock.moko.permissions.PermissionsController

@Composable
actual fun rememberLocationTrackerFactory(accuracy: LocationTrackerAccuracy): LocationTrackerFactory {
val context: Context = LocalContext.current
return remember(context) {
object : LocationTrackerFactory {
override fun createLocationTracker(): LocationTracker {
return LocationTracker(
permissionsController = PermissionsController(
applicationContext = context.applicationContext
),
priority = accuracy.toPriority()
)
}

override fun createLocationTracker(
permissionsController: PermissionsController
): LocationTracker {
return LocationTracker(
permissionsController = permissionsController,
priority = accuracy.toPriority()
)
}
}
}
}

private fun LocationTrackerAccuracy.toPriority(): Int {
return when (this) {
LocationTrackerAccuracy.Best -> LocationRequest.PRIORITY_HIGH_ACCURACY
LocationTrackerAccuracy.Medium -> LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
LocationTrackerAccuracy.LowPower -> LocationRequest.PRIORITY_LOW_POWER
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright 2023 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.geo.compose

import androidx.compose.runtime.Composable
import dev.icerock.moko.geo.LocationTracker

@Suppress("FunctionNaming")
@Composable
expect fun BindLocationTrackerEffect(locationTracker: LocationTracker)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2023 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.geo.compose

import androidx.compose.runtime.Composable
import dev.icerock.moko.geo.LocationTracker
import dev.icerock.moko.permissions.PermissionsController

interface LocationTrackerFactory {
fun createLocationTracker(): LocationTracker
fun createLocationTracker(permissionsController: PermissionsController): LocationTracker
}

enum class LocationTrackerAccuracy {
Best,
Medium,
LowPower
}

@Composable
expect fun rememberLocationTrackerFactory(accuracy: LocationTrackerAccuracy): LocationTrackerFactory
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright 2023 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.geo.compose

import androidx.compose.runtime.Composable
import dev.icerock.moko.geo.LocationTracker

// on iOS side we should not do anything to prepare LocationTracker to work
@Suppress("FunctionNaming")
@Composable
actual fun BindLocationTrackerEffect(locationTracker: LocationTracker) = Unit
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2023 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.geo.compose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import dev.icerock.moko.geo.LocationTracker
import dev.icerock.moko.permissions.PermissionsController
import platform.CoreLocation.CLLocationAccuracy
import platform.CoreLocation.kCLLocationAccuracyBest
import platform.CoreLocation.kCLLocationAccuracyKilometer
import platform.CoreLocation.kCLLocationAccuracyReduced

@Composable
actual fun rememberLocationTrackerFactory(accuracy: LocationTrackerAccuracy): LocationTrackerFactory {
return remember {
object : LocationTrackerFactory {
override fun createLocationTracker(): LocationTracker {
return LocationTracker(
permissionsController = dev.icerock.moko.permissions.ios.PermissionsController(),
accuracy = accuracy.toIosAccuracy()
)
}

override fun createLocationTracker(
permissionsController: PermissionsController
): LocationTracker {
return LocationTracker(
permissionsController = permissionsController,
accuracy = accuracy.toIosAccuracy()
)
}
}
}
}

private fun LocationTrackerAccuracy.toIosAccuracy(): CLLocationAccuracy {
return when (this) {
LocationTrackerAccuracy.Best -> kCLLocationAccuracyBest
LocationTrackerAccuracy.Medium -> kCLLocationAccuracyKilometer
LocationTrackerAccuracy.LowPower -> kCLLocationAccuracyReduced
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import dev.icerock.moko.permissions.Permission
import dev.icerock.moko.permissions.PermissionsController
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -44,7 +45,7 @@ actual class LocationTracker(
fun bind(lifecycle: Lifecycle, context: Context, fragmentManager: FragmentManager) {
permissionsController.bind(lifecycle, fragmentManager)

locationProviderClient = FusedLocationProviderClient(context)
locationProviderClient = LocationServices.getFusedLocationProviderClient(context)

@SuppressLint("MissingPermission")
if (isStarted) {
Expand All @@ -63,7 +64,7 @@ actual class LocationTracker(
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)

val lastLocation = locationResult.lastLocation
val lastLocation = locationResult.lastLocation ?: return

val speedAccuracy = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) null
else lastLocation.speedAccuracyMetersPerSecond.toDouble()
Expand Down Expand Up @@ -104,7 +105,8 @@ actual class LocationTracker(
azimuth = azimuth,
speed = speed,
altitude = altitude,
timestampMs = lastLocation.time
timestampMs = lastLocation.time,
isMock = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) lastLocation.isMock else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) lastLocation.isFromMockProvider else null
)

trackerScope.launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ data class ExtendedLocation(
val azimuth: Azimuth,
val speed: Speed,
val altitude: Altitude,
val timestampMs: Long
val timestampMs: Long,
val isMock:Boolean? = null
) : Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package dev.icerock.moko.geo
import dev.icerock.moko.permissions.Permission
import dev.icerock.moko.permissions.PermissionsController
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
Expand All @@ -23,7 +24,7 @@ actual class LocationTracker(
) {
private val locationsChannel = Channel<LatLng>(Channel.BUFFERED)
private val extendedLocationsChannel = Channel<ExtendedLocation>(Channel.BUFFERED)
private val trackerScope = CoroutineScope(UIDispatcher())
private val trackerScope = CoroutineScope(Dispatchers.Main)
private val tracker = Tracker(
locationsChannel = locationsChannel,
extendedLocationsChannel = extendedLocationsChannel,
Expand Down
73 changes: 0 additions & 73 deletions geo/src/iosMain/kotlin/dev/icerock/moko/geo/UIDispatcher.kt

This file was deleted.

8 changes: 3 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ org.gradle.configureondemand=false
org.gradle.parallel=true

kotlin.code.style=official
kotlin.native.enableDependencyPropagation=false
kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.mpp.enableCompatibilityMetadataVariant=true
kotlin.mpp.androidSourceSetLayoutVersion=2

android.useAndroidX=true

moko.android.targetSdk=31
moko.android.compileSdk=31
moko.android.targetSdk=33
moko.android.compileSdk=33
moko.android.minSdk=16

moko.publish.name=MOKO geo
Expand Down
Loading