Merge pull request #116 from NordicSemiconductor/feat/analytics_permission

Add analytics permission switch to settings
This commit is contained in:
Sylwester Zieliński
2022-06-03 14:40:05 +02:00
committed by GitHub
48 changed files with 92 additions and 90 deletions

View File

@@ -92,6 +92,7 @@ dependencies {
implementation libs.nordic.ui.scanner
implementation libs.nordic.navigation
implementation libs.nordic.ui.logger
implementation libs.nordic.analytics
implementation libs.bundles.hilt
kapt libs.bundles.hiltkapt

View File

@@ -7,6 +7,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import dagger.hilt.android.AndroidEntryPoint
import no.nordicsemi.analytics.view.AnalyticsPermissionRequestDialog
import no.nordicsemi.android.gls.GLSDestinations
import no.nordicsemi.android.material.you.NordicActivity
import no.nordicsemi.android.material.you.NordicTheme
@@ -32,6 +33,8 @@ class MainActivity : NordicActivity() {
) {
NavigationView(HomeDestinations + ProfileDestinations + ScannerDestinations + GLSDestinations)
}
AnalyticsPermissionRequestDialog()
}
}
}

View File

@@ -20,8 +20,8 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.nrftoolbox.R
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.nrftoolbox.R
@Composable
fun FeatureButton(

View File

@@ -17,12 +17,10 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.analytics.Link
import no.nordicsemi.android.analytics.Profile
import no.nordicsemi.android.analytics.ProfileOpenEvent
import no.nordicsemi.android.logger.LoggerAppRunner
import no.nordicsemi.android.nrftoolbox.BuildConfig
import no.nordicsemi.android.nrftoolbox.ProfileDestination
import no.nordicsemi.android.nrftoolbox.R
import no.nordicsemi.android.nrftoolbox.viewmodel.HomeViewModel
import no.nordicsemi.android.theme.view.TitleAppBar
private const val DFU_PACKAGE_NAME = "no.nordicsemi.android.dfu"
private const val DFU_LINK = "https://play.google.com/store/apps/details?id=no.nordicsemi.android.dfu"

View File

@@ -0,0 +1,27 @@
package no.nordicsemi.android.nrftoolbox.view
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.colorResource
import no.nordicsemi.analytics.view.AnalyticsPermissionButton
import no.nordicsemi.android.theme.R
@Composable
fun TitleAppBar(text: String) {
SmallTopAppBar(
title = { Text(text, maxLines = 2) },
colors = TopAppBarDefaults.smallTopAppBarColors(
scrolledContainerColor = MaterialTheme.colorScheme.primary,
containerColor = colorResource(id = R.color.appBarColor),
titleContentColor = MaterialTheme.colorScheme.onPrimary,
actionIconContentColor = MaterialTheme.colorScheme.onPrimary,
navigationIconContentColor = MaterialTheme.colorScheme.onPrimary,
),
actions = {
AnalyticsPermissionButton()
}
)
}

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.nrftoolbox.viewmodel
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel

View File

@@ -11,7 +11,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.0'
classpath 'com.android.tools.build:gradle:7.2.1'
classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

View File

@@ -8,4 +8,6 @@ dependencies {
implementation platform('com.google.firebase:firebase-bom:29.2.1')
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-crashlytics'
implementation libs.nordic.analytics
}

View File

@@ -1,22 +1,17 @@
package no.nordicsemi.android.analytics
import android.annotation.SuppressLint
import android.content.Context
import com.google.firebase.analytics.FirebaseAnalytics
import dagger.hilt.android.qualifiers.ApplicationContext
import no.nordicsemi.analytics.NordicAnalytics
import javax.inject.Inject
import javax.inject.Singleton
@SuppressLint("MissingPermission")
@Singleton
class AppAnalytics @Inject constructor(
@ApplicationContext
private val context: Context
private val nordicAnalytics: NordicAnalytics
) {
private val firebase by lazy { FirebaseAnalytics.getInstance(context) }
fun logEvent(event: FirebaseEvent) {
firebase.logEvent(event.eventName, event.params)
nordicAnalytics.logEvent(event.eventName, event.params)
}
}

View File

@@ -27,6 +27,7 @@ sealed class DeviceHolder(val device: BluetoothDevice) {
class IdleResult<T> : BleManagerResult<T>
class ConnectingResult<T>(device: BluetoothDevice) : DeviceHolder(device), BleManagerResult<T>
class ConnectedResult<T>(device: BluetoothDevice) : DeviceHolder(device), BleManagerResult<T>
class SuccessResult<T>(device: BluetoothDevice, val data: T) : DeviceHolder(device), BleManagerResult<T>
class LinkLossResult<T>(device: BluetoothDevice, val data: T?) : DeviceHolder(device), BleManagerResult<T>

View File

@@ -26,6 +26,7 @@ class ConnectionObserverAdapter<T> : ConnectionObserver {
override fun onDeviceConnected(device: BluetoothDevice) {
Log.d(TAG, "onDeviceConnected()")
_status.value = ConnectedResult(device)
}
override fun onDeviceFailedToConnect(device: BluetoothDevice, reason: Int) {

View File

@@ -36,20 +36,6 @@ fun CloseIconAppBar(text: String, onClick: () -> Unit) {
)
}
@Composable
fun TitleAppBar(text: String) {
SmallTopAppBar(
title = { Text(text, maxLines = 2) },
colors = TopAppBarDefaults.smallTopAppBarColors(
scrolledContainerColor = MaterialTheme.colorScheme.primary,
containerColor = colorResource(id = R.color.appBarColor),
titleContentColor = MaterialTheme.colorScheme.onPrimary,
actionIconContentColor = MaterialTheme.colorScheme.onPrimary,
navigationIconContentColor = MaterialTheme.colorScheme.onPrimary,
)
)
}
@Composable
fun LoggerBackIconAppBar(text: String, onClick: () -> Unit) {
SmallTopAppBar(

View File

@@ -2,7 +2,10 @@ package no.nordicsemi.android.theme.view.dialog
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.bps.view
import android.annotation.SuppressLint
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -10,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.bps.R
import no.nordicsemi.android.bps.data.BPSData
import no.nordicsemi.android.bps.viewmodel.BPSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
@@ -37,6 +35,7 @@ fun BPSScreen() {
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is ConnectedResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)

View File

@@ -2,7 +2,6 @@ package no.nordicsemi.android.bps.view
import no.nordicsemi.android.bps.data.BPSData
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice
internal sealed class BPSViewState

View File

@@ -14,7 +14,7 @@ import no.nordicsemi.android.bps.data.BPS_SERVICE_UUID
import no.nordicsemi.android.bps.repository.BPSRepository
import no.nordicsemi.android.bps.view.*
import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.android.utils.getDevice
import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice
@@ -59,7 +59,7 @@ internal class BPSViewModel @Inject constructor(
repository.downloadData(viewModelScope, device).onEach {
_state.value = WorkingState(it)
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.BPS))
}
}.launchIn(viewModelScope)

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.cgms.repository
import android.bluetooth.BluetoothDevice
import android.content.Intent
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -5,6 +5,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -17,10 +18,9 @@ import no.nordicsemi.android.cgms.data.CGMData
import no.nordicsemi.android.cgms.data.CGMRecord
import no.nordicsemi.android.cgms.data.CGMServiceCommand
import no.nordicsemi.android.cgms.data.RequestStatus
import no.nordicsemi.android.theme.view.BatteryLevelView
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.theme.view.BatteryLevelView
import no.nordicsemi.android.theme.view.SectionTitle
import androidx.compose.material3.CircularProgressIndicator
@Composable
internal fun CGMContentView(state: CGMData, onEvent: (CGMViewEvent) -> Unit) {

View File

@@ -9,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.cgms.R
import no.nordicsemi.android.cgms.data.CGMData
import no.nordicsemi.android.cgms.viewmodel.CGMViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
@@ -36,6 +35,7 @@ fun CGMScreen() {
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is ConnectedResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)

View File

@@ -9,11 +9,11 @@ import no.nordicsemi.android.analytics.AppAnalytics
import no.nordicsemi.android.analytics.Profile
import no.nordicsemi.android.analytics.ProfileConnectedEvent
import no.nordicsemi.android.cgms.data.CGMS_SERVICE_UUID
import no.nordicsemi.android.cgms.repository.CGMRepository
import no.nordicsemi.android.cgms.data.CGMServiceCommand
import no.nordicsemi.android.cgms.repository.CGMRepository
import no.nordicsemi.android.cgms.view.*
import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.android.utils.getDevice
import no.nordicsemi.ui.scanner.ScannerDestinationId
@@ -39,7 +39,7 @@ internal class CGMViewModel @Inject constructor(
repository.data.onEach {
_state.value = WorkingState(it)
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.CGMS))
}
}.launchIn(viewModelScope)

View File

@@ -9,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.csc.R
import no.nordicsemi.android.csc.data.CSCData
import no.nordicsemi.android.csc.viewmodel.CSCViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
@@ -36,6 +35,7 @@ fun CSCScreen() {
is WorkingState -> when (state.cscManagerState.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(OnDisconnectButtonClick) }
is ConnectedResult -> DeviceConnectingView { viewModel.onEvent(OnDisconnectButtonClick) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)

View File

@@ -5,15 +5,11 @@ import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import no.nordicsemi.android.csc.R
import no.nordicsemi.android.csc.data.WheelSize
import no.nordicsemi.android.material.you.NordicTheme
import no.nordicsemi.android.theme.view.dialog.FlowCanceled
import no.nordicsemi.android.theme.view.dialog.ItemSelectedResult
import no.nordicsemi.android.theme.view.dialog.StringListDialog
import no.nordicsemi.android.theme.view.dialog.StringListDialogConfig
import no.nordicsemi.android.theme.view.dialog.StringListDialogResult
import no.nordicsemi.android.theme.view.dialog.toAnnotatedString
import no.nordicsemi.android.utils.exhaustive
@Composable
internal fun SelectWheelSizeDialog(onEvent: (StringListDialogResult) -> Unit) {

View File

@@ -10,9 +10,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.csc.R
import no.nordicsemi.android.csc.data.CSCData
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.theme.view.BatteryLevelView
import no.nordicsemi.android.theme.view.KeyValueField
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.theme.view.SectionTitle
@Composable

View File

@@ -12,7 +12,7 @@ import no.nordicsemi.android.csc.data.CSC_SERVICE_UUID
import no.nordicsemi.android.csc.repository.CSCRepository
import no.nordicsemi.android.csc.view.*
import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.android.utils.getDevice
import no.nordicsemi.ui.scanner.ScannerDestinationId
@@ -38,7 +38,7 @@ internal class CSCViewModel @Inject constructor(
repository.data.onEach {
_state.value = _state.value.copy(cscManagerState = WorkingState(it))
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.CSC))
}
}.launchIn(viewModelScope)

View File

@@ -2,14 +2,10 @@ package no.nordicsemi.android.gls.details.view
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.*
import no.nordicsemi.android.gls.R
import no.nordicsemi.android.gls.data.MedicationUnit
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Carbohydrate
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Meal
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Tester
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Health
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Medication
import no.nordicsemi.android.gls.data.ConcentrationUnit
import no.nordicsemi.android.gls.data.MedicationUnit
import no.nordicsemi.android.gls.data.SampleLocation
@Composable

View File

@@ -7,6 +7,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -22,9 +23,8 @@ import no.nordicsemi.android.gls.data.GLSRecord
import no.nordicsemi.android.gls.data.RequestStatus
import no.nordicsemi.android.gls.data.WorkingMode
import no.nordicsemi.android.gls.main.viewmodel.GLSViewModel
import androidx.compose.material3.CircularProgressIndicator
import no.nordicsemi.android.theme.view.BatteryLevelView
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.theme.view.BatteryLevelView
import no.nordicsemi.android.theme.view.SectionTitle
@Composable

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.gls.main.view
import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -10,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.gls.R
import no.nordicsemi.android.gls.data.GLSData
import no.nordicsemi.android.gls.main.viewmodel.GLSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
@@ -37,6 +35,7 @@ fun GLSScreen() {
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is ConnectedResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)

View File

@@ -1,19 +1,21 @@
package no.nordicsemi.android.gls.main.viewmodel
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import no.nordicsemi.android.analytics.AppAnalytics
import no.nordicsemi.android.analytics.Profile
import no.nordicsemi.android.analytics.ProfileConnectedEvent
import no.nordicsemi.android.gls.GlsDetailsDestinationId
import no.nordicsemi.android.gls.repository.GLSRepository
import no.nordicsemi.android.gls.data.GLS_SERVICE_UUID
import no.nordicsemi.android.gls.main.view.*
import no.nordicsemi.android.gls.repository.GLSRepository
import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.android.utils.getDevice
import no.nordicsemi.ui.scanner.DiscoveredBluetoothDevice
@@ -61,7 +63,7 @@ internal class GLSViewModel @Inject constructor(
repository.downloadData(viewModelScope, device).onEach {
_state.value = WorkingState(it)
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.GLS))
}
}.launchIn(viewModelScope)

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.hrs.service
import android.bluetooth.BluetoothDevice
import android.content.Intent
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -9,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.hrs.R
import no.nordicsemi.android.hrs.data.HRSData
import no.nordicsemi.android.hrs.viewmodel.HRSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
@@ -36,6 +35,7 @@ fun HRSScreen() {
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is ConnectedResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)

