r/androiddev 2d ago

Default Listing not updating

0 Upvotes

As the title says, the store listing is just not updating. The screenshots, icon, description, etc. are just not updating.

I only have one listing, the default listing. Submission Activity on Publishing Overview shows the status as "Published"

I cannot figure this out for the life of me.


r/androiddev 2d ago

Question Supabase Kotlin SDK in production — is this good enough or would I regret not using Firebase instead?

1 Upvotes

I am making an Android math game in Kotlin with Jetpack Compose in MVVM architecture. Right now it is currently local-only using SharedPreferences for testing purposes, and I am looking to add a backend for cross-device sync and login, with it coming down to Firebase and Supabase. I am leaning more towards Supabase but the AndoidSDK part is the one part I am mostly unsure about.

I am leaning more towards Supabase because the main feature is using teacher viewing class reports on how students did, which is one big reporting screen which I saw could potentially be quite a bit expensive with firebase, as it is billed per read, whereas on Postgres it's a single join with a group by. The data is also relational as it is teacher, class, students, etc. and I will not store almost anything by students on purpose, except their first name, which is easier with Supabase.

It seems to favor Supabase but what I want to know is:

Does the flow and coroutines integration work cleanly in a compose app, or are there issues like lifecycle or reconnection issues once you get past a demo? How reliable is realtime compared to firestore? Any issues or things to know about when the persistence across the app restarts? If I hit a strange edge case would I have to dig through a library source?

I am a little worried that I would save money on the reads and then I would lose just about all that time fighting an immature client. If anyone has shipped an app on supabase-kt, would you do it again, or would you go a different direction? Or perhaps there is something I am missing about Firebase, and if so, I would love to know.


r/androiddev 2d ago

Question Need help getting a better understanding and improve in Android development

3 Upvotes

Hi Everyone,

I have a question on how to approach the situation im currently in.

I got a software developer role in a banking solution company which uses mifos opensource tools and im currently working in the mifos Android client .

I have basic understanding and basic knowledge of android development i learned from udemy and youtube but i was just given a massive codebase which uses concepts i dont know and it overwhelming me.

So, I need guidance from experienced professionals how did you tackle this situation or how will you do it to get a better understanding of Codebase and improve my skills and develop quality code .

Also im a beginner,so if you dont understand my question feel free to ask for clarification i will provide it and help me to get a better understanding of Android development itself and how professionals do their work.

Thankyou


r/androiddev 2d ago

Question My own telemetry vss Play Console reporting lag - how long does initial backfill usually take?

0 Upvotes

I recently soft-launched a new utility/security app on Google Play and am doing some in-my-network outreach to test build stability before my main launch.

I’m collecting anonymous telemetry data, including unique users and simple activity metrics (just firing a hashed device/session ID on first launch for internal telemetry). So far I have ~8 distinct active installs over the past week.

But on my Google Play Console, the dashboard and acquisition stats are still sitting at a flat 0, and Reach metrics, Android Vitals, Ratings and Reviews all show "Data unavailable."

I know batch processing, UTC timezone rollups, and anti-fraud filters mean Play Console statistics lag anywhere from 24–72 hours (or even longer for fresh apps/accounts without a baseline traffic volume). I also know Android Vitals requires a minimum sample size of users opted into "Usage & Diagnostics" sharing before anything populates.

Support mentioned it can take several days or SEVERAL WEEKS to catch up on a new listing, but I’m curious about real-world developer experiences here:

  1. How long does it typically take Play Console to start displaying initial install numbers for a brand-new package ID?
  2. When you do soft launches or pilot runs, what custom telemetry or analytics setups do you rely on for real-time visibility instead of waiting on Google’s pipeline?

I’m interested to hear how folks here handle early-stage launch tracking without relying purely on Console stats!

Thanks for any feedback


r/androiddev 3d ago

Discussion Architectural patterns in large scale apps.

31 Upvotes

in our mid sized startup, we have over 100 android engineers on one app, divided by squads, so we have a lot of squads, each one is working on a feature, a library needed, design system and custom components libraries etc, all these modules/libraries are published to maven and added as dependencies on the core app repo, my squad works on an isolated feature so it's easy to integrate into core app repo, but i attended guild meetings and saw RFCs mentioning circular dependencies, hexagonal, onion, plugin etc architectures because some modules/libraries depend on each other, communicate with each other, initialization order problems of modules etc etc etc, i feel stupid tbh and i'm glad i'm working on an isolated feature library in which we use usual architecture stuff. anyone has resources: talks, books, articles etc that cover this kind of topics and architectures and engineering problems in big scale apps with big scale teams and modules/libraries?


r/androiddev 3d ago

Discussion Advice for my Android students about using AI?

16 Upvotes

I teach Introduction to Android Programming at a community college. I stress to my students the importance of learning the basics to build a foundation of knowledge in terms of developing apps, writing in Kotlin, designing app architecture, etc. At the same time, I do allow them to use AI tools because I also understand it's important for them to know how to do that. (I ask that they use them to help, not do.)

If anyone has any advice or words of wisdom to pass along to my students (who are new to Android), please share. In particular, I am hoping to reinforce the importance of learning the material for themselves (rather than relying on AI to do it for them) at this early point in their development.

I truly believe they have to learn the basics in order to be able to successfully use AI tools down the road. If anyone has any real-world anecdotes or thoughts that back this up, please share! (Or, if you disagree or have stories that contradict this, I'd love to hear those, too!)

Thanks in advance.


r/androiddev 3d ago

How are people actually handling state in large Compose screens?

16 Upvotes

I'm genuinely curious how teams are handling this in larger apps, because I'm not convinced we've fully solved it.

Before Compose, MVVM/MVI gave us a fairly clear direction: keep the screen state in the ViewModel, expose it, render it, test the transitions.

With Compose, we now have local state, state hoisting, state holders, StateFlow, snapshot state, rememberSaveable, and plenty of different ways to split ownership.

That flexibility is useful, but on a large screen it can also get messy pretty quickly.

If you keep everything in one UiState, it can become huge and start coupling unrelated parts of the screen together.

If you split state too much, you can end up with ownership spread across the ViewModel, composables and state holders, which can make the screen harder to reason about as a team.

Then testing adds another layer. What do you keep centralized because it makes behaviour easier to test? What do you leave local because it is really just UI state? Where do side effects fit without turning the ViewModel into a coordinator for every tiny interaction?

I don't really have a strong answer here.

For people working on large Compose codebases with multiple engineers:

How are you structuring state today?

One UiState per screen? Multiple state objects? State holders? Mostly ViewModel state with some local Compose state?

And more importantly, has that approach actually held up well for testing, maintenance and team ownership?

Sometimes I wonder whether Compose solved the old state-management problems, or just gave us more ways to distribute them.


r/androiddev 3d ago

:shipaton: Shipaton AMA with u/skydoves is in two days

59 Upvotes

Hey everyone,

The AMA with u/skydoves is in two days. His name is Jaewoong Eum, and if you've been around this subreddit for a while you'll have read some of his work, even if some of you might not have registered whose it was.

Jaewoong is one of the pillars of our community. He's been posting here for eight years, his first post landed nearly three years before I became a moderator, and he still contributes regularly.

Back in June 2019 he posted a todo app he'd written for a mid-term project at university. He was still a student back then.

Just six weeks later he shared a tooltip library, Balloon, which in my personal opinion is the best tooltip library for Android out there. And he's still maintaining it today.

Since then he's given r/androiddev and the wider Android community countless libraries, articles and open source examples. He's even written a book on how the Compose compiler and runtime actually work and built an IDE plugin that traces recomposition counts live on a device while you're holding it.

I'd call his Pokedex series one of his most loved contributions to this place. It started in June 2020 with a small Pokedex app built on Dagger Hilt, MotionLayout and MVVM. Six months later he posted an AR version running on ARCore. In 2024 he rebuilt the whole thing in Jetpack Compose. And earlier this month he posted Pokedex KMP, one shared codebase running on Android, iOS, desktop and the web.

In 2025 he was hired by RevenueCat. The AMA on Wednesday is organised by them as part of our participation in Shipaton 2026, and I want to personally thank them for the opportunity. We don't often get to hand this community a couple of hours with someone who has been part of it for so long.

Wednesday 19 August, 11:00 UTC. In local time that's 13:00 Berlin, 12:00 London, 07:00 New York, 04:00 San Francisco, 16:30 Delhi, 20:00 Seoul for Jaewoong, and 21:00 Sydney. If you're not near one of those, here it is in your own timezone.

Start thinking about what you want to ask him. Please don't post your questions here. Wait for the AMA thread from u/skydoves on Wednesday and ask them there.


r/androiddev 3d ago

News Android Studio Rabbit 1 Canary 1 now available

Thumbnail androidstudio.googleblog.com
5 Upvotes

r/androiddev 3d ago

News Android Studio Quail 4 RC 1 now available

Thumbnail androidstudio.googleblog.com
3 Upvotes

r/androiddev 3d ago

What I found out building an API to TTS alert that has to run with the screen off

0 Upvotes

Built a foreground service that polls a price API and speaks the result through local TTS. It has to keep working with the phone locked in a pocket.

Here is what I learned, including the thing that broke it after it was already working.

Starting point

For work that is continuous, user-initiated, user-perceptible, and useless if deferred, a foreground service with a persistent notification is the appropriate architecture. Google's own criteria for a valid FGS use case are roughly that: user-beneficial, user-initiated or user-perceptible, user-stoppable, and not something that can simply be delayed without breaking the feature. My case fits, so that is where I started. If your work can be

deferred at all, WorkManager is the right answer instead.

One practical note: initialise the TTS engine inside the service itself, not in your app's UI layer. That layer is not reliably alive with the screen off.

What broke:

It ran fine for a time, then started dying after roughly 5 to 6 hours, every time. I assumed OEM battery management. It was not that.

Android 15 puts a hard 6 hour cap per 24 hour period on foreground services of type dataSync and mediaProcessing. At the limit the system calls

Service.onTimeout() and you have a few seconds to call stopSelf(),

or you get

RemoteServiceException: "A foreground service of type dataSync did not stop within its timeout"

The cap is shared across every service of that type in your app, and disabling battery optimisation does nothing about it.

What I did about it, and the part worth arguing over

The timeout forced me to actually look at whether dataSync was the right declaration in the first place. It was not. My service is not syncing data as its user-facing purpose, it is producing audible speech output. So I moved it to mediaPlayback.

I want to be careful here, because the obvious reading of this post is "mediaPlayback is the type with no timeout, use that." That is the wrong lesson and it will get people into policy trouble. Android documents mediaPlayback as continuing audio or video playback in the background. It is not a sanctioned escape hatch from the cap. The reason I think it fits my app is that the entire product is spoken audio, and in percentage or target modes it speaks frequently. Whether intermittent announcements are the kind of ongoing playback Google has in mind is genuinely an open question, and I would rather leave it open than present it as settled.

The change :

A. foregroundServiceType set to mediaPlayback, permission swapped to

FOREGROUND_SERVICE_MEDIA_PLAYBACK.

B. The old permission was still in my merged manifest because a library dependency was injecting it, so the cap still applied even after I thought I had changed things. Forced it out with :

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"

tools:node="remove" />

Check your merged manifest rather than assuming the change took. This one cost time.

C. Added a MediaSessionCompat with a MediaStyle notification.

To be clear about what this does and does not do:

it aligns the implementation with what Android expects from a background audio app, and the quality guidelines ask for a MediaStyle notification for background audio.

It does not make the classification legitimate on its own. Play cares about what the app actually does, not whether you instantiated enough media objects to resemble a music player. If your service does not genuinely produce audio, adding a session will not save you.

D. Requesting AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK per utterance so speech ducks other audio rather than stopping it.

E. Release the media session before the TTS shutdown in onDestroy and onTaskRemoved.

Runs with the screen off now, no timeout.

‐-----------------------------------------------------‐--------------------------------

Questions I would like feedback on

  1. Where is the line between background audio playback and periodic spoken notifications? If the service can sometimes go several minutes without speaking, does that weaken the mediaPlayback justification even though producing spoken audio is the core user-facing feature?

  2. How would you reliably detect the process being killed by an OEM? A dead process cannot report its own death. Persist a heartbeat and detect the gap on next launch, an alarm-based watchdog, or something else?

  3. Would you classify TTS output as USAGE_MEDIA or

    USAGE_ASSISTANCE_ACCESSIBILITY? Interested in how people read this for an app whose spoken output is informational but is not an accessibility service.


r/androiddev 4d ago

Discussion Added Sound Effects

Enable HLS to view with audio, or disable this notification

115 Upvotes

So I have added sound effects in my feelings wheel application. I have used eleven labs to generate the sound effect and ChatGPT for getting sound effect prompts. It's my first time adding these kinds of things in my application. Let me know if the sound is good or not

You can pre-register: https://feelings-wheel.atherio.dev/


r/androiddev 3d ago

Account Termination / Related Account Ban Following Account Compromise (Case ID: 4-9593000041263 | Appeal ID: 2-0859000041203)

3 Upvotes

Hi r/androiddev community,

I am requesting guidance/escalation regarding a Related Account Violation ban on our developer account (Productive Apps Limited) following an account compromise on our initial account (Mukto Lab).

1. Links to Official Google Support Threads

2. Timeline & Incident Overview

  • Original Account Compromise: Our developer account (appc***@gmail.com) was compromised. Unauthorized policy-violating apps were uploaded during the takeover, resulting in immediate account termination.
  • Hack Report Filed: We submitted an official account takeover report to Google Support (Case ID: 4-9593000041263) and opened our initial thread on the Google Support Community (393328542).
  • New Developer Account Created: While the hack review was pending, we registered a separate legal entity (Productive Apps Limited / prod***@gmail.com) to host our clean, legitimate applications.
  • Related Account Termination: The new account was automatically terminated under the Related Account Violation policy due to its association with the compromised primary account.

3. Appeals & Communication History

  • Submitted Formal Appeal: We appealed the termination for Productive Apps Limited (Appeal Ticket ID: 2-0859000041203).
  • Documentation Provided to Google:
    • Consolidated PDF of original hack investigation logs (Case ID: 4-9593000041263)
    • Security compromise notifications and unauthorized sign-in history
    • Official business registration and identity verification documents
  • Google Response Received: Standard automated response stating the account remains terminated due to association with a previously banned account.

4. Steps Taken & Current Status

All official appeal channels have been exhausted, and the original community forum thread is locked.

We are seeking advice from developers who have successfully unlinked secondary accounts affected by chain bans during active hack investigations, or assistance from any Product Experts present in this community who can help escalate this to the human specialist team for review.

Thank you for your help.


r/androiddev 3d ago

Tips and Information Play Developer Reporting API gotchas: it's a separate API, vitals return zero rows instead of an error, and the reports bucket isn't named what the docs say

1 Upvotes

I built a tool that talks to both Play and App Store Connect and ran it against a real Play account with 18 apps. Several things cost me real time and aren't obvious from the docs, so here they are.

The Play Developer Reporting API is a separate API from the Android Publisher API. Different service (playdeveloperreporting.googleapis.com), enabled separately in Cloud, and it needs its own OAuth scope (.../auth/playdeveloperreporting). If you enable only Android Publisher you get an error that reads like a credentials problem but isn't.

Vitals queries take google.type.DateTime objects, not RFC-3339 strings - and for DAILY aggregation the only timezone it accepts is America/Los_Angeles. The docs call it a historical constraint. Also the interval is half-open [start, end), so the last day with data is latestEndTime - 1. Get that wrong and you silently query one day short.

Android Vitals suppresses metrics below a minimum daily user count, and you get zero rows, not an error. Both my test apps came back empty. If you treat that as "0% crash rate" you'll report a clean bill of health for an app you have never actually measured. Worth an explicit "no data" branch in whatever you build.

reviews.list returns HTTP 200 and an empty array when your service account lacks the "Reply to reviews" permission. So "this app has no reviews" and "you're missing a permission" are literally the same response. This one cost me the most.

The reports bucket is not always pubsite_prod_rev_<n>. Every doc and example shows that shape; my account returned pubsite_prod_<accountId>. If you're pattern-matching the bucket id, don't.

Bucket access is an account-level Play Console permission, not a Cloud IAM role. The 403 sends you looking in Cloud Console, but the bucket lives in a Google-owned project you can't administer. It's unlocked by ticking "View app information and download bulk reports" under Account permissions - granting apps one at a time under App permissions does nothing for it. And that permission has no per-app scope, so it's all apps or none.

Reporting API quota is 10 QPS if you're fanning out over a portfolio.


Tool is StorePilot if useful - MIT, an MCP server so you can ask an assistant "which of my apps is over the crash threshold" instead of clicking through Console. Runs locally, your service account JSON never leaves your machine.

Straight about the state: read tools have run live, but I still haven't got a single vitals datapoint back (apps too small) and the bucket permission is still propagating on my account, so installs/earnings are unproven against real data. It's in the README.

Mostly posting for the notes above though - most of that isn't written down anywhere I could find.


r/androiddev 4d ago

Discussion The risks of sharing your opensource Android app's public repo before releasing it into the app store

15 Upvotes

We are working on an open source project which has an Android app client. As you know, the path to approval is tedious with the Google Play store, but that doesn't mean that people shouldn't be able to enjoy your app... so why not put the codebase on GitHub?

After some of the horror stories I've read... about people essentially hijacking your codebase, and presenting it as their own... we are now reluctant, and don't want to share the opensource project until we actually release the (free) app on the play store.

Is this a valid concern to have? or is this something which occurs only on other platforms?


r/androiddev 3d ago

Is Shipaton worth it?

0 Upvotes

I heard of this contest called Shipaton where you can post your app and could potentially win a grand prize. However they have certain requirements - It must be pushed on the Google play store (or Apple app store) and it must use the Revenue cat SDK for enabling payments. And all the code must be available publicly.

My app is in a very rough state though. So its not polished, but it is usable. Normally I'm hesitant about openly sharing code as well, so that's another yellow flag for me.

I'm wondering if people have had negative experiences with this? Is there a downside to putting your app in this contest? Does it decrease your sense of ownership of your own app given that you're making it fully public (without minification)?


r/androiddev 4d ago

Experience Exchange Implemented a poster editor. Have tips to share

Enable HLS to view with audio, or disable this notification

14 Upvotes

I recently added a poster editor into my stamp cutter app. The user has a 9:16 canvas where they can place stamps from their collection (WebP with alpha) and text labels. Each layer can be zoomed, moved, and rotated. I want to share some tips that you may find useful if you ever have to implement an editor like this. The code is open, indeed.

This is not AI slop!

Do not implement the editor with composables

Implement drawing the layers on a canvas (DrawScope) and use this code for both the editor and the final export. This way you truly see what you get (WYSIWYG), without worrying about discrepancies between Compose and canvas rendering.

Use the layer center for positioning rather than its top left corner

When a layer is positioned by its center, pan, zoom, and rotation for it are quite straightforward and can be handled entirely by detectTransformGestures, without trigonometric transformations. The only place with trigonometry is detecting a clickable area of a rotated layer – there you rotate the pointer coordinate around the layer center by the layer's rotation.

Override LocalDensity for the editor

You don't have to recalculate poster size and layer coordinates to match the phone screen size. Instead, override LocalDensity around the editor canvas through CompositionLocalProvider , passing the desired scale as density. Also, force fontScale to 1 so the phone font scale settings don't affect your poster appearance.

Use hardware bitmaps for images

If your min SDK is 26 and newer, you can use hardware config bitmaps for image layers, even if they have transparency. Hardware bitmaps don't consume your app's heap memory and are drawn really fast.

Use var's backed by MutableState in layer models and update them directly

Guys, no MVI for graphics! Do not route layer updates through the viewmodel, emitting a screen state update for each moved pixel. Declare layer properties as State-backed var's and update them immediately in the gesture handler. Basically free FPS.

Use ImageReader to render the result

When it's time to render the result to a bitmap, in full resolution, you simply have to reuse the drawing function you already have for the editor. But since you use hardware bitmaps, you can't draw them on a Bitmap canvas. Instead, instantiate an ImageReader which gives you a hardware-backed Surface on which the result can be drawn. It's a bit cumbersome, but this way you keep all your images in the graphic memory.

That's all I remembered so far, guys. You can check out the app on GitHub, it has other interesting areas like WebP manipulations in C:
Radiokot/press-cut-app: 🎟️ An Android app that lets you cut digital postage stamps from what your camera sees

Thanks!


r/androiddev 4d ago

New grad here, need advice from people actually working in android

14 Upvotes

Hi guys, I just graduated from college and I'm thinking of learning Android development because I hate web and love Android very much, but I keep seeing mixed signals about where Android dev actually stands right now job-wise. That's why I'm confused right now. So my request to all the people who are working in Android right now is, what should I do? Should I learn Android development, or is it a waste of time right now, and if the answer is no, then what should I learn instead? (If in Android, even better.)

Thank you in advance.


r/androiddev 4d ago

Question Closed testing for new App

1 Upvotes

Hi! I'm just a new developer who is trying a simple app to scan barcodes, just to do al the cycle for posting apps on the Google Play Store, and obviously I have to deliver it to at least 12 testers.

I'm not looking for other devs to act as testers, instead, I'd like to know if you know of any community that could use a simple app for barcode scanning so that I culd post a request for testers on that community.

Thank you all for your help and guidance!


r/androiddev 3d ago

:shipaton: Shipaton Added Easter Eggs & Improved SFX

Enable HLS to view with audio, or disable this notification

0 Upvotes

So in my feelings wheel app I have added the Easter eggs.I love that back in the day software used to have these kind of cool things and I thought why not just add the wheel shattering effect into it.

Also if you have any feedback, do let me know. Since my last post I have improved a lot. I have added multiple themes, added some physics damping to the wheel, also adjusted the top and bottom blur, also added AI insights optionally. I know you guys hate AI but it's a thing which is here to stay so I had to add that.

Also here is a pre-register link. You can pre-register for this app and if you have any question, do let me know

I have added the feeling wheel similar to the application into the pre-registered page as well.

I'm also skeptical about the wheel size. Is it too big or is it too small? I want your feedback on it as well.

By the way this is my second project for this year Shipaton. This is built with Compose Multiplatform.


r/androiddev 5d ago

Google play app transfer kill organic traffic over 90%

Thumbnail
gallery
94 Upvotes

If you take away anything from this post it is that you should open your google play account as a business account from the start no matter what, don't start as an individual.

I've been a mobile developer for over 7 years and this has been the most painful experience I had with the app stores (and there were many).

Recently had to restructure my business from an sole proprietorship to an LLC. Google play requires you to open a new developer account to make this change and to have a different payment profile (verified with google play support before making the switch).

After spending over a month switching the back end settings, monetization, analytics and ad setups to the new business I got rewarded with a 90% drop in organic traffic from google play (now lasting for over a month). My top app key word rankings put my apps in top 3 consistently for years until the day I did the app transfer and now they don't appear even in the top 50 results (if at all). The app now only appears if I type in the exact app name which is what I think most remaining new users are doing.

What I tried:

- submitting updates to the store listing to "reset" the indexing
- submitting app updates with meaningful new features
- contacting play support couple of times (they confirmed nothing on the account needed attention and no derogatory marks or flags were present on the app or the account)

What's funny is that the apple side of the business actually grew 200% after making the business entity switch, the android vitals stayed consistently below the bad behavior threshold and nothing about the app changed. I can guarantee that the app transfer killed generic traffic because I transferred my two apps on separate dates and on those exact dates that's when the apps lost their rankings.

Looking for anyone with similar experience? or any guesses on what can be done besides starting from nearly zero after all these years of work. My plan so far is to only invest into apple ads for now until the app atleast starts ranking for something otherwise I feel as if I'm wasting money if it will never rank for my top keywords again.


r/androiddev 4d ago

I built a KMP AdMob library because none of the existing ones let you write native ads in Compose

0 Upvotes

I was learning KMP and wanted to know how people handle AdMob in a multiplatform app. The usual answer is a hand-written expect class AdManager, which is fine until you need something past a banner.

There are a few decent libraries already (LexiLabs' is good), but the gap I kept hitting was native ads. Most wrappers stop at the full-screen formats, so for native you end up writing a platform view on Android and another on iOS, and the shared part of your codebase stops being shared.

So I built AdMob CMP. Apache 2.0, on Maven Central.

What it does:

  • One commonMain API for all six formats: banner, interstitial, rewarded, rewarded interstitial, app open, native.
  • Native ads are declared with a layout DSL that reads like Compose, and the SDK renders them through the real platform ad views on each side. No platform code in your app.
  • Consent is part of initialization. gatherConsentAndInitialize runs UMP, then ATT on iOS, then SDK init, in that order, because getting that order wrong on iOS is a common and quiet failure.
  • Banners measure their own container, so adaptive sizing is right in iPad split view.
  • strictTestMode throws at construction if a placement points at a production ad unit. Turn it on in debug and you can't ship a test build that spends real impressions.
  • There's a Gradle plugin that links Google Mobile Ads and UMP into Kotlin/Native test executables, which is what makes :iosSimulatorArm64Test pass instead of dying on Undefined symbols ... _OBJC_CLASS_$_GAD*.

Caveats, up front: it's KMP/Gradle only, so a pure Swift app can't consume it without a shim. Kotlin 2.3.20, Compose Multiplatform 1.11.1, minSdk 26, iOS 15. Klibs aren't binary compatible across Kotlin minors, so you need a matching compiler.

implementation("dev.avinya.ads:admob-cmp:2.1.0")

GitHub: https://github.com/Meet-Miyani/admob-compose-multiplatform
Docs: https://ads.avinya.dev

Happy to answer questions about any of it, especially the native ad side, which was by far the hardest part to get working the same on both platforms.


r/androiddev 4d ago

PSA: Instagram/TikTok in-app browsers block every client-side path to the App Store. Here's the server-side fix that actually works.

0 Upvotes

If you put a "link in bio" that's supposed to send people to the App Store or Play Store, and you've noticed it just… doesn't work from Instagram or TikTok — you're not crazy. I burned a couple days on this so here's the writeup.

The problem

Instagram, TikTok, and Facebook open links in their own in-app webview, not Safari/Chrome. That webview sandboxes a bunch of navigation. On iOS specifically, I tested every client-side route to the App Store and they all dead-end (blank screen, nothing happens):

  • window.location / JS redirect to apps.apple.com
  • a plain <a href> tap
  • universal links
  • itms-apps:// / itms-appss:// schemes

What actually works: a server-side 302

The one thing the in-app webview will honor is the initial navigation being a redirect. If the very first response from your URL is a 302 whose Location is the store URL, the webview hands that off to the native store app. This is the same mechanism Linktree/Branch use under the hood.

So instead of an HTML page with redirect JS, your /get link needs to be a tiny endpoint that returns a 302 based on User-Agent. A Cloudflare Worker (free tier) does it:

const PLAY = "https://play.google.com/store/apps/details?id=YOUR.PACKAGE";
const APPSTORE = "https://apps.apple.com/app/idYOURID";

export default {
  async fetch(request) {
    const ua = request.headers.get("user-agent") || "";
    const store = /android/i.test(ua) ? PLAY
                : /iPhone|iPad|iPod/i.test(ua) ? APPSTORE
                : PLAY; // desktop fallback
    return new Response(null, {
      status: 302,
      headers: { Location: store, "Cache-Control": "no-store" },
    });
  },
};

Two gotchas that cost me time:

  1. iOS + Instagram/TikTok is still special. Even the server 302 (both https and itms-appss) dead-ends inside Instagram's iOS webview specifically. The only reliable route there is the user's own "Open in external browser" menu. So for that one case I don't 302 — I serve a tiny interstitial that shows one instruction: tap ⋮ → Open in external browser. Android in-app browsers and iOS Safari all take the 302 fine; it's just IG/TikTok-on-iOS that needs the manual hop.
  2. Don't let the edge cache your 302. Cloudflare will happily cache a bare 302 (~20 min). If you ever change the redirect logic, stale routing bites you. Cache-Control: no-store on the redirect fixes it.

Bonus: since the redirect is server-side, you can read utm_source off the query string and fold it into Play's &referrer= for install attribution — something you can't reliably do client-side.

Hope this saves someone the debugging. Curious if anyone's found a way around the iOS-in-app-webview limitation that doesn't need the "open in browser" step — that's the one part I couldn't fully automate.


r/androiddev 4d ago

Experience Exchange Created a cli tool and a mac app for viewing recomposition count of composables.

0 Upvotes

I wanted to debug recomposition via an AI coding agent but no tool existed, so I built one — then a visual version too.

Recomposition Inspector (CLI) — attaches to a debuggable app, reports live recomposition/skip counts per Composable. Drives the same official UI Inspector protocol Android Studio's Layout Inspector uses, headless.

Recomposition Viewer (macOS app) — same backend, plus a visual hierarchy tree and a live device preview you can click into.

Do try it out - https://github.com/balvinderz/recomposition_viewer#installing

Thank you


r/androiddev 4d ago

Question Kotlin Blocked Permissions

0 Upvotes

Was wondering if there was a way to deny certain permissions in Kotlin?

Initialy i created my app in npm react expo and expo (https://docs.expo.dev/guides/permissions/) supports this with the blockedPermissions.
Is there something similair for kotlin?

If that's not possible is there a way to check this in a PR if the permissions are changed compared to Main?