23 May, 2024

Kotlin 2.0

 Migrated the current Android project to Kotlin 2.0 and it seems that Compose has strong skipping mode enabled by default as promised. Didn't see anything about it in the announcements though.

16 March, 2024

Start using adb from terminal on MacOS

 

Add the android sdk and platform-tools to your zsh

echo 'export ANDROID_HOME=/Users/$USER/Library/Android/sdk' >> ~/.zshrc
echo 'export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools' >> ~/.zshrc

 

04 March, 2024

Jetpack Compose remove unselected tab indicator

 

use 

divider = {},

like so:

    TabRow(
selectedTabIndex = selectedTabIndex,
modifier = modifier,
containerColor = Color.Transparent,
contentColor = MaterialTheme.colorScheme.onSurface,
indicator = { tabPositions ->
TabRowDefaults.Indicator(
modifier = Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]),
height = 2.dp,
// uncomment below to customize indicator color:
// color = MaterialTheme.colorScheme.onSurface,
)
},
divider = {},
tabs = tabs,
)

 

Disable Dark Theme alltoghether

 

@AndroidEntryPoint
class MainActivity : ComponentActivity() {


@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val config = resources.configuration
config.uiMode = Configuration.UI_MODE_NIGHT_NO
resources.updateConfiguration(config, resources.displayMetrics)

03 March, 2024

Download an image to local disk and show it with Compose.

 



class DownloadImageUseCase @Inject constructor(
@ApplicationContext private val context: Context,
private val dispatchersProvider: DispatchersProvider,
) {
suspend operator fun invoke(imageUrl: String): String? = withContext(dispatchersProvider.io()) {
try {
val input = URL(imageUrl).openStream()
val fileName = imageUrl.substringAfterLast("/")
val file = File(context.filesDir, fileName)
FileOutputStream(file).use { output ->
input.copyTo(output)
}
file.absolutePath
} catch (e: Exception) {
e.printStackTrace()
null
}
}
}
 
 
viewModelScope.launch {
state.update { oldState ->
oldState.copy(
imagePath =
downloadImageUseCase(
"https://apod.nasa.gov/apod/image/2403/IM_Odysseus_landing-1100x600.png",
),
)
}
}
 

@Composable
fun DisplayImageFromDisk(imagePath: String?) {
imagePath?.let {
Image(
painter = rememberAsyncImagePainter(File(it)),
contentDescription = "Cached Image",
modifier = Modifier.fillMaxWidth()
)
}
}
 

18 December, 2023

 

 

To add a watermark to all of the images in a directory:

1. install imagemagick

sudo apt-get install imagemagick

2.  run the following script:

counter=1; total=$(ls my_files_dir/* | wc -l); for img in my_files_dir/*; do echo "Processing file $counter of $total: $img"; convert "$img" -gravity center -pointsize 35 -fill 'maroon' -draw "text 0,0 'my watermark text'" "$img"; ((counter++)); done

16 December, 2023

09 November, 2023

 The UiState handling approach I like the most so far is the one used by the github project Dogiz :

1. there is a UiState sealed Interface + extention functions to map the Flow to the UiState
2. a UiStateWrapper that provides a unified view for every possible state

Nice, clean and efficient.





25 October, 2023

 Lo que aún me motiva a actualizar mis aplicaciones son las personas que las utilizan y piden ayuda. Nunca pensaba que esta sería la principal fuente de satisfacción cuando empezaba a escribir aplicaciones.

 

SpeakIt, a pesar de tener tiempo en el mercado, está viva y prospera.

 


 

06 October, 2023

Won 2nd place

 Have to urgently decide what to do with the 75$ prize. Cat-a-log won the second place, good docs and code they say!



22 September, 2023

 If Android Studio is not showing previews for markdown files, do the following:

1. Go to menu Help -> Find Action(Ctrl+Shift+A) -> Choose Boot Time Java for the IDE -> and select JetBrains Runtime with JCEF


2. Restart the IDE:



3. Now the preview should be working: