Android
APK
Programmatically
Installation
Duplicate

Android install .apk programmatically

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

On modern Android, a normal app cannot silently install an APK the way a system app or enterprise-managed device might. What a regular app can do is trigger the system package installer with the APK file and let the user approve the installation. The correct implementation depends on Android version, file URI rules, and whether the app is allowed to request package installs.

Understand the Security Model First

There are two very different cases:

  • user-approved installation through the system package installer
  • silent installation without user interaction

For regular Play Store style apps, the first is the supported path. Silent installation is generally reserved for privileged apps, device-owner scenarios, or system-level environments.

That distinction matters because many old examples imply that any app can just install an APK directly. That is no longer true for ordinary apps.

Use a FileProvider and Installer Intent

On modern Android, you should share the APK through a content URI, not a raw file URI.

xml
1<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
2
3<application>
4    <provider
5        android:name="androidx.core.content.FileProvider"
6        android:authorities="${applicationId}.fileprovider"
7        android:exported="false"
8        android:grantUriPermissions="true">
9        <meta-data
10            android:name="android.support.FILE_PROVIDER_PATHS"
11            android:resource="@xml/file_paths" />
12    </provider>
13</application>

A simple file_paths.xml might look like:

xml
1<?xml version="1.0" encoding="utf-8"?>
2<paths>
3    <files-path name="apk" path="." />
4    <cache-path name="cache" path="." />
5</paths>

Then launch the installer:

kotlin
1import android.content.Intent
2import android.net.Uri
3import androidx.core.content.FileProvider
4import java.io.File
5
6fun installApk(activity: android.app.Activity, apkFile: File) {
7    val uri: Uri = FileProvider.getUriForFile(
8        activity,
9        "${activity.packageName}.fileprovider",
10        apkFile
11    )
12
13    val intent = Intent(Intent.ACTION_VIEW).apply {
14        setDataAndType(uri, "application/vnd.android.package-archive")
15        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
16        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
17    }
18
19    activity.startActivity(intent)
20}

This hands off to the system installer UI.

Android 8 and Later: Unknown App Sources Permission

Starting with Android 8.0, the permission model changed from a global "unknown sources" setting to a per-app capability. If your app is not allowed to request package installs, the system will block the flow.

You can check it like this:

kotlin
1if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
2    val allowed = activity.packageManager.canRequestPackageInstalls()
3    println("Can request installs: $allowed")
4}

If it is not allowed, guide the user to the appropriate settings screen before retrying.

Use PackageInstaller Only When You Need More Control

Android also has the PackageInstaller API for session-based installs. That is useful for more advanced workflows, but it does not magically bypass the platform's security model for ordinary apps.

For many app-updater scenarios, launching the installer with a FileProvider URI is simpler and sufficient.

Test the Whole Flow, Not Only the Intent

A lot of installation code looks correct but still fails because one of these pieces is missing:

  • the APK file path is wrong
  • the FileProvider authority does not match the manifest
  • URI read permission was not granted
  • the app is not allowed to request installs
  • the APK itself is invalid or incompatible

The handoff to the system installer is only one part of the full flow.

Common Pitfalls

The most common mistake is trying to use file:// URIs directly on modern Android instead of a FileProvider content URI.

Another issue is assuming a regular app can silently install an APK with no user interaction. That is not the normal security model.

Developers also often forget the per-app install permission requirement on Android 8.0 and later.

Finally, do not confuse "I can launch the installer" with "the install succeeded." The APK still has to be valid and acceptable to the platform.

Summary

  • A normal Android app can trigger the system installer, but not silently install APKs in the general case.
  • Use FileProvider to share the APK securely.
  • Add REQUEST_INSTALL_PACKAGES and handle the per-app install permission flow on Android 8.0 and later.
  • Launch the installer with a content URI and read permission.
  • Treat silent installation as a privileged special case, not the default app behavior.

Course illustration
Course illustration

All Rights Reserved.