Guía del desarrollador

Guía de integración de Deeplink en Android

X-Installer proporciona un protocolo de deeplink robusto que permite a las aplicaciones Android de terceros activar de forma fluida la instalación de formatos complejos de split-APK sin necesidad de acceso root.

Descripción general del protocolo

Esquema de Deeplinkxinstaller://install?uri=<content_uri>
Paquete de destinocom.pasta.xinstaller
ExtensiónDescripciónControlador
.apkPaquete estándar de AndroidPredeterminado del sistema
.xapkSplit APK con datos OBBX-Installer
.apksExportaciones de Android App Bundle / AABX-Installer
.apkmFormatos split de APKMirrorX-Installer
.zipArchivo ZIP que contiene archivos APKX-Installer

Configuración del entorno

Para compartir de forma segura archivos grandes APK/XAPK con X-Installer sin provocar FileUriExposedException en Android 7.0+, debes implementar FileProvider.

1. Añadir dependencia

gradle
// File: app/build.gradle
dependencies {
    // Required for FileProvider implementation
    implementation 'androidx.core:core:1.10.1'
}

2. Registrar FileProvider

xml
<!-- 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. Definir rutas de archivos

xml
<?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>

Clase de integración principal (Kotlin)

Copia esta clase auxiliar directamente en tu proyecto. Gestiona la detección de formato, la conversión de URI, la concesión de permisos y la redirección a Google Play si el usuario aún no ha instalado X-Installer.

kotlin
// 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()
    }
}

Ejemplo de uso

Una vez añadida la clase auxiliar, puedes activar la instalación desde cualquier Activity o Fragment después de que se complete la descarga de tu archivo.

kotlin
// 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)

¿Necesitas ayuda?

Para las últimas actualizaciones, soporte de formatos y técnicas avanzadas de integración, contacta con nuestro equipo.

support@xapksinstaller.com