Developing Android Apps

46 readers
1 users here now

News for Android developers with the who, what, where, when and how of the Android community. News / Articles / Talks / Tools / Open source!.

founded 2 years ago
MODERATORS
26
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/DroidRamon on 2025-02-05 09:24:05+00:00.


I know one should not pass down the navController. However people just do it. (People including devs generally do stupid shit.)

I pretty much inherited an app that passes through a navController deep into each composable. To make it even worse, it also uses hiltViewModels and there isn't a single preview in the entire app. I repeat, not a single preview. I do not know how they worked on it. Most probably they used LiveEdit as some kind of hot reload. That works if you're on the dashboard and you make a quick reload after a change.

However, being 5 clicks deep in a detail graph, it becomes extremely inefficient. Each time you have to click your way through, in addition to programming the UI blindly. In any case, my job isn't just to change the colors, so I need previews. To generate previews, there is a lot of refactoring to do.

After that however, one looks at a function and thinks what am I doing here. The sheer verbosity makes me uneasy. Down there is an example of what I mean. There are 2 questions here: 1. Am I doing the right thing here? 2. What do I do with this many function parameters? (given that I will have even more)

@Composable
fun SomeScreen(
    navController: NavController,
    isMocked: Boolean = false,
    @DrawableRes placeholderImageId: Int = -1,
    viewModel: ViewModel = hiltViewModel(),
    designArgs: DesignArgs = viewModel.defaultDesignArgs,
    behaviorArgs: ListBehaviorArgs = BehaviorArgs()
) {

    SomeScreenContent(
        isMocked = isMocked,
        data = viewModel.displayedData,
        designArgs = masterDesignArgs,
        designArgs = someViewModel.designArgs,
        behaviorArgs = behaviorArgs,
        doSth = viewModel::init,
        getMockedData =  vm::doSth,
        placeholderImageId = placeholderImageId,
        onSearch = { pressReleaseViewModel.search(it) },
        wrapperState = vm.wrapperState,
        previousBackStackEntry = navController.previousBackStackEntry,
        popBackstack = navController::popBackStack,
        navigateToDetail = {
            navController.navigate(NavItems.getGetRoute(it))
        })
}

27
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/OffbeatUpbeat on 2025-02-05 06:18:29+00:00.

28
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/skydoves on 2025-02-04 09:23:53+00:00.

29
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/Marvinas-Ridlis on 2025-02-02 20:47:22+00:00.


For example measuring UI improvements seems pretty straightforward, we can measure FPS.

What about other parts, such as network request speed, latency and other things.

What else do you measure, to for example catch bottlenecks quickly? Just good ol'd RAM/CPU/NETWORK in the Profiler?

30
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/demon_slayer_002 on 2025-02-03 14:23:56+00:00.

31
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/ramtahor on 2025-02-02 15:39:24+00:00.


Hey fellow Android devs!

I've built a Jetpack Compose library that simplifies swipeable card interactions, inspired by the Tinder-style swipe UX. If you're looking to add fluid, customizable swipe gestures to your app, check it out!

🔗 GitHub Repository:

32
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/niskeykustard on 2025-02-01 15:53:23+00:00.


Just dropping this as it might be useful for anyone diving into Android security. Kontra has a set of free interactive exercises aligned with the OWASP Mobile Top 10, specifically for Android (Java). Each module digs into common threats, vulnerabilities, and best practices for secure app development. Worth checking out if you’re brushing up on mobile security or just want a structured way to learn how these vulnerabilities play out in real code.

Can be found here:

Anyone else tried it yet? Thoughts on how it compares to other training resources out there?

33
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/MosesAustria on 2025-01-31 07:46:56+00:00.


What are your predictions and thoughts and experiences for the mobile android dev job market, especially in Europe ?

Currently, I'm finishing my bachelors CS degree in Europe and thinking about to pursue my interest in mobile android development and focus on gathering in this field skills and probably getting a job here. But I don't have any idea how sustainable this is, considering the job market currently and in the future for android developers ?

Or is cross-platform the way to go for future mobile devs ? (like React Native etc...)

Would be curious what you guys are thinking about and how freshmen are valued currently in the job market for mobile android development.

34
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/TimeTuneStudio on 2025-01-30 17:15:26+00:00.


(Note: This article was first published on our blog, we hope you find it useful)

For a long time, we had a problem with user reviews in TimeTune. Although we were using the recommended In-App Review API, we received very few reviews compared to the amount of daily downloads.

Most reviews were positive, so we already knew that users like the app. But the small amount of reviews made that the pace of growth for our Google Play rating was excruciatingly slow.

What was happening? 🤔

It turns out that TimeTune doesn’t have a specific ‘winning’ moment in the app. Winning moments are those occasions where a user completes a specific action that triggers a clear sense of accomplishment and satisfaction (for example, completing a level in a game). Showing a review prompt in such occasions increases the chances of receiving a positive review.

But being a time-blocking planner, we didn’t have a perfect place to show the review prompt. Instead, we were showing it from time to time in the main screen when the user opened the app.

In other words, we were interrupting the user’s experience and workflow. And that probably lead to the review prompt being dismissed most of the time 😖

We needed a different approach.

PSYCHOLOGY TO THE RESCUE

That’s when we turned our attention to one of the most acclaimed books in the world of persuasion: ‘Influence: The Psychology Of Persuasion‘, by Robert Cialdini. If you’re a developer and haven’t read that book yet, we highly recommend it. Seriously, it’s full of ideas you can implement in your apps.

Using the principles from that book, we began to design a process where we could ask for reviews in a non-intrusive way (and if possible, increasing the ratio of positive reviews even more).

And it worked. Big time.

Here’s how we did it:

DRAWING ATTENTION

First, we needed a way to draw the user’s attention without interrupting. So on the main screen, we added a red badge to the top menu’s overflow icon:

Adding a badge to the overflow icon

Notice however how that badge is not a dot, it’s a heart. That detail, although small, is very important psychologically speaking. Besides being the start of the review path, that heart is already moving the user towards a positive frame of mind.

Also, curiosity has been aroused: “That’s not a normal badge”. All users without exception will click there to see what the heart is about. So that’s another win, because this approach will draw more clicks than the ordinary in-app review prompt.

The user is now thinking: “What could this heart be?”

FOLLOWING THE PATH

Clicking on the overflow icon opens the top submenu. Here we needed a way to direct the user towards the proper option, in this case our settings:

Leading the user towards the right option

Instead of highlighting the settings option with a different method, we used the read heart again to mark the way. At this moment, the user knows they need to ‘follow the heart’.

As they already took the first step by opening the overflow menu, the user is now invested in the process (another psychological principle). Again without exception, they will click on this second heart, which at the same time reinforces their move towards a positive frame of mind.

MAKING THE ASK

Now that the user is in the screen we want them to be (you’ll see why soon), it’s time to ask for the review. However, we’re not doing it directly 😮

If we showed an ordinary ‘Please give us a review’ message, the user would probably dismiss the dialog like they did when they saw the old in-app review prompt (also, a message like that could have been shown in the main screen).

Instead, we’re showing the following message:

Asking for support

Notice how we’re still showing the red heart, but bigger. This heart symbolizes now several things at the same time:

  • Our love for the user.
  • That we’re asking for their support in the kindest way.
  • Most importantly, the love the user feels for the app.

We also made the dialog not cancelable, so the user needs to click on ‘Got it’ to dismiss it. This seemingly unimportant detail records in the user’s mind that they indeed got the message, reinforcing their commitment to this process (a good alternative would be to show something like ‘I will do my best’ in the button).

Remember, this dialog is not an interrupting dialog. It’s the user who initiated the process and ‘followed the heart’.

So, since they already clicked on ‘Got it’ and they are in a positive frame of mind, it’s easy to scroll a bit and see what this is all about.

GAMIFYING TASKS

This is the final and most important step. Here is where the persuasion principles shine.

Here’s what appears at the end of our settings screen:

Gamifying the process

The header in this section is crucial. Besides using the heart again to mark the final step, we switched to the first person to express the user’s thoughts. Why is this important?

The use of the first person in that sentence filters out all those users who don’t identify with it. This happens unconsciously. A user who doesn’t like the app won’t feel motivated to leave a review here (even a negative one). But a user who likes it will.

Besides, in psychology, it’s a well known fact that writing down a statement reinforces your commitment with it (for example, writing your personal goals on paper). So using the first person in that sentence makes it seem as if the user wrote it themselves, reaffirming their commitment ✍️

Finally, we also added gamification components, like a ‘Done’ button in each support task and a progress bar to indicate how many of the tasks are completed.

Notice how the first task is marked as completed by default. ‘Install the app’… duh. But persuasion principles tell us that showing a progression as already started motivates the user to keep going with it, so that’s what we’re doing here ✔️

Also, why ask for several support tasks and not just one? Because if a user cannot complete all tasks (especially the last one, upgrading to premium), they’ll probably think: “Well, the least I can do is leave a review”.

👉 Keep in mind that users will click more on the top tasks and less on the bottom ones, so put the most important task at the top (well, the most important task would be upgrading to premium, but we have dedicated buttons for that in several screens, so here we ask for a review).

In any case, the gamification instinct will lead users to complete as many tasks as possible. So use this approach to show all the support tasks that can help with your project (in our case, we’d like users to try our other apps).

If a user completes all tasks, it would be a good idea to give them some kind of prize or reward. That would reinforce their satisfaction and strengthen the bond with your app (that’s something we still need to implement).

RESULTS

After publishing the new approach (even in beta), we started to see results immediately. Not only did the amount of reviews increase a lot, but all the reviews were extremely positive! 🎉

And maybe not surprisingly, the amount of negative reviews decreased too. That probably happened because of two factors:

  • With the old approach (the in-app review prompt), some users left negative reviews because we were interrupting their workflow; now that we’re not interrupting, those reviews are not happening anymore.
  • The in-app review prompt also appeared to all users -happy and unhappy-, while now we’re targeting happy users only (we still want feedback from unhappy ones, but preferably through email).

We liked the new approach so much that we ended up removing the in-app review API completely! However, depending on the type of app you’re developing, it may be better to use one approach or the other (or even a combination of both). You need to test and measure.

BE HONEST

Using persuasion and psychology principles in your app is not a license to trick your users in deceiving ways. That never works, users are not dumb.

Be honest, treat your users with respect and they will love you for it ❤️

We hope this article can bring new ideas to your projects. Those ideas certainly worked for us.

Cheers! 🥰

35
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/sinasamaki on 2025-01-30 07:08:45+00:00.

36
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/StatusWntFixObsolete on 2025-01-30 00:52:31+00:00.

37
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/buzz009me on 2025-01-30 03:37:22+00:00.


Hey guys, this discussion came up and like title, I was pretty surprised they weren't using Alias or scrcpy. So I showed them my aliases and workflow and they thought it was very helpful. It gave me idea to share with you guys too. So I created this repo with alias that I use (modified to be generic). I also made a youtube video to share these and some other tips. Hope it helps to improve your daily workflow a little bit.

38
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/Consistent_Hurry on 2025-01-29 21:51:40+00:00.


Fellow Android dev here.

If you work on an Android app that requires entering a 2FA code that's been emailed to me, for the love of God(s), PLEASE maintain the app's state. Use Workflow, Circuit, Mavericks, some other library, or maintain it yourself. I don't care.

If I go to my email inbox on my phone to view the code and then come back to the app, the app shouldn't reset and begin at the start of the authentication flow again. I have to enter my phone number and so on ♻️ Especially if I don't have access to view my inbox on a laptop or something, it's so annoying. It's not hard, but the only trick I've found is to use Android split screen to view Gmail and the other app at the same time.

Or am I not thinking of a security reason to not doing this?

39
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/spaaarky21 on 2025-01-29 07:35:22+00:00.


I've been learning Compose for a couple weeks. It's still a little early for me to have an informed opinion of it but my experience so far has me wondering…

Is Compose the future of Android development, where Google and the Android community will invest 99% of its effort and Fragment-based development will become increasingly neglected? Or is Compose simply an alternative for those who prefer its style of development and both will be maintained well into the future? Presenters at events like I/O are always excited about Compose (of course) but has Google said anything "official" about it being the standard going forward, like they did with Kotlin over Java?

40
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/newguytolife101 on 2025-01-28 20:51:43+00:00.


Hey guys,

I’m diving back into Android development after about 4-5 years away, and wow, a lot has changed! One thing that’s stood out is Jetpack Compose. While it seems like a big shift, I’ve noticed mixed opinions about it from other Android devs online. Should I invest time in learning and building with Compose right now?

At the moment I just left my previous company and thought now I should strive myself into trying to have my next dev be in Android/Mobile space. Funny enough I actually was pretty bummed when I first got hired in my old job and realized I wasn't going to be working on Android. Here’s a throwback to a post I made when I was disappointed about not starting in the Android space back then lol: link Anyways my general understanding of Android rn is probably like 5-6 years outdated now especially since I haven't really been dabbling with it as much as I wanted. Since then, I’ve worked as a full-stack developer for 4 years, with a focus on frontend (angular/typescript) this past year.

My plan going forward is to make 2-4 Android apps to hopefully showcase my understanding of Android even though I don't have work experience for it . Alongside Compose, are there any other major developments, tools, or best practices I should catch up on? I’d really appreciate guidance on what’s important to learn or integrate into my projects to make them stand out in today’s job market as well as anything else that might help me transition to being an Android developer without the work experience under my belt.

41
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/Ok_Issue_6675 on 2025-01-28 20:01:46+00:00.


This post discusses:

lessons learned while optimizing native Android AI code for wake word detection, significantly reducing battery consumption. The solution described involves a combination of open-source ONNX Runtime and proprietary optimizations by DaVoice.

  1. ONNX Runtime: A fully open-source library that was customized and compiled with specific Android hardware optimizations for improved performance.
  2. DaVoice Product: Available for free use by independent developers for personal projects, with paid plans for enterprise users.

The links below include:

  1. Documentation and guides on optimizing ONNX Runtime for Android with hardware-specific acceleration.
  2. Link to ONNX runtime open source - the ONNX open source that can be cross compiled to different Android hardware architecture s.
  3. Links to DaVoice.io proprietary product and GitHub repository, which includes additional tools and implementation details.

The Post:

Open Microphone, continuous audio processing with AI running "on-device"??? sounds like a good recipe for overheating devices and quickly drained battery.

But we had to do it, as our goal was to run several "wake word" detection models in parallel on an Android devices, continuously processing audio.

Our initial naive-approach took ~0.41% battery per minute or ~25% per hour and the device heat up very quickly - providing only 4 hours of battery life time.

After a long journey of researching, optimizing, experimentation and debugging on different hardware (with lots of nasty crashes), we managed to reduce battery consumption to 0.02% per minute, translating to over 83 hours of runtime*.*

MOST SIGNIFICANT OPTIMIZATION - MAIN LESSON LEARNED - CROSS-COMPILING WITH SPECIFIC HW OPTIMIZATION

We took native open source Framework such as ONNX and compiled them to utilize most known CPU and GPU Android architecture optimizations.

We spent significant amount of time cross compiling AI Libraries for "Android ARM" architecture and different GPU’s such as Qualcomm QNN.

Here is the how-to from ONNX:

The goal was to utilize as much hardware acceleration as possible and it did the work! Drastically reduce power consumption.

But, it wasn’t easy, most of the builds crashed, the reasons were vague and hard to understand. determining if a specific HW/GPU actually exists on a device was challenging. Dealing with many dynamic and static libraries and understand where the fault came from - HW, library, linking, or something else was literally driving us crazy in some cases.

But at the end it was worth it. We can now detect multiple wake words at a time and use this for not just for "hot word" but also for "Voice to Intent" and "Phrase Recognition" keeping battery life time almost as in idle mode.

Links:

Hope this is interesting or helpful.

42
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/imaginativeshohag on 2025-01-28 19:55:04+00:00.


Hello everyone! 👋

I’m thrilled to share Why Not Compose!, one of my open-source showcase projects today. 🎉

What is “Why Not Compose!”?

It’s a collection of animations, compositions, and UIs built using Jetpack Compose—a sort of Compose cookbook, showcase, or playground. As an early adopter of Jetpack Compose, I’ve always enjoyed exploring its potential. While following official examples like the Now in Android open-source app, I found some implementations a bit complex. So, I was inspired to simplify and reimplement features in my way, storing finalized implementations in this repo.

The result? A repository that not only aids me in daily tasks but also allows me to quickly share implementations with my colleagues. I hope this resource can help you, too! 😊

Check it out

Notable Features

  • MVVM Pattern
  • Navigation Component
  • Hilt
  • Dark mode support
  • Ready-to-use Compositions
  • Material 3
  • Gradle Kotlin DSL
  • CI/CD
  • ktlint, CodeQL
  • Baseline profile generation
  • Fastlane for Play Store publishing
  • Animated Splash Screen (Introduced in Android 12)

App Sections

  1. Animations: Explore animations built with Compose APIs.
  2. Compositions: Ready-to-use Compose components—App bar, badge, list, dialogs, swipe-to-refresh, swipe-to-dismiss, etc.
  3. UIs: Prebuilt UI screens—Map view, OTP verification, web view, pager, and more.
  4. Tutorials: 15+ real-world examples of Compose solutions.

Screenshots

Some screenshots from the repository (Part 1)

Some screenshots from the repository (Part 2)

Tutorial Highlights

  • Counter (Beginner): Simple counter implementation.
  • Counter with ViewModel (Beginner): Counter with a ViewModel.
  • AnimatedVisibility (Beginner): Animate UI using AnimatedVisibility.
  • Lottie (Beginner): Explore Lottie animations.
  • Select and Crop Image (Intermediate): Pick and crop images with uCrop.
  • Capture and Crop Image (Intermediate): Capture images via the camera app and crop using uCrop.
  • Permission Handling (Beginner): Handle runtime permissions in Compose.
  • Data Fetch & Paging (Advanced): Use the Android Jetpack Paging library.
  • Tic-Tac-Toe (Advanced): A simple game with basic AI.
  • ExoPlayer (Advanced): Integrate ExoPlayer with Compose.
  • CMS (Advanced): Example of a Content Management System using “Go REST” APIs.
  • Memory and Storage Caching
  • Deep Link (Intermediate): Handle deep links.
  • Navigation Data Pass (Intermediate): Pass data with the Navigation component.
  • Reactive Model (Beginner): Reactive MVVM example.
  • Baseline Profiles (Intermediate): Check install status using ProfileVerifier.
  • Barcode Scanner (Intermediate): Scan barcodes using Google Code Scanner and ML Kit.

How You Can Help

  • Suggestions: I’d love your ideas for features or improvements.
  • Contributions: Feel free to clone, fork, and contribute!

Please let me know what you think, and I hope you find this repository as useful as I do. 🚀

Happy coding! 🧑‍💻

43
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/skydoves on 2025-01-28 12:06:39+00:00.

44
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/thejasiology on 2025-01-28 07:21:29+00:00.


There was a requirement at my workplace where we had to draw something like following:

Design to achieve

I thought it would be simple enough to just call a draw arc function where I could pass corner sizes to it. But funnily enough, android (or compose shall I say) does not provide an API to do so! This resulted in me going around trying to find a solution myself. Compose only provides stroke cap while drawing arcs which does not respect the available sweep, does not let us modify each corner and does not respect angle of the arc at each point.

And so I created an extension function which would help us achieve the above and added it to the following stack overflow question:

The above linked implementation takes cares of various edge cases where there may not be enough space available to draw a corner, as well as taking care of cases where one corner might require more space than other in case total space is not enough to render both.

We tested the logic out with animations and so far we have no performance issues whatsoever.

Result

45
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/Alexorla on 2025-01-27 18:18:26+00:00.

46
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/dayanruben on 2025-01-27 10:31:16+00:00.

47
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/dayanruben on 2025-01-25 10:53:28+00:00.

48
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/sbifido on 2025-01-25 01:05:49+00:00.


49
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/dayanruben on 2025-01-24 18:31:15+00:00.

50
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/androiddev by /u/nomanr on 2025-01-23 10:36:34+00:00.

view more: ‹ prev next ›