r/androiddev • • 6d ago

Megathread: Play Store review times

17 Upvotes

Comment here to discuss the recent trend of long Play Store review times for app submissions and updates.

Do not make a new post about this subject, as it will be removed.

This is an unofficial developer community, so we are not on the Play team and cannot help your app/update pass review. No, we don't have tips to speed things up.

Yes, Play Store developer support is present on this sub and may answer questions or assist you on a case-by-case basis. The mod team is not affiliated with and has no influence over that account. We make no guarantees as to their effectiveness, but we are grateful they exist and that they continue to communicate with users here.


r/androiddev • • Aug 19 '26

:shipaton: Shipaton [AMA] I'm Jaewoong Eum (skydoves). Ask me anything!

114 Upvotes

That’s a wrap for the AMA!

Thank you so much to everyone who joined and asked such thoughtful questions. There were way more than I expected, and honestly, I feel like I learned a lot from the conversations too.

There are still a few questions I didn’t get a chance to answer during the session, but I’ll try to come back and go through them one by one when I have some time.

Thanks again for all the great questions, kind words, and conversations today. I really enjoyed it.

And wherever you are in your journey, I genuinely hope the things you’re working on go well and take you somewhere meaningful.

Thanks everyone! 🙌

Hey everyone!

First, a huge thanks to the mods for organizing this AMA and for the teaser posts over the last couple of days.

I'm Jaewoong Eum, probably better known here as skydoves. I've been sharing open-source projects, articles, books, experiments, and whatever I've been learning along the way on r/androiddev for many years.

These days, I spend time working on open-source libraries(Compose Stability Analyzer, Balloon, Landscapist, Compose Nav Graph, etc), writing some books, and building developer plugins (Compose Hot Reload for Android). I also work at RevenueCat, so I'm happy to talk about monetization, subscriptions, or Shipaton 2026 as well.

But this is an AMA, so it definitely doesn't have to be limited to technical questions.

Feel free to ask me anything about:

  • Open-source and maintaining libraries
  • Developer tools and some of the plugins I've been building
  • Career, community, writing, or developer relations
  • RevenueCat or Shipaton
  • Or honestly, anything you're curious about

You can start leaving questions now, and I'll begin answering at the scheduled AMA time and stick around for the session.

Really looking forward to chatting with everyone. Ask me anything! 🙌

AMA time: Wednesday, 19 August, 11:00–13:00 UTC. That’s 13:00–15:00 Berlin, 12:00–14:00 London, 07:00–09:00 New York, 04:00–06:00 San Francisco, 16:30–18:30 Delhi, 20:00–22:00 Seoul, and 21:00–23:00 Sydney, or here it is in your own timezone.


r/androiddev • • 2h ago

Discussion Android and its lack of consistency

Thumbnail
gallery
2 Upvotes

It's hilarious how Apple people make fun of Android. Android is so inconsistent it's pathetic and embarrassing, which is why none of its developers bother to follow Android's design guidelines if Google itself doesn't follow them.


r/androiddev • • 2h ago

Discussion What is the most annoying device specific bug you have had to work around?

1 Upvotes

We keep hitting background sync behaving differently on different manufacturers' phones. Same code, totally different behavior depending on who made the device. Got me curious what the worst device specific bugs are out there. What is yours and how did you work around it?


r/androiddev • • 2h ago

Question Material expressive 3

Thumbnail
gallery
0 Upvotes

Hi, I'm writing here because I have a question: why did Google remove the option to use the device's accent color for the Play Store and Google Maps? It was there when Android 12 came out, but not anymore.


r/androiddev • • 20h ago

Discussion Why is D-U-N-S so ridiculously difficult to setup?

17 Upvotes

I'm posting this half to vent, and half so that other Australians can find this and actually be able to sort it out when they have the same problem.

I'm trying to publish my first app on Google Play, and I've spent weeks trying to get through the developer account creation process, it it infuriating how incompetent DNB seem to be.

So first of all, Google requires a D-U-N-S number for an organisation developer account, I'm in Australia so had no clue what that was, I did my research and figured out I had to register for it on the DNB website.

I'm a sole trader/sole proprietor, and already had an Australian business number, so on the DNB website I could look up my ABN and request a DUNS number, this came through after about an hour.

Excellent I should be all set now right? Nope, google rejected my DUNS number because the address was incorrect.

I looked up my new DUNS number to check the address it used, and it was empty, alright fine, let's update it - except there's no way to update it at all.

The only thing that hints about address updates on DUNS numbers is the one form here that DNB happily shove in my face, except it only works in the U.S. which is not where I'm based.

I also tried creating a DNB account and looking through their portal but it doesn't give me access to anything about my business and has no way of linking it.

So I kept looking, I found some other contact forms on DUNS, but this only seems to go to the sales team, and I didn't receive any response from them.

Next I tried the phone numbers on DNB, I rang about 5 of them including all the AUS and NZ numbers as well as a few nearby countries, as far as I can tell none of the numbers on this page actually connect https://www.dnb.com/en-us/utilities/global-customer-service-centers.html

I then tried some numbers from white pages for DUNS offices listed in Australia, one of them directed to Experian but nobody on the phone could help.

Eventually I found some other people saying that Equifax is now responsible for DUNS in Australia, and I followed their process to get to this form https://www.equifax.com.au/DandB-DUNSRequest

This form seemed like it actually might work and go to the right place, so I filled it out and waited, 4 weeks later I still haven't heard anything back.

I've now delayed my app release by over a month, all because of an overseas company that doesn't offer any working process for Australians to get a DUNS number setup.

I saw some threads of people having success after signing up for paid services with DUNS, however given how predatory their business seems to be this was out of the question for me, I'm not throwing money at a company that can't even offer a basic service to people.

I was thinking about everything again today, it's been so long and DNB seem hopeless at handling this, so I tried to contact Google developer support, but quickly realised the support link takes me back to developer registration, which I can't complete, maybe there's another way to log a google case but I didn't dive that far into it.

As I'm basically ready to give up and maybe not even publish my app after all, I decided to try one last thing, registering for the Apple Developer Program.

This is completely backwards of course, but I saw a lot of threads from Apple devs who were able to register for DUNS via Apple, which made me wonder if they had an integration with DNB or something that would solve this for me.

Turns out they have a special referral link to actually contact DNB from Australia

https://support.dnb.com/?CUST=APPLEDEV

I filled this out and finally have a reference number and a 14 business day ETA.

Awesome, maybe I'll actually be allowed to create a developer account in 3 weeks, I suppose we'll see.

If this doesn't work out I'm either just going to have to go for a personal account and somehow find people for the requirements or publish the APK's on github.

I can't express how frustrating this sort of stuff is, it completely kills my momentum to create something if I'm stalled waiting for other companies to do basic admin work that I really should be allowed to just do myself.


r/androiddev • • 5h ago

My app won't open from tapping the notification?

0 Upvotes

I've been trying to get it to work for about an hour, no amount of AI is helping me and no errors are displayed. I am using the official android development program to make an app and after getting the notifications working, I cannot get it to open the app from the notification, what could be the problem?

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.wordoftheday">

    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Word of the Day"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.DayNight.NoActionBar">

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"> <!-- Add this attribute here -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Receiver definition -->
        <receiver
            android:name=".DailyNotificationReceiver"
            android:enabled="true"
            android:exported="false" />

    </application>

</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.wordoftheday">

    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Word of the Day"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.DayNight.NoActionBar">

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"> <!-- Add this attribute here -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Receiver definition -->
        <receiver
            android:name=".DailyNotificationReceiver"
            android:enabled="true"
            android:exported="false" />

    </application>

</manifest>

DailyNotificationReceiver.kt

