-
Notifications
You must be signed in to change notification settings - Fork 16
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
When I update items
in BarChartView
with number of entries larger then before (e.g. from 7 to 24) I get IndexOutOfBoundsException
#140
Comments
Ok, yeah, it should have been a separate issue. As I edited the comment, crash appears when number of entries changes in any way (not only increases) (in the logs below going from 30 to 7). logs
code causing the issue (a bit of a mess since I'm just starting)package nodomain.pacjo.healthconnect.viewer
import [...]
class MainActivity : ComponentActivity() {
// TODO: move this out too
private val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()
private val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(StepsRecord::class),
// TODO: add the rest
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
// TODO: move this somewhere else
val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
if (granted.containsAll(PERMISSIONS)) {
Toast.makeText(this, "Permissions granted!", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "Missing permissions!", Toast.LENGTH_SHORT).show()
}
}
suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient): Boolean {
val granted = healthConnectClient.permissionController.getGrantedPermissions()
if (!granted.containsAll(PERMISSIONS))
requestPermissions.launch(PERMISSIONS)
else
return true
return false
}
setContent {
val healthConnectClient = getHealthConnectClient(LocalContext.current)
var permissionsGranted = false
LaunchedEffect(healthConnectClient) {
if (healthConnectClient != null) {
permissionsGranted = checkPermissionsAndRun(healthConnectClient)
}
}
AppTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding)
) {
Text(text = "Are permissions granted?: $permissionsGranted")
Graph(
healthConnectClient = healthConnectClient!!, // TODO: check non-null
defaultPeriod = GraphPeriod.MONTH
)
}
}
}
}
}
}
/***
* Gets [HealthConnectClient] or returns `null` if unsupported
*/
private fun getHealthConnectClient(context: Context): HealthConnectClient? {
val providerPackageName = "com.google.android.apps.healthdata"
val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName)
if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
return null
}
if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
// Optionally redirect to package installer to find a provider, for example:
val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding"
context.startActivity(
Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(uriString)
putExtra("overlay", true)
putExtra("callerId", context.packageName)
}
)
return null
}
return HealthConnectClient.getOrCreate(context)
}
enum class GraphPeriod {
DAY,
WEEK,
MONTH
}
@Composable
fun Graph(healthConnectClient: HealthConnectClient, defaultPeriod: GraphPeriod = GraphPeriod.WEEK) {
var period by remember { mutableStateOf(defaultPeriod) }
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
PeriodSelector(defaultPeriod) { selection ->
period = selection
}
GenericGraph(healthConnectClient, period)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PeriodSelector(startPeriod: GraphPeriod, onClick: (GraphPeriod) -> Unit) {
val options = GraphPeriod.entries
SingleChoiceSegmentedButtonRow {
options.forEachIndexed { index, period ->
SegmentedButton(
selected = (period == startPeriod),
onClick = { onClick(period) }, // TODO: simplify
shape = SegmentedButtonDefaults.itemShape(index = index, count = options.size),
) {
Text(
text = when (period) {
GraphPeriod.DAY -> "Day"
GraphPeriod.WEEK -> "Week"
GraphPeriod.MONTH -> "Month"
}
)
}
}
}
}
@Composable
fun GenericGraph(healthConnectClient: HealthConnectClient, period: GraphPeriod) {
val data = remember { mutableListOf<Float>() }
val endTime = Instant.now().truncatedTo(ChronoUnit.DAYS)
val startTime = when (period) {
GraphPeriod.DAY -> endTime
GraphPeriod.WEEK -> endTime.minus(6, ChronoUnit.DAYS)
GraphPeriod.MONTH -> endTime.minus(30, ChronoUnit.DAYS) // or 31, 28, 29? i fucking hate calendars
}
val range = when (period) {
GraphPeriod.DAY -> 0L..23L
GraphPeriod.WEEK -> 0L..6L
GraphPeriod.MONTH -> 0L..29L
}
val unit = when (period) {
GraphPeriod.DAY -> ChronoUnit.HOURS
GraphPeriod.WEEK -> ChronoUnit.DAYS
GraphPeriod.MONTH -> ChronoUnit.DAYS
}
for (i in range) {
val dayStartTime = startTime.plus(i, unit) // TODO: rename
val dayEndTime = dayStartTime.plus(1, unit) // TODO: rename
var dataPoint: Long?
runBlocking {
dataPoint = readDataPoint(healthConnectClient, StepsRecord.COUNT_TOTAL, dayStartTime, dayEndTime)
}
if (dataPoint != null) {
data.add(dataPoint!!.toFloat())
} else {
data.add(0f)
}
}
BarChartView(
dataSet = ChartDataSet(
items = data,
title = "Steps"
)
)
}
suspend fun <T : Number> readDataPoint(
healthConnectClient: HealthConnectClient,
aggregateMetric: AggregateMetric<T>,
startTime: Instant,
endTime: Instant
): T? {
try {
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(aggregateMetric),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
return response[aggregateMetric]
} catch (_: Exception) {
return null
}
} |
Thank you for the additional information! I'll fix this as soon as I find the time. Currently, I'm working on a new feature that will most likely be available next week. |
Awesome! Take you're time. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the explanation. I got
2.0.0-SNAPSHOT
working without any issues.Well, some issues, but they were also present in 1.3.1. When I update
items
inBarChartView
with number of entries larger then before (e.g. from 7 to 24) I getIndexOutOfBoundsException
Originally posted by @pacjo in #97 (comment)
The text was updated successfully, but these errors were encountered: