Skip to content

Commit

Permalink
Merge pull request #69 from mutualmobile/development
Browse files Browse the repository at this point in the history
Version 1.0.0 Changes
  • Loading branch information
shubhamsinghmutualmobile committed Jun 10, 2023
2 parents 931ff83 + 104b637 commit 229f0c0
Show file tree
Hide file tree
Showing 61 changed files with 1,978 additions and 599 deletions.
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ This library provides a convenience wrapper over the [Sensor APIs](https://devel
## Demo ❤️
![Screen Recording 2023-04-03 at 1 00 08 PM](https://user-images.githubusercontent.com/89389061/229441943-6339d18f-c704-4d92-9fe8-28c2fd94fdeb.gif)

## WIP 🚧
This library is a work-in-progress and is subject to major changes. Our team is working hard to get it stable as soon as possible. Thank you for your patience 🌺

## Usage 🚀
### Install dependency 📲
#### Kotlin `build.gradle.kts (:module-name)`
Expand Down Expand Up @@ -65,15 +62,15 @@ Ambient Temperature | ✅️ | rememberAmbientTemperatureSensorState()
Magnetic Field (Uncalibrated) | ✅️️ | rememberUncalibratedMagneticFieldSensorState()
GameRotation Vector | ✅️ | rememberGameRotationVectorSensorState()
Gyroscope (Uncalibrated) | ✅️ | rememberUncalibratedGyroscopeSensorState()
Significant Motion | | N/A
Significant Motion | | rememberSignificantMotionSensorState(onMotionEvent = {})
Step Detector | ✅️ | rememberStepDetectorSensorState()
Step Counter | ✅️ | rememberStepCounterSensorState()
Geomagnetic Rotation Vector | ✅️️ | rememberGeomagneticRotationVectorSensorState()
Heart Rate | ✅️ | rememberHeartRateSensorState()
Pose6DOF | — | N/A
Stationary Detect | ️ | WIP
Motion Detect | ️ | WIP
Heart Beat | | N/A
Stationary Detect | ️ | rememberStationaryDetectSensorState()
Motion Detect | ️ | rememberMotionDetectSensorState()
Heart Beat | | rememberHeartBeatSensorState()
Low Latency Off-Body Detect | ✅️ | rememberLowLatencyOffBodyDetectSensorState()
Accelerometer (Uncalibrated) | ✅️ | rememberUncalibratedAccelerometerSensorState()
Hinge Angle | ✅️ | rememberHingeAngleSensorState()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class AccelerometerSensorState internal constructor(
val zForce: Float = 0f,
val isAvailable: Boolean = false,
val accuracy: Int = 0,
) {
private val startListeningEvents: (() -> Unit)? = null,
private val stopListeningEvents: (() -> Unit)? = null
) : SensorStateListener {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is AccelerometerSensorState) return false
Expand All @@ -32,6 +34,8 @@ class AccelerometerSensorState internal constructor(
if (zForce != other.zForce) return false
if (isAvailable != other.isAvailable) return false
if (accuracy != other.accuracy) return false
if (startListeningEvents != other.startListeningEvents) return false
if (stopListeningEvents != other.stopListeningEvents) return false

return true
}
Expand All @@ -42,30 +46,44 @@ class AccelerometerSensorState internal constructor(
result = 31 * result + zForce.hashCode()
result = 31 * result + isAvailable.hashCode()
result = 31 * result + accuracy.hashCode()
result = 31 * result + startListeningEvents.hashCode()
result = 31 * result + stopListeningEvents.hashCode()
return result
}

override fun toString(): String {
return "AccelerometerSensorState(xForce=$xForce, yForce=$yForce, zForce=$zForce, " +
"isAvailable=$isAvailable, accuracy=$accuracy)"
"isAvailable=$isAvailable, accuracy=$accuracy)"
}

override fun startListening() {
startListeningEvents?.invoke()
}

override fun stopListening() {
stopListeningEvents?.invoke()
}
}

/**
* Creates and [remember]s an instance of [AccelerometerSensorState].
* @param autoStart Start listening to sensor events as soon as sensor state is initialised.
* Defaults to true.
* @param sensorDelay The rate at which the raw sensor data should be received.
* Defaults to [SensorDelay.Normal].
* @param onError Callback invoked on every error state.
*/
@Composable
fun rememberAccelerometerSensorState(
autoStart: Boolean = true,
sensorDelay: SensorDelay = SensorDelay.Normal,
onError: (throwable: Throwable) -> Unit = {},
onError: (throwable: Throwable) -> Unit = {}
): AccelerometerSensorState {
val sensorState = rememberSensorState(
sensorType = SensorType.Accelerometer,
sensorDelay = sensorDelay,
onError = onError,
autoStart = autoStart,
onError = onError
)
val accelerometerSensorState = remember { mutableStateOf(AccelerometerSensorState()) }

Expand All @@ -79,7 +97,9 @@ fun rememberAccelerometerSensorState(
yForce = sensorStateValues[1],
zForce = sensorStateValues[2],
isAvailable = sensorState.isAvailable,
accuracy = sensorState.accuracy
accuracy = sensorState.accuracy,
startListeningEvents = sensorState::startListening,
stopListeningEvents = sensorState::stopListening
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,84 @@ import androidx.compose.runtime.remember
*/
@Immutable
class AmbientTemperatureSensorState internal constructor(
val temperature: Float = 0f,
val isAvailable: Boolean = false,
val accuracy: Int = 0
) {
override fun toString(): String {
return "AmbientTemperatureSensorState(temperature=$temperature, " +
"isAvailable=$isAvailable, accuracy=$accuracy)"
}
val temperature: Float = 0f,
val isAvailable: Boolean = false,
val accuracy: Int = 0,
private val startListeningEvents: (() -> Unit)? = null,
private val stopListeningEvents: (() -> Unit)? = null
) : SensorStateListener {
override fun equals(other: Any?): Boolean {
if (this === other) return true
other as AmbientTemperatureSensorState

override fun equals(other: Any?): Boolean {
if (this === other) return true
other as AmbientTemperatureSensorState
if (temperature != other.temperature) return false
if (isAvailable != other.isAvailable) return false
if (accuracy != other.accuracy) return false
if (startListeningEvents != other.startListeningEvents) return false
if (stopListeningEvents != other.stopListeningEvents) return false
return true
}

if (temperature != other.temperature) return false
if (isAvailable != other.isAvailable) return false
if (accuracy != other.accuracy) return false
return true
}
override fun hashCode(): Int {
var result = temperature.hashCode()
result = 31 * result + isAvailable.hashCode()
result = 31 * result + accuracy.hashCode()
result = 31 * result + startListeningEvents.hashCode()
result = 31 * result + stopListeningEvents.hashCode()
return result
}

override fun hashCode(): Int {
var result = temperature.hashCode()
result = 31 * result + isAvailable.hashCode()
result = 31 * result + accuracy
return result
}
}
override fun toString(): String {
return "AmbientTemperatureSensorState(temperature=$temperature, " +
"isAvailable=$isAvailable, accuracy=$accuracy)"
}

override fun startListening() {
startListeningEvents?.invoke()
}

override fun stopListening() {
stopListeningEvents?.invoke()
}
}

/**
* Creates and [remember]s instance of [AmbientTemperatureSensorState].
* @param autoStart Start listening to sensor events as soon as sensor state is initialised.
* Defaults to true.
* @param sensorDelay The rate at which the raw sensor data should be received.
* Defaults to [SensorDelay.Normal].
* @param onError Callback invoked on every error state.
*/
@Composable
fun rememberAmbientTemperatureSensorState(
sensorDelay: SensorDelay = SensorDelay.Normal,
onError: (throwable: Throwable) -> Unit = {},
autoStart: Boolean = true,
sensorDelay: SensorDelay = SensorDelay.Normal,
onError: (throwable: Throwable) -> Unit = {}
): AmbientTemperatureSensorState {
val sensorState = rememberSensorState(
sensorType = SensorType.AmbientTemperature,
sensorDelay = sensorDelay,
onError = onError,
)

val ambientTemperatureSensorState = remember { mutableStateOf(AmbientTemperatureSensorState()) }
val sensorState = rememberSensorState(
sensorType = SensorType.AmbientTemperature,
sensorDelay = sensorDelay,
autoStart = autoStart,
onError = onError
)

LaunchedEffect(key1 = sensorState, block = {
val sensorStateValues = sensorState.data
if (sensorStateValues.isNotEmpty()) {
ambientTemperatureSensorState.value = AmbientTemperatureSensorState(
temperature = sensorStateValues[0],
isAvailable = sensorState.isAvailable,
accuracy = sensorState.accuracy
)
val ambientTemperatureSensorState = remember {
mutableStateOf(AmbientTemperatureSensorState())
}
})

return ambientTemperatureSensorState.value
}
LaunchedEffect(key1 = sensorState, block = {
val sensorStateValues = sensorState.data
if (sensorStateValues.isNotEmpty()) {
ambientTemperatureSensorState.value = AmbientTemperatureSensorState(
temperature = sensorStateValues[0],
isAvailable = sensorState.isAvailable,
accuracy = sensorState.accuracy,
startListeningEvents = sensorState::startListening,
stopListeningEvents = sensorState::stopListening
)
}
})

return ambientTemperatureSensorState.value
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,72 +16,93 @@ import androidx.compose.runtime.remember
*/
@Immutable
class GameRotationVectorSensorState internal constructor(
val vectorX: Float = 0f,
val vectorY: Float = 0f,
val vectorZ: Float = 0f,
val isAvailable: Boolean = false,
val accuracy: Int = 0
) {
override fun toString(): String {
return "GameRotationVectorSensorState(vectorX=$vectorX, " +
"vectorY=$vectorY, vectorZ=$vectorZ, isAvailable=$isAvailable, " +
"accuracy=$accuracy)"
}
val vectorX: Float = 0f,
val vectorY: Float = 0f,
val vectorZ: Float = 0f,
val isAvailable: Boolean = false,
val accuracy: Int = 0,
private val startListeningEvents: (() -> Unit)? = null,
private val stopListeningEvents: (() -> Unit)? = null
) : SensorStateListener {
override fun equals(other: Any?): Boolean {
if (this === other) return true
other as GameRotationVectorSensorState

override fun equals(other: Any?): Boolean {
if (this === other) return true
other as GameRotationVectorSensorState
if (vectorX != other.vectorX) return false
if (vectorY != other.vectorY) return false
if (vectorZ != other.vectorZ) return false
if (isAvailable != other.isAvailable) return false
if (accuracy != other.accuracy) return false
if (startListeningEvents != other.startListeningEvents) return false
if (stopListeningEvents != other.stopListeningEvents) return false
return true
}

if (vectorX != other.vectorX) return false
if (vectorY != other.vectorY) return false
if (vectorZ != other.vectorZ) return false
if (isAvailable != other.isAvailable) return false
if (accuracy != other.accuracy) return false
return true
}
override fun hashCode(): Int {
var result = vectorX.hashCode()
result = 31 * result + vectorY.hashCode()
result = 31 * result + vectorZ.hashCode()
result = 31 * result + isAvailable.hashCode()
result = 31 * result + accuracy.hashCode()
result = 31 * result + startListeningEvents.hashCode()
result = 31 * result + stopListeningEvents.hashCode()
return result
}

override fun hashCode(): Int {
var result = vectorX.hashCode()
result = 31 * result + vectorY.hashCode()
result = 31 * result + vectorZ.hashCode()
result = 31 * result + isAvailable.hashCode()
result = 31 * result + accuracy
return result
}
}
override fun toString(): String {
return "GameRotationVectorSensorState(vectorX=$vectorX, " +
"vectorY=$vectorY, vectorZ=$vectorZ, isAvailable=$isAvailable, " +
"accuracy=$accuracy)"
}

override fun startListening() {
startListeningEvents?.invoke()
}

override fun stopListening() {
stopListeningEvents?.invoke()
}
}

/**
* Creates and [remember]s instance of [GameRotationVectorSensorState].
* @param autoStart Start listening to sensor events as soon as sensor state is initialised.
* Defaults to true.
* @param sensorDelay The rate at which the raw sensor data should be received.
* Defaults to [SensorDelay.Game].
* @param onError Callback invoked on every error state.
*/
@Composable
fun rememberGameRotationVectorSensorState(
sensorDelay: SensorDelay = SensorDelay.Game,
onError: (throwable: Throwable) -> Unit = {},
autoStart: Boolean = true,
sensorDelay: SensorDelay = SensorDelay.Game,
onError: (throwable: Throwable) -> Unit = {}
): GameRotationVectorSensorState {
val sensorState = rememberSensorState(
sensorType = SensorType.GameRotationVector,
sensorDelay = sensorDelay,
onError = onError,
)

val gameRotationVectorSensorState = remember { mutableStateOf(GameRotationVectorSensorState()) }
val sensorState = rememberSensorState(
sensorType = SensorType.GameRotationVector,
sensorDelay = sensorDelay,
autoStart = autoStart,
onError = onError
)

LaunchedEffect(key1 = sensorState, block = {
val sensorStateValues = sensorState.data
if (sensorStateValues.isNotEmpty()) {
gameRotationVectorSensorState.value = GameRotationVectorSensorState(
vectorX = sensorStateValues[0],
vectorY = sensorStateValues[1],
vectorZ = sensorStateValues[2],
isAvailable = sensorState.isAvailable,
accuracy = sensorState.accuracy
)
val gameRotationVectorSensorState = remember {
mutableStateOf(GameRotationVectorSensorState())
}
})

return gameRotationVectorSensorState.value
}
LaunchedEffect(key1 = sensorState, block = {
val sensorStateValues = sensorState.data
if (sensorStateValues.isNotEmpty()) {
gameRotationVectorSensorState.value = GameRotationVectorSensorState(
vectorX = sensorStateValues[0],
vectorY = sensorStateValues[1],
vectorZ = sensorStateValues[2],
isAvailable = sensorState.isAvailable,
accuracy = sensorState.accuracy,
startListeningEvents = sensorState::startListening,
stopListeningEvents = sensorState::stopListening
)
}
})

return gameRotationVectorSensorState.value
}
Loading

0 comments on commit 229f0c0

Please sign in to comment.