View File

@@ -12,7 +12,7 @@ import no.nordicsemi.android.hrs.data.HRS_SERVICE_UUID
import no.nordicsemi.android.hrs.service.HRSRepository
import no.nordicsemi.android.hrs.view.*
import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.android.utils.getDevice
import no.nordicsemi.ui.scanner.ScannerDestinationId
@@ -39,7 +39,7 @@ internal class HRSViewModel @Inject constructor(
val zoomIn = (_state.value as? WorkingState)?.zoomIn ?: false
_state.value = WorkingState(it, zoomIn)
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.HRS))
}
}.launchIn(viewModelScope)

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.hts.repository
import android.bluetooth.BluetoothDevice
import android.content.Intent
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -12,9 +12,9 @@ import androidx.compose.ui.unit.dp
import no.nordicsemi.android.hts.R
import no.nordicsemi.android.hts.data.HTSData
import no.nordicsemi.android.material.you.RadioButtonGroup
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.theme.view.BatteryLevelView
import no.nordicsemi.android.theme.view.KeyValueField
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.theme.view.SectionTitle
@Composable

View File

@@ -9,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.hts.R
import no.nordicsemi.android.hts.data.HTSData
import no.nordicsemi.android.hts.viewmodel.HTSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
@@ -36,6 +35,7 @@ fun HTSScreen() {
is WorkingState -> when (state.htsManagerState.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is ConnectedResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)

View File

@@ -12,7 +12,7 @@ import no.nordicsemi.android.hts.data.HTS_SERVICE_UUID
import no.nordicsemi.android.hts.repository.HTSRepository
import no.nordicsemi.android.hts.view.*
import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.android.utils.getDevice
import no.nordicsemi.ui.scanner.ScannerDestinationId
@@ -38,7 +38,7 @@ internal class HTSViewModel @Inject constructor(
repository.data.onEach {
_state.value = _state.value.copy(htsManagerState = WorkingState(it))
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.HTS))
}
}.launchIn(viewModelScope)

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.prx.repository
import android.bluetooth.BluetoothDevice
import android.content.Intent
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -4,6 +4,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.HighlightOff
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
@@ -14,10 +15,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.prx.R
import no.nordicsemi.android.theme.R as themeR
import androidx.compose.material.icons.filled.HighlightOff
import no.nordicsemi.android.material.you.ScreenSection
@Composable
fun DeviceOutOfRangeView(navigateUp: () -> Unit) {

View File

@@ -10,7 +10,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.prx.R
import no.nordicsemi.android.prx.data.PRXData
import no.nordicsemi.android.prx.viewmodel.PRXViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
@@ -37,6 +36,7 @@ fun PRXScreen() {
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is ConnectedResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceOutOfRangeView { viewModel.onEvent(DisconnectEvent) }
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)

View File

@@ -12,7 +12,7 @@ import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.prx.data.PRX_SERVICE_UUID
import no.nordicsemi.android.prx.repository.PRXRepository
import no.nordicsemi.android.prx.view.*
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.android.utils.getDevice
import no.nordicsemi.ui.scanner.ScannerDestinationId
@@ -38,7 +38,7 @@ internal class PRXViewModel @Inject constructor(
repository.data.onEach {
_state.value = WorkingState(it)
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.PRX))
}
}.launchIn(viewModelScope)

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.rscs.repository
import android.bluetooth.BluetoothDevice
import android.content.Intent
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -9,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.rscs.R
import no.nordicsemi.android.rscs.data.RSCSData
import no.nordicsemi.android.rscs.viewmodel.RSCSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
@@ -36,6 +35,7 @@ fun RSCSScreen() {
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is ConnectedResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)

