Android Deeplink Integration Guide
X-Installer provides a robust deeplink protocol that allows third-party Android applications to seamlessly trigger the installation of complex split-APK formats without requiring root access.
Protocol Overview
xinstaller://install?uri=<content_uri>com.pasta.xinstaller| Extension | Description | Handler |
|---|---|---|
| .apk | Standard Android Package | System default |
| .xapk | Split APK with OBB data | X-Installer |
| .apks | Android App Bundle / AAB exports | X-Installer |
| .apkm | APKMirror split formats | X-Installer |
| .zip | ZIP Archive containing APK files | X-Installer |
Environment Configuration
To securely share large APK/XAPK files with X-Installer without triggering FileUriExposedException on Android 7.0+, you must implement FileProvider.
1. Add Dependency
// File: app/build.gradle
dependencies {
// Required for FileProvider implementation
implementation 'androidx.core:core:1.10.1'
}2. Register FileProvider
<!-- File: AndroidManifest.xml -->
<application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>3. Define File Paths
<?xml version="1.0" encoding="utf-8"?>
<!-- File: res/xml/file_paths.xml -->
<paths>
<cache-path name="cache" path="" />
<files-path name="files" path="" />
</paths>Core Integration Class (Kotlin)
Copy this helper class directly into your project. It handles format detection, URI conversion, permission granting, and fallback routing to Google Play if the user hasn't installed X-Installer yet.
// File: app/src/main/java/com/yourdomain/utils/XInstallerHelper.kt
package com.yourdomain.utils
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import androidx.appcompat.app.AlertDialog
import androidx.core.content.FileProvider
import java.io.File
class XInstallerHelper(private val context: Context) {
companion object {
// Official X-Installer package name
private const val XINSTALLER_PACKAGE = "com.pasta.xinstaller"
}
/**
* Entry point: Automatically routes the file to the correct installer based on extension.
*/
fun handleFileInstall(file: File) {
if (!file.exists() || !file.canRead()) return
when (file.extension.lowercase()) {
"apk" -> installApkDirectly(file)
"xapk", "apks", "apkm", "zip" -> installViaXInstaller(file)
}
}
private fun installViaXInstaller(file: File) {
if (!isXInstallerInstalled()) {
showDownloadFallback()
return
}
val contentUri = createContentUri(file) ?: return
try {
// 1. Grant temporary read permission to X-Installer
context.grantUriPermission(
XINSTALLER_PACKAGE,
contentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
// 2. Build the official deeplink protocol
val deeplink = Uri.Builder()
.scheme("xinstaller")
.authority("install")
.appendQueryParameter("uri", contentUri.toString())
.build()
// 3. Launch the intent
val intent = Intent(Intent.ACTION_VIEW, deeplink).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
setPackage(XINSTALLER_PACKAGE)
}
context.startActivity(intent)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun installApkDirectly(file: File) {
val uri = createContentUri(file) ?: return
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri, "application/vnd.android.package-archive")
flags = Intent.FLAG_ACTIVITY_NEW_TASK
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
context.startActivity(intent)
}
private fun isXInstallerInstalled(): Boolean {
return try {
context.packageManager.getPackageInfo(XINSTALLER_PACKAGE, 0)
true
} catch (e: PackageManager.NameNotFoundException) {
false
}
}
private fun createContentUri(file: File): Uri? {
return try {
val authority = "${context.packageName}.fileprovider"
FileProvider.getUriForFile(context, authority, file)
} catch (e: Exception) {
null
}
}
private fun showDownloadFallback() {
AlertDialog.Builder(context)
.setTitle("X-Installer Required")
.setMessage("Installing this split APK format requires the official X-Installer. Would you like to download it now?")
.setPositiveButton("Download from Google Play") { _, _ ->
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("https://play.google.com/store/apps/details?id=$XINSTALLER_PACKAGE")
}
context.startActivity(intent)
}
.setNegativeButton("Cancel", null)
.show()
}
}Usage Example
Once the helper is added, you can trigger the installation from any Activity or Fragment after your file download completes.
// File: app/src/main/java/com/yourdomain/ui/MainActivity.kt
// Example invocation inside your download completion listener
val installerHelper = XInstallerHelper(this)
val downloadedFile = File(cacheDir, "awesome_game.xapk")
installerHelper.handleFileInstall(downloadedFile)Need Help?
For the latest updates, format support, and advanced integration techniques, contact our team.
support@xapksinstaller.com