@@ -28,11 +28,15 @@ import androidx.compose.foundation.background
28
28
import androidx.compose.foundation.layout.Arrangement
29
29
import androidx.compose.foundation.layout.Box
30
30
import androidx.compose.foundation.layout.Column
31
+ import androidx.compose.foundation.layout.PaddingValues
31
32
import androidx.compose.foundation.layout.Row
33
+ import androidx.compose.foundation.layout.fillMaxHeight
32
34
import androidx.compose.foundation.layout.fillMaxSize
33
35
import androidx.compose.foundation.layout.fillMaxWidth
34
36
import androidx.compose.foundation.layout.padding
35
37
import androidx.compose.foundation.layout.width
38
+ import androidx.compose.foundation.lazy.LazyColumn
39
+ import androidx.compose.foundation.lazy.items
36
40
import androidx.compose.foundation.rememberScrollState
37
41
import androidx.compose.foundation.shape.RoundedCornerShape
38
42
import androidx.compose.foundation.verticalScroll
@@ -46,8 +50,10 @@ import androidx.compose.material3.Surface
46
50
import androidx.compose.material3.Text
47
51
import androidx.compose.material3.TextButton
48
52
import androidx.compose.runtime.Composable
53
+ import androidx.compose.runtime.LaunchedEffect
49
54
import androidx.compose.runtime.MutableState
50
55
import androidx.compose.runtime.getValue
56
+ import androidx.compose.runtime.mutableStateListOf
51
57
import androidx.compose.runtime.mutableStateOf
52
58
import androidx.compose.runtime.remember
53
59
import androidx.compose.runtime.setValue
@@ -58,6 +64,11 @@ import androidx.compose.ui.text.font.FontWeight
58
64
import androidx.compose.ui.unit.dp
59
65
import androidx.core.content.ContextCompat
60
66
import androidx.lifecycle.ViewModelProvider
67
+ import kotlinx.coroutines.Dispatchers
68
+ import kotlinx.coroutines.isActive
69
+ import kotlinx.coroutines.withContext
70
+ import java.io.BufferedReader
71
+ import java.io.InputStreamReader
61
72
62
73
/* * Sample activity to test the TFLite C API. */
63
74
class MainActivity : ComponentActivity () {
@@ -155,6 +166,8 @@ class MainActivity : ComponentActivity() {
155
166
StatusSection ()
156
167
Divider (modifier = Modifier .padding(vertical = 16 .dp))
157
168
ResultsSection ()
169
+ Divider (modifier = Modifier .padding(vertical = 16 .dp))
170
+ LogcatScreen ()
158
171
}
159
172
}
160
173
@@ -279,8 +292,10 @@ class MainActivity : ComponentActivity() {
279
292
val result by mainViewModel.resultState
280
293
Column (
281
294
modifier = Modifier
295
+ .fillMaxHeight(0.5f )
282
296
.fillMaxWidth()
283
297
.verticalScroll(rememberScrollState())
298
+
284
299
) {
285
300
Text (
286
301
text = result,
@@ -378,114 +393,45 @@ class MainActivity : ComponentActivity() {
378
393
}
379
394
}
380
395
381
- // @Composable
382
- // fun ModelSelectionSection() {
383
- // val modelList by mainViewModel.tfliteFileNamesState
384
- // Surface(
385
- // modifier = Modifier
386
- // .fillMaxWidth()
387
- // .padding(horizontal = 16.dp, vertical = 8.dp),
388
- // color = Color(0xFFC4C4C4),
389
- // shape = RoundedCornerShape(8.dp),
390
- // ) {
391
- // Row(
392
- // modifier = Modifier
393
- // .fillMaxWidth()
394
- // .padding(horizontal = 16.dp, vertical = 8.dp), // Content padding
395
- // verticalAlignment = Alignment.CenterVertically
396
- // ) {
397
- // Text(
398
- // text = "SELECT MODEL",
399
- // modifier = Modifier
400
- // .width(130.dp),
401
- // color = Color(0xFFFFFFFF),
402
- // style = MaterialTheme.typography.bodyMedium.copy(
403
- // fontWeight = FontWeight.Bold
404
- // )
405
- // )
406
- // DropdownMenuComponent(
407
- // items = modelList,
408
- // selectedItemState = mainViewModel.selectedTfLiteFilename,
409
- // modifier = Modifier.weight(5f)
410
- // )
411
- // }
412
- // }
413
- //
414
- // }
415
-
416
- // @Composable
417
- // fun LogViewer() {
418
- // val items by mainViewModel.eventsFlow.collectAsStateWithLifecycle()
419
- // LazyColumn (
420
- // modifier = Modifier
421
- // .fillMaxSize()
422
- // .background(Color.LightGray)
423
- // ) {
424
- // item {
425
- // Text(
426
- // text="Hellooo",
427
- // modifier = Modifier.padding(vertical = 4.dp)
428
- // )
429
- // }
430
- // items(items) { item ->
431
- // Text(
432
- // text=item,
433
- // modifier = Modifier.padding(vertical = 4.dp)
434
- // )
435
- // }
436
- //
437
- // }
438
- // }
439
-
440
- // private fun logEvent(message: String, logMessages: MutableList<String>, throwable: Throwable? = null) {
441
- // Log.e(TAG, message, throwable)
442
- // logMessages.add(message)
443
- // throwable?.let {
444
- // logMessages.add("${it.javaClass.canonicalName}: ${it.message}")
445
- // logMessages.addAll(it.stackTrace.map { stackElement -> stackElement.toString() })
446
- // }
447
- // }
448
- //
449
- // private fun getFileArrayAdapter(files: ArrayList<File>): ArrayAdapter<File> {
450
- // return object : ArrayAdapter<File>(this, android.R.layout.simple_spinner_item, files) {
451
- // override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
452
- // val view = super.getView(position, convertView, parent)
453
- // val textView: TextView = view.findViewById(android.R.id.text1)
454
- // textView.text = getItem(position)?.name
455
- // return view
456
- // }
457
- //
458
- // override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
459
- // val view = super.getDropDownView(position, convertView, parent)
460
- // val textView: TextView = view.findViewById(android.R.id.text1)
461
- // textView.text = getItem(position)?.name
462
- // return view
463
- // }
464
- // }.apply {
465
- // setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
466
- // }
467
- // }
468
-
469
- // class SharedResource {
470
- // private val lock = Object()
471
- //
472
- // fun waitForSignalWithTimeout(timeoutMillis: Long): Boolean {
473
- // val startTime = System.currentTimeMillis()
474
- // synchronized(lock) {
475
- // try {
476
- // lock.wait(timeoutMillis) // Wait for the signal or timeout
477
- // } catch (e: InterruptedException) {
478
- // Thread.currentThread().interrupt() // Restore interrupt status
479
- // return false
480
- // }
481
- // return (System.currentTimeMillis() - startTime) < timeoutMillis
482
- // }
483
- // }
484
- //
485
- // fun sendSignal() {
486
- // synchronized(lock) {
487
- // lock.notify() // Notify the waiting thread
488
- // }
489
- // }
490
- // }
396
+ @Composable
397
+ fun LogcatScreen () {
398
+ // State list to hold log lines
399
+ val logs = remember { mutableStateListOf<String >() }
400
+
401
+ // Launch a coroutine to read from logcat
402
+ LaunchedEffect (Unit ) {
403
+ withContext(Dispatchers .IO ) {
404
+ try {
405
+ // Execute the logcat command
406
+ val process = Runtime .getRuntime().exec(" logcat tflite:V *:S" )
407
+ val reader = BufferedReader (InputStreamReader (process.inputStream))
408
+ // Continuously read new lines
409
+ while (isActive) {
410
+ val line = reader.readLine() ? : break
411
+ // Post the line to the UI thread
412
+ withContext(Dispatchers .Main ) {
413
+ logs.add(line)
414
+ // Optionally, limit the size of the logs list
415
+ if (logs.size > 1000 ) { // for example, keep only the latest 1000 lines
416
+ logs.removeAt(0 )
417
+ }
418
+ }
419
+ }
420
+ } catch (e: Exception ) {
421
+ e.printStackTrace()
422
+ }
423
+ }
424
+ }
425
+
426
+ // Display the logs in a scrollable list
427
+ LazyColumn (
428
+ modifier = Modifier .fillMaxWidth(),
429
+ contentPadding = PaddingValues (16 .dp)
430
+ ) {
431
+ items(logs) { log ->
432
+ Text (text = log)
433
+ }
434
+ }
435
+ }
436
+
491
437
}
0 commit comments