Android installer apk Avec intention.Voir L'ACTION ne fonctionne pas avec le fournisseur de fichiers

mon application a une fonction de mise à jour automatique qui télécharge un APK et lorsque le téléchargement est terminé Qu'une intention.VIEW_ACTION pour ouvrir l'application et laisser l'utilisateur installer l'apk téléchargé

         Uri uri = Uri.parse("file://" + destination);
         Intent install = new Intent(Intent.ACTION_VIEW);
        install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        install.setDataAndType(uri,
            manager.getMimeTypeForDownloadedFile(downloadId));
        activity.startActivity(install);

cela fonctionne très bien pour tous les appareils < 24

maintenant avec Android 24 apparemment nous ne sommes plus autorisés à commencer intents avec file: / / / et après quelques googling il a été conseillé d'utiliser un fournisseur de fichiers

nouveau code:

Intent install = new Intent(Intent.ACTION_VIEW);
    install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Uri apkUri = FileProvider.getUriForFile(AutoUpdate.this,
        BuildConfig.APPLICATION_ID + ".provider", file);
    install.setDataAndType(apkUri,
        manager.getMimeTypeForDownloadedFile(downloadId));
    activity.startActivity(install);

Maintenant activité.startActivity (install); lance une erreur

aucune activité trouvée pour traiter L'intention { act=android.intention.action.VUE dat=content: / / com.xxxx.xx.provider/MyFolder/Download / MyApkFile.apk type=application/vnd.Android.package-archive flg=0x4000000 }

y a-t-il un moyen d'ouvrir le visualiseur APK dans Android 7 (24) ?

36
demandé sur Johny19 2016-08-25 17:10:18

2 réponses

après beaucoup d'essais, j'ai été en mesure de résoudre ce problème en créant des intentions différentes pour tout ce qui est inférieur à Nougat, comme utiliser le FileProvider pour créer une intention d'installation avec les Versions Android avant que Nougat ne provoque l'erreur:

ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.INSTALL_PACKAGE dat=content://XXX.apk flg=0x1 }

lors de l'utilisation d'un Uri normal sur Android Nougat crée l'erreur suivante:

FileUriExposedException: file:///XXX.apk exposed beyond app through Intent.getData()

Ma solution qui fonctionne pour moi avec Android N sur l'émulateur et un téléphone sous Android M.

File toInstall = new File(appDirectory, appName + ".apk");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Uri apkUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", toInstall);
    Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
    intent.setData(apkUri);
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    activity.startActivity(intent)
} else {
    Uri apkUri = Uri.fromFile(toInstall);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    activity.startActivity(intent);
}

mise à jour Pour Android Oreo:

Comme mentionné dans les commentaires de @Jasongiss

"il est intéressant de mentionner qu'à partir de Oreo vous devez également ajouter la permission REQUEST_INSTALL_PACKAGES à votre manifeste. Sinon, il échoue silencieusement."

mise à jour:

n'oubliez pas de demander les autorisations de lecture et d'écriture de stockage externe si le fichier que vous essayez d'installer est sur le stockage externe. Et aussi pour mettre en place un bon FileProvider pour Nougat Androïde et plus haut.

vérifiez d'Abord si vous avez l'autorisation d'écriture en appelant canReadWriteExternal() ci-dessous, si pas appeler requestPermission() avant:

private static final int REQUEST_WRITE_PERMISSION = 786;

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED)
        Toast.makeText(this, "Permission granted", Toast.LENGTH_LONG).show();
}

private void requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}

private boolean canReadWriteExternal() {
    return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
            ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
}

voici un exemple de fournisseur de fichier pour le dossier de téléchargement sur le stockage externe. AndroidManifest.xml:

<application ... >
    ...

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
    </provider>
</application>

ressources/xml/filepaths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_download" path="Download"/>
</paths>

si vous obtenez une erreur lors de l'installation du .apk disant quelque chose comme "Il ya un problème paquet."il se pourrait que vous n'avez pas demandé l'autorisation de lecture/écriture ou le fichier que vous essayez d'installer n'existe pas ou est corrompu.

82
répondu just_user 2018-06-11 14:22:35

Ce qui pourrait être le problème, vous avez

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

dans ton exemple, il devrait être

install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

installer est le nom de l'intention.

4
répondu Rob Francis 2016-09-14 12:53:37