Guia do Desenvolvedor

Guia de Integração Android Deeplink

O X-Installer fornece um protocolo deeplink robusto que permite que aplicativos Android de terceiros acionem perfeitamente a instalação de formatos complexos de split-APK sem necessidade de acesso root.

Visão Geral do Protocolo

Esquema Deeplinkxinstaller://install?uri=<content_uri>
Pacote Alvocom.pasta.xinstaller
ExtensãoDescriçãoManipulador
.apkPacote Android PadrãoSystem default
.xapkSplit APK com dados OBBX-Installer
.apksAndroid App Bundle / exportações AABX-Installer
.apkmFormatos split do APKMirrorX-Installer
.zipArquivo ZIP contendo arquivos APKX-Installer

Configuração do Ambiente

Para compartilhar com segurança arquivos grandes APK/XAPK com o X-Installer sem acionar FileUriExposedException no Android 7.0+, você deve implementar o FileProvider.

1. Adicionar Dependência

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 Caminhos de Arquivos

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>

Classe de Integração Principal (Kotlin)

Copie esta classe auxiliar diretamente para seu projeto. Ela lida com detecção de formato, conversão de URI, concessão de permissões e redirecionamento para o Google Play caso o usuário ainda não tenha instalado o 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()
    }
}

Exemplo de Uso

Uma vez adicionada a classe auxiliar, você pode acionar a instalação a partir de qualquer Activity ou Fragment após a conclusão do download do arquivo.

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)

Precisa de Ajuda?

Para as últimas atualizações, suporte a formatos e técnicas avançadas de integração, entre em contato com nossa equipe.

support@xapksinstaller.com