Feature Request: Directly Installable Android APK from Google AI Studio

Feature Request: Directly Installable Android APK from Google AI Studio

I am using Google AI Studio on a mobile phone to build an Android application. Currently, after creating the Android app, I am unable to get a properly installable APK directly on my Android device.

I would like Google AI Studio to add better Android app build and export support in future versions.

Requested Improvements

1. Add a Build Android APK option inside Google AI Studio.

2. Generate a properly signed/debug APK that can be installed directly on Android devices.

3. Provide a clear Download APK button after the build is completed.

4. Make the APK compatible with modern Android versions.

5. Show clear build errors if the APK cannot be generated.

6. Support mobile users so they can create, build, download, and install their Android apps without needing a PC.

7. Ideally provide options for:

  • Debug APK

  • Release APK

  • AAB for Google Play Store

8. Make the build process automatic, so developers do not need to manually configure Gradle or Android Studio.

9. If installation is blocked because of signing, permissions, SDK versions, or architecture, clearly explain the exact reason and how to fix it.

Main Goal

The goal is to allow a user to create an Android app using Google AI Studio entirely from a mobile device, build the project, download a working APK, and install it directly on their Android phone.

This would make Google AI Studio much more useful for mobile developers and beginners who do not have access to a computer.

Here’s how I work around that problem: ask Gemini

Please add a custom Gradle post-build task (copyDebugApk) to app/build.gradle.kts (or the main app-level build.gradle.kts) that automatically copies the generated app-debug.apk to the project root directory whenever assembleDebug runs.

Ensure the task handles race conditions and file locking during Android packaging by waiting for file stabilization and verifying file handles before copying:

Add the necessary imports to the top of build.gradle.kts:

import java.io.File

import java.nio.file.Files

Add the custom CopyApkTask class:

abstract class CopyApkTask : DefaultTask() {

@get:Internal

abstract val apkDir: DirectoryProperty

@get:Internal

abstract val outputDir: DirectoryProperty

private fun hasOtherProcessOpenFile(file: File): Boolean {

val targetCanonicalPath = try {

  file.canonicalPath

} catch (e: Exception) {

  file.absolutePath

}

val procDir = File("/proc")

if (!procDir.exists() || !procDir.isDirectory) return false

val currentPid = try {

  ProcessHandle.current().pid()

} catch (e: Throwable) {

  -1L

}

val pids = procDir.listFiles { f -> f.isDirectory && f.name.all { it.isDigit() } } ?: return false

for (pidDir in pids) {

  val pidStr = pidDir.name

  val pid = pidStr.toLongOrNull() ?: continue

  if (pid == currentPid) continue

  val fdDir = File(pidDir, "fd")

  val fds = fdDir.listFiles() ?: continue

  for (fd in fds) {

    try {

      val linkTarget = Files.readSymbolicLink(fd.toPath()).toFile().canonicalPath

      if (linkTarget == targetCanonicalPath) {

        println("Process $pid has an open handle to $targetCanonicalPath")

        return true

      }

    } catch (e: Exception) {

      // Ignore deleted files, permission errors, or dynamic /proc race conditions

    }

  }

}

return false

}

@TaskAction

fun run() {

val dir = apkDir.get().asFile

val file = File(dir, "app-debug.apk")

val destDir = outputDir.get().asFile

val destFile = File(destDir, file.name)

// Delay start: Pauses briefly to let file packaging settle

Thread.sleep(1500)

// Wait for source file size to stabilize and check /proc for open handles

var lastSize = -1L

var stableCount = 0

for (attempt in 1..100) {

  if (file.exists()) {

    val currentSize = file.length()

    if (currentSize > 0 && currentSize == lastSize) {

      stableCount++

      if (stableCount >= 7) {

        val sourceHasHandles = hasOtherProcessOpenFile(file)

        val destHasHandles = destFile.exists() && hasOtherProcessOpenFile(destFile)

        if (sourceHasHandles || destHasHandles) {

          println("APK size stable at $currentSize, but open file handles found via /proc. Resetting stableCount (attempt $attempt/100)...")

          stableCount = 0

        } else {

          println("APK is fully stabilized at $currentSize bytes with no open file handles.")

          break

        }

      }

    } else {

      stableCount = 0

    }

    lastSize = currentSize

  }

  Thread.sleep(500)

}

if (file.exists() && file.length() > 0) {

  file.copyTo(destFile, overwrite = true)

  println("Successfully copied APK to ${destFile.absolutePath} (${destFile.length()} bytes)")

} else {

  println("Source APK file not found or empty: ${file.absolutePath}")

}

}

}

Register the task and attach it as finalizedBy on assembleDebug:

val copyDebugApk = tasks.register(“copyDebugApk”) {

apkDir.set(layout.buildDirectory.dir(“outputs/apk/debug”))

outputDir.set(layout.projectDirectory.dir(“..”))

}

afterEvaluate {

tasks.findByName(“assembleDebug”)?.finalizedBy(copyDebugApk)

}

After this, there will be a copy of the debug APK in the project root dir that you can download through the AI studio file explorer. You could probably ask it to do the same for release builds and APKs.

Another trick I have used is to ask Gemini to serve up a file using a web server. This doesn’t seem to persist well but has occasionally been handy. It has taken me multiple prompts to get this working but they could presumably be combined into one:

Can you configure nginx to serve the AAB file as a downloadable link?

That usually works, but on one recent occasion Gemini told me it couldn’t do that, and I had to insist:

Yes you can. You did it before, to serve up the feature graphic that you constructed.

After that, Gemini gave me links to download the AAB file, but on first trying to use it I got a 403 error. If that happens to you, ask Gemini:

That didn’t work. Please disable lua Auth.

BTW, getting Gemini to build debug or release builds of APKs or AABs is just a matter of asking it to.