View File

@@ -12,7 +12,7 @@ import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.rscs.data.RSCS_SERVICE_UUID
import no.nordicsemi.android.rscs.repository.RSCSRepository
import no.nordicsemi.android.rscs.view.*
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.android.utils.getDevice
import no.nordicsemi.ui.scanner.ScannerDestinationId
@@ -38,7 +38,7 @@ internal class RSCSViewModel @Inject constructor(
repository.data.onEach {
_state.value = WorkingState(it)
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.RSCS))
}
}.launchIn(viewModelScope)

View File

@@ -26,12 +26,10 @@ import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattService
import android.content.Context
import android.text.TextUtils
import android.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.withContext
import no.nordicsemi.android.ble.BleManager
import no.nordicsemi.android.ble.WriteRequest
import no.nordicsemi.android.ble.common.callback.battery.BatteryLevelResponse

View File

@@ -1,6 +1,5 @@
package no.nordicsemi.android.uart.repository
import android.bluetooth.BluetoothDevice
import android.content.Intent
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -1,6 +1,8 @@
package no.nordicsemi.android.uart.view
import androidx.compose.foundation.*
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan

View File

@@ -38,6 +38,7 @@ fun UARTScreen() {
is WorkingState -> when (state.uartManagerState.result) {
is IdleResult,
is ConnectingResult -> Scroll { DeviceConnectingView { viewModel.onEvent(DisconnectEvent) } }
is ConnectedResult -> Scroll { DeviceConnectingView { viewModel.onEvent(DisconnectEvent) } }
is DisconnectedResult -> Scroll { DeviceDisconnectedView(Reason.USER, navigateUp) }
is LinkLossResult -> Scroll { DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp) }
is MissingServiceResult -> Scroll { DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp) }

View File

@@ -8,10 +8,9 @@ import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import no.nordicsemi.android.analytics.*
import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.service.ConnectedResult
import no.nordicsemi.android.service.IdleResult
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.uart.data.*
import no.nordicsemi.android.uart.data.UARTPersistentDataSource
import no.nordicsemi.android.uart.repository.UARTRepository
import no.nordicsemi.android.uart.view.*
import no.nordicsemi.android.utils.exhaustive
@@ -43,7 +42,7 @@ internal class UARTViewModel @Inject constructor(
}
_state.value = _state.value.copy(uartManagerState = WorkingState(it))
(it as? SuccessResult)?.let {
(it as? ConnectedResult)?.let {
analytics.logEvent(ProfileConnectedEvent(Profile.UART))
}
}.launchIn(viewModelScope)

View File

@@ -15,10 +15,11 @@ dependencyResolutionManagement {
library('nordic-log', 'no.nordicsemi.android:log:2.3.0')
version('commonlibraries', '1.0.8')
version('commonlibraries', '1.0.11')
library('nordic-ui-scanner', 'no.nordicsemi.android.common', 'uiscanner').versionRef('commonlibraries')
library('nordic-navigation', 'no.nordicsemi.android.common', 'navigation').versionRef('commonlibraries')
library('nordic-theme', 'no.nordicsemi.android.common', 'theme').versionRef('commonlibraries')
library('nordic-analytics', 'no.nordicsemi.android.common', 'analytics').versionRef('commonlibraries')
library('nordic-ui-logger', 'no.nordicsemi.android.common', 'uilogger').versionRef('commonlibraries')
library('localbroadcastmanager', 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0')