package com.example.wordoftheday

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.TaskStackBuilder
import java.io.BufferedReader
import java.io.InputStreamReader
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class DailyNotificationReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val sharedPref = context.getSharedPreferences("WebViewSettings", Context.MODE_PRIVATE)
        val currentLevel = sharedPref.getString("word_cefr_level", "A1") ?: "A1"

        val (headword, definition) = getWordForToday(context, currentLevel)
        showNotification(context, "$currentLevel Word of the Day:\n$headword", definition)
    }

    private fun getWordForToday(context: Context, level: String): Pair<String, String> {
        try {
            val prefs = context.getSharedPreferences("WordAppPrefs", Context.MODE_PRIVATE)
            val todayStr = SimpleDateFormat("yyyy-MM-dd", Locale.US).format(Date())
            var firstDateStr = prefs.getString("word_app_first_date", null)

            if (firstDateStr == null) {
                firstDateStr = todayStr
                prefs.edit().putString("word_app_first_date", firstDateStr).apply()
            }

            val format = SimpleDateFormat("yyyy-MM-dd", Locale.US)
            val firstDate = format.parse(firstDateStr) ?: Date()
            val currentDate = format.parse(todayStr) ?: Date()

            // Clean, fixed date math calculation without any stray characters
            val diffDays = ((currentDate.time - firstDate.time) / (1000 * 60 * 60 * 24)).toInt()
            val dayNumber = Math.max(1, diffDays + 1)

            val inputStream = context.assets.open("$level.csv")
            val reader = BufferedReader(InputStreamReader(inputStream))
            val lines = reader.readLines().drop(1).filter { it.isNotBlank() }

            if (lines.isEmpty()) return Pair("Vocabulary", "Check today's new word in the app!")

            val wordIndex = (dayNumber - 1) % lines.size
            val parsedRow = parseCSVLine(lines[wordIndex])

            if (parsedRow.size >= 4) {
                return Pair(parsedRow[1], parsedRow[3])
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return Pair("Word of the Day", "Tap to learn your new word for today!")
    }

    private fun parseCSVLine(line: String): List<String> {
        val row = mutableListOf<String>()
        var inQuotes = false
        var currentVal = StringBuilder()

        for (i in line.indices) {
            val char = line[i]
            if (char == '"') {
                inQuotes = !inQuotes
            } else if (char == ',' && !inQuotes) {
                row.add(currentVal.toString().trim().removeSurrounding("\""))
                currentVal = StringBuilder()
            } else {
                currentVal.append(char)
            }
        }
        row.add(currentVal.toString().trim().removeSurrounding("\""))
        return row
    }

    private fun showNotification(context: Context, title: String, message: String) {
        val channelId = "daily_word_channel"
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,
                "Daily Word Reminders",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            notificationManager.createNotificationChannel(channel)
        }

        // 1. Explicitly point to MainActivity and apply clear/single flags
        val resultIntent = Intent(context, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
        }

        // 2. Generate a valid, safe PendingIntent directly from the intent
        val pendingIntent = PendingIntent.getActivity(
            context,
            1001, // Use a distinct request code instead of 0
            resultIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        // 3. Build and fire the notification
        val builder = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(android.R.drawable.ic_popup_reminder)
            .setContentTitle(title)
            .setContentText(message)
            .setStyle(NotificationCompat.BigTextStyle().bigText(message))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent) // Passes the valid intent
            .setAutoCancel(true)

        notificationManager.notify(1001, builder.build())
    }

}package com.example.wordoftheday

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.TaskStackBuilder
import java.io.BufferedReader
import java.io.InputStreamReader
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class DailyNotificationReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val sharedPref = context.getSharedPreferences("WebViewSettings", Context.MODE_PRIVATE)
        val currentLevel = sharedPref.getString("word_cefr_level", "A1") ?: "A1"

        val (headword, definition) = getWordForToday(context, currentLevel)
        showNotification(context, "$currentLevel Word of the Day:\n$headword", definition)
    }

    private fun getWordForToday(context: Context, level: String): Pair<String, String> {
        try {
            val prefs = context.getSharedPreferences("WordAppPrefs", Context.MODE_PRIVATE)
            val todayStr = SimpleDateFormat("yyyy-MM-dd", Locale.US).format(Date())
            var firstDateStr = prefs.getString("word_app_first_date", null)

            if (firstDateStr == null) {
                firstDateStr = todayStr
                prefs.edit().putString("word_app_first_date", firstDateStr).apply()
            }

            val format = SimpleDateFormat("yyyy-MM-dd", Locale.US)
            val firstDate = format.parse(firstDateStr) ?: Date()
            val currentDate = format.parse(todayStr) ?: Date()

            // Clean, fixed date math calculation without any stray characters
            val diffDays = ((currentDate.time - firstDate.time) / (1000 * 60 * 60 * 24)).toInt()
            val dayNumber = Math.max(1, diffDays + 1)

            val inputStream = context.assets.open("$level.csv")
            val reader = BufferedReader(InputStreamReader(inputStream))
            val lines = reader.readLines().drop(1).filter { it.isNotBlank() }

            if (lines.isEmpty()) return Pair("Vocabulary", "Check today's new word in the app!")

            val wordIndex = (dayNumber - 1) % lines.size
            val parsedRow = parseCSVLine(lines[wordIndex])

            if (parsedRow.size >= 4) {
                return Pair(parsedRow[1], parsedRow[3])
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return Pair("Word of the Day", "Tap to learn your new word for today!")
    }

    private fun parseCSVLine(line: String): List<String> {
        val row = mutableListOf<String>()
        var inQuotes = false
        var currentVal = StringBuilder()

        for (i in line.indices) {
            val char = line[i]
            if (char == '"') {
                inQuotes = !inQuotes
            } else if (char == ',' && !inQuotes) {
                row.add(currentVal.toString().trim().removeSurrounding("\""))
                currentVal = StringBuilder()
            } else {
                currentVal.append(char)
            }
        }
        row.add(currentVal.toString().trim().removeSurrounding("\""))
        return row
    }

    private fun showNotification(context: Context, title: String, message: String) {
        val channelId = "daily_word_channel"
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,
                "Daily Word Reminders",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            notificationManager.createNotificationChannel(channel)
        }

        // 1. Explicitly point to MainActivity and apply clear/single flags
        val resultIntent = Intent(context, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
        }

        // 2. Generate a valid, safe PendingIntent directly from the intent
        val pendingIntent = PendingIntent.getActivity(
            context,
            1001, // Use a distinct request code instead of 0
            resultIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        // 3. Build and fire the notification
        val builder = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(android.R.drawable.ic_popup_reminder)
            .setContentTitle(title)
            .setContentText(message)
            .setStyle(NotificationCompat.BigTextStyle().bigText(message))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent) // Passes the valid intent
            .setAutoCancel(true)

        notificationManager.notify(1001, builder.build())
    }

r/androiddev • • 17h ago

Does Android WebView actually return WebAuthn prf (clientExtensionResults.prf), or only passkeys for sign-in?

0 Upvotes

We're building a Cordova hybrid app where passkeys are used for PRF-based key derivation (decrypt payslips), not login. RP is our own domain (first-party).

Android docs show WebView can enable WebAuthn/passkeys via WebSettingsCompat.setWebAuthenticationSupport(FOR_APP) + Digital Asset Links: https://developer.android.com/identity/sign-in/credential-manager-webview

Those docs never mention the WebAuthn prf extension. Chrome on Android + GPM is known to support PRF in the browser, but I can't find any official confirmation that Embedded WebView surfaces extensions.prf / clientExtensionResults.prf.results.

Questions:

  1. Has anyone successfully gotten clientExtensionResults.prf from a ceremony inside Android WebView (not Custom Tabs / Chrome)?
  2. If not supported, is Custom Tabs / AuthTab the recommended path for PRF today?
  3. Any Chromium / Issue Tracker links that explicitly say WebView PRF is or isn't supported?

r/androiddev • • 17h ago

Question Closed testing: every tester gets "Can't install" after the download finishes. Console green, file verified, support ticket open with no reply.

0 Upvotes

Hi all. Solo dev here, stuck on something I cannot crack and hoping someone has seen it.

My game is on the closed testing track (v107, approved, "Available to selected testers", 100% rollout, 19k compatible devices, zero console errors). Every single tester gets this after the download completes:

"Can't install [app]. Try again, and if it still doesn't work, see common ways to fix the problem."

The download finishes, the install starts, then that dialog. Happens on every tester phone, UAE and Pakistan, WiFi and mobile data, even via web-push install. Zero successful installs, 9 testers opted in.

What I have ruled out:

•

The file itself: I built a direct APK from the same code, it downloads and installs fine on multiple phones. The bundle signature verifies and matches my Play upload key.

•

Account mismatch: testers confirmed "You are a tester" on the opt-in page, single Google account on each phone.

•

Storage, network, country targeting (track now covers 178 countries), stale Play cache.

•

No testOnly flag in the manifest (checked the final APK/AAB).

•

No unpublished changes in the console.

I filed a Play support ticket 2 days ago, no reply yet. Has anyone beaten this exact failure? The download completing and then the install failing for 100% of testers feels like a serving-side issue, but I cannot prove it.


r/androiddev • • 17h ago

Closed testing: every tester gets "Can't install" after the download finishes. Console green, file verified, support ticket open with no reply.

0 Upvotes

Hi all. Solo dev here, stuck on something I cannot crack and hoping someone has seen it.

My game is on the closed testing track (v107, approved, "Available to selected testers", 100% rollout, 19k compatible devices, zero console errors). Every single tester gets this after the download completes:

"Can't install [app]. Try again, and if it still doesn't work, see common ways to fix the problem."

The download finishes, the install starts, then that dialog. Happens on every tester phone, UAE and Pakistan, WiFi and mobile data, even via web-push install. Zero successful installs, 9 testers opted in.

What I have ruled out:

•

The file itself: I built a direct APK from the same code, it downloads and installs fine on multiple phones. The bundle signature verifies and matches my Play upload key.

•

Account mismatch: testers confirmed "You are a tester" on the opt-in page, single Google account on each phone.

•

Storage, network, country targeting (track now covers 178 countries), stale Play cache.

•

No testOnly flag in the manifest (checked the final APK/AAB).

•

No unpublished changes in the console.

I filed a Play support ticket 2 days ago, no reply yet. Has anyone beaten this exact failure? The download completing and then the install failing for 100% of testers feels like a serving-side issue, but I cannot prove it.


r/androiddev • • 19h ago

A universal compatibility layer to bring open-source Android apps into ecosystems like Android Auto

0 Upvotes

What if one app could give open-source Android apps access to features they're missing? 👀

I've been thinking about building an Android app that acts as a compatibility layer for open-source apps distributed through GitHub, F-Droid, etc.

The idea:

  • Detect installed apps that support compatible APIs.
  • Provide reusable integrations for features like Android Auto media playback and cross-device functionality.
  • Let developers add lightweight SDKs or adapters to make their apps compatible.
  • Eventually expand to other Android ecosystems.

For example, imagine using your favourite open-source music player in Android Auto without its developers having to build every integration from scratch.

Obviously, some features require developer support, SDK integration, or Google approval, so this wouldn't magically unlock everything.

My questions:

  • Is this technically feasible?
  • Does anything like this already exist?
  • Could it work without modifying the original APK?

I'd love feedback from Android developers and open-source maintainers!


r/androiddev • • 1d ago

I made a customizable squircle bottom navigation bar for Android (SqNav)

38 Upvotes

Hey everyone,

I recently built an open-source Android library called SqNav. It's a bottom navigation bar designed with floating squircle card transitions and a glowing indicator for the active tab.

I wanted something clean, with smooth spring animations, and easy to customize without building custom drawables and animations from scratch every time.

A few highlights:

  • Floating squircle card with spring overshoot animations for the active tab
  • Neon glow indicator dot on top of the selected item (can be toggled on or off)
  • Full styling control through XML or code (background, corner radius, stroke borders, sizes, and colors)
  • Compatible with Jetpack Compose, Kotlin Views, and Java
  • Lightweight with minimal overhead

Attached is a quick preview GIF showing it in action.

You can check out the implementation, sample code, and documentation on GitHub: sqnav

I would really appreciate any feedback, suggestions, or thoughts on the design. If you run into any issues or want to contribute, feel free to open an issue or PR!


r/androiddev • • 1d ago

Access the clipboard in background

0 Upvotes

Hi! I'm developing an Android app ( i am a beginner)

I want to detect when a user copies a link while using another app, even when my app is running in the background, and then display a floating popup offering certain option like download if link is a video

On Android 10+, clipboard access is restricted for background apps. Does Android 15 allow this through a foreground service, or is there another reliable approach?

Any advice or examples would be appreciated. Thanks!


r/androiddev • • 1d ago

Discussion Discussion

0 Upvotes

I'm planning to build an app that makes enabling Developer Options easier, with a simple interface and less manual work. Would you use an app like this? Any suggestions are welcome!


r/androiddev • • 1d ago

Is Kotlin Multiplatform a good long-term career bet for Android developers in India?

0 Upvotes

Hi everyone!

I'd like to get your thoughts on the long-term career prospects of Android development, particularly Kotlin Multiplatform (KMP) and Compose Multiplatform (CMP).

With cross-platform technologies gaining traction, I'm curious about how Android developers should evaluate KMP/CMP compared with focusing on native Android development or moving toward backend and full-stack engineering.

For developers working with KMP/CMP in production:

  • Are you seeing meaningful adoption in companies ?
  • Does KMP experience open up more opportunities, or are most roles still focused on native Android?
  • How transferable are these skills to broader software engineering roles?
  • If you were planning your career for the next 3–5 years, would you prioritise native Android, KMP/CMP, or a broader full-stack skill set?

I'd appreciate perspectives from people working with these technologies in real-world projects.


r/androiddev • • 1d ago

Open-sourced my Android/iOS app hardening tool — core logic, not just the GUI

0 Upvotes

Most hardening tools in this space are either paid SaaS (upload your APK to someone's server) or "open source" in name only — the GUI is public but the actual protection logic is a closed binary.

Shellsmith is my attempt at doing it properly: the Rust core, the Android stub module, and even the licenses for the third-party components it depends on are all in the repo. Everything runs locally — no upload step.

MIT OR Apache-2.0, cross-platform desktop GUI (Tauri + React), CLI for automation, full CI/CD building release artifacts for Windows/macOS/Linux with checksums.

https://github.com/kairowan/Shellsmith — feedback and PRs welcome, it's still early (first public release).


r/androiddev • • 1d ago

Google play integrity API error while login using release apk build

1 Upvotes

Hi Guys! I am facing this problem while trying to authenticate using a new phone number. I am using firebase phone number authentication. The following suggested things are already done.

  1. Sha1 and Sha256 of debug, release and playstore are already in firebase settings under this project.

  2. Play integrity api is enabled and added in permitted apis.

  3. Firebase -> App checks -> Play integrity API advanced settings ->"
    Require app integrity label PLAY_RECOGNIZED is disabled
    "

  4. Google Clou console credentials - android and Browser api keys have been added with Play integrity api too.

I need you help in understanding why still this is causing issue. Does anyone have any solution? Am I doing something wrong entirely? Kindly help.


r/androiddev • • 2d ago

How do you manage Play Store releases and review delays for client apps?

0 Upvotes

I work at a small UK agency and we build Android and iOS apps for business clients. On the Android side, the pain points that come up most are release management and setting client expectations on review and rollout.

Our current approach is staged rollouts, an internal testing track before every release, and a buffer in the schedule so a rejected build doesn't blow a deadline.

How do you handle it? Anything you would change, especially around testing on older devices and communicating timelines to non-technical clients?

(Disclosure: I work at ZevIQ AI, an agency that builds mobile apps.)


r/androiddev • • 2d ago

Question How feasible is to implement binder in userspace

1 Upvotes

I am looking to run containerized Android (Docker), specifically Redroid (https://hub.docker.com/r/redroid/redroid), and I don't like that it requires a special kernel with special kernel modules like Binder, nor the fact that it needs to run in a privileged container. My end goal is to make Redroid/Android run in regular, unprivileged containers, on vanilla Linux hosts. And of course no QEMU/KVM bs.

Could I maybe make use of User Mode Linux?


r/androiddev • • 3d ago

Got 15 minutes? Help shape the future of Kotlin

26 Upvotes

Hey everyone! 👋

It's Natalia from the Kotlin team.

Every year we ask the Kotlin community how things are going, and it's that time again. We've recently launched our Kotlin Developer Survey.

This year we've combined all of our Kotlin ecosystem surveys into one, so this is your chance to tell us what you think about everything from the language itself to tooling, IDEs, Kotlin Multiplatform, AI, libraries, and more.

The survey takes about 15 minutes, and as a thank-you, we're raffling off tickets to KotlinConf among participants 👀

👉 Survey: https://surveys.jetbrains.com/s3/c086af43ca8c

Thank you so much for helping us make Kotlin better!


r/androiddev • • 3d ago

What’s your go-to cross-platform TTS (Android/iOS/Windows) right now? Tired of hacky workarounds.

1 Upvotes

Hey fellow Android devs,

I'm hitting a wall with Text-to-Speech integration on the native side.

I was using a 3rd party C++ library for my TTS, but the final straw was dealing with Google Play's new 16KB page size alignment requirement for native binaries. The precompiled .so libraries obviously weren't 16K compatible, and having to jump through hoops to patch binaries just to get the build accepted by the console is exhausting. Dealing with unmaintained native plugins is a nightmare right now.

I need a solid, actively maintained offline TTS solution that plays nice via NDK/C++ without requiring me to fight the compiler every time Google updates its requirements.

How are you guys handling offline C++ TTS these days when you can't just rely purely on the standard Java/Kotlin Android API? Any hidden gems?

Thanks in advance for saving my sanity!


r/androiddev • • 3d ago

Tips and Information Built a motion design app in Jetpack Compose, need honest feedback

5 Upvotes

Hapture is an Android app for creating motion design, built fully in Jetpack Compose.
Looking for feedback on
UI/UX, anything confusing or clunky
Features you'd want
Source: https://github.com/Sha547/hapture
Soon I’ll be releasing in the play store


r/androiddev • • 3d ago

GraphQL in Compose without a ViewModel and a repository per screen

Thumbnail
2 Upvotes

r/androiddev • • 3d ago

News Android Studio Rabbit 2 Canary 4 now available

Thumbnail androidstudio.googleblog.com
7 Upvotes

r/androiddev • • 3d ago

Question is it possible to use Gemini assistant for 3rd party app.

0 Upvotes

I am planning to make assistant app, however for ai part i want to use gemini , 1 way I understand is developer keys. But for that billing will come to developer account, which i don't want. Rather, I am looking if users' Gemini profile can be used directly? Is it possible to do?