Installer l'Application programmatically sur Android
je suis intéressé de savoir s'il est possible d'installer de manière programmatique un apk téléchargé dynamiquement à partir d'une application Android personnalisée.
14 réponses
vous pouvez facilement lancer un lien de marché ou une invite d'installation:
Intent promptInstall = new Intent(Intent.ACTION_VIEW)
.setDataAndType(Uri.parse("file:///path/to/your.apk"),
"application/vnd.android.package-archive");
startActivity(promptInstall);
Intent goToMarket = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("market://details?id=com.package.name"));
startActivity(goToMarket);
Cependant, vous ne pouvez pas installer .apk sans que l'utilisateur permission explicite ; non, sauf si l'appareil et votre programme est enracinée.
File file = new File(dir, "App.apk");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);
j'ai eu le même problème et après plusieurs tentatives, il a travaillé pour moi de cette façon. Je ne sais pas pourquoi, mais mettre des données et taper séparément a gâché mon intention.
Eh bien, j'ai creusé plus profondément, et j'ai trouvé des sources D'application PackageInstaller à partir de Android Source.
https://github.com/android/platform_packages_apps_packageinstaller
du Manifeste j'ai trouvé qu'il faut une permission:
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
et le processus d'installation proprement dit se produit après confirmation
Intent newIntent = new Intent();
newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mPkgInfo.applicationInfo);
newIntent.setData(mPackageURI);
newIntent.setClass(this, InstallAppProgress.class);
String installerPackageName = getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
if (installerPackageName != null) {
newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName);
}
startActivity(newIntent);
les solutions proposées à cette question s'appliquent toutes aux targetSdkVersion
s de 23 et moins. Pour Android N, C'est-à-dire API Niveau 24, et au-dessus, cependant, ils ne fonctionnent pas et plantent avec l'Exception suivante:
android.os.FileUriExposedException: file:///storage/emulated/0/... exposed beyond app through Intent.getData()
cela est dû au fait que à partir D'Android 24, le Uri
pour l'adressage du fichier téléchargé a changé. Par exemple ,un fichier d'installation nommé appName.apk
stocké sur le système de fichier externe primaire de l'application avec nom du paquet com.example.test
serait comme
file:///storage/emulated/0/Android/data/com.example.test/files/appName.apk
pour API 23
et plus bas, alors que quelque chose comme
content://com.example.test.authorityStr/pathName/Android/data/com.example.test/files/appName.apk
pour API 24
et plus.
plus de détails à ce sujet peuvent être trouvés ici et je ne vais pas passer par là.
pour répondre à la question pour targetSdkVersion
de 24
et plus, il faut suivre ces étape:
Ajoutez ce qui suit au AndroidManifest.xml:
<application
android:allowBackup="true"
android:label="@string/app_name">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.authorityStr"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths"/>
</provider>
</application>
2. Ajouter le fichier paths.xml
suivant au dossier xml
sur res
dans src, main:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="pathName"
path="pathValue"/>
</paths>
le pathName
est celui montré dans l'exemple de contenu exemplaire ci-dessus et pathValue
est le chemin réel sur le système.
Ce serait une bonne idée de mettre un "."(sans guillemets) pour pathValue dans ce qui précède si vous ne voulez pas ajouter d'extra répertoire.
-
écrivez le code suivant pour installer l'apk avec le nom
appName.apk
sur le système de fichier externe primaire:File directory = context.getExternalFilesDir(null); File file = new File(directory, fileName); Uri fileUri = Uri.fromFile(file); if (Build.VERSION.SDK_INT >= 24) { fileUri = FileProvider.getUriForFile(context, context.getPackageName(), file); } Intent intent = new Intent(Intent.ACTION_VIEW, fileUri); intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true); intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); context.startActivity(intent); activity.finish();
aucune permission n'est également nécessaire lorsque vous écrivez dans le répertoire privé de votre propre application sur le système de fichiers externe.
j'ai écrit une bibliothèque AutoUpdate ici dans laquelle j'ai utilisé ce qui précède.
je veux juste partager le fait que mon fichier apk a été enregistré dans le répertoire "Data" de mon application et que j'avais besoin de changer les permissions sur le fichier apk pour être lisible dans le monde entier afin de le permettre d'être installé de cette façon, sinon le système lançait "erreur D'analyse: il y a un problème D'analyse du paquet"; donc en utilisant la solution de @Horaceman qui fait:
File file = new File(dir, "App.apk");
file.setReadable(true, false);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);
suivez ces étapes:
1 - ajouter le texte suivant à la AndroidManifest.xml
:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths"/>
</provider>
2 - ajouter les chemins suivants.fichier xml dans le dossier xml (s'il n'existe pas le créer) sur res dans src, main
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_file"
path="."/>
</paths>
le nom de chemin est celui indiqué dans l'exemple d'uri de contenu exemplaire ci-dessus et pathValue est le chemin réel sur le système. Ce serait une bonne idée de mettre un "." pour pathValue dans ce qui précède si vous ne voulez pas ajouter de sous-répertoire supplémentaire.
3 - écrivez le code suivant pour exécuter vos fichiers Apk:
File file = "path of yor apk file";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri fileUri = FileProvider.getUriForFile(getBaseContext(), getApplicationContext().getPackageName() + ".provider", file);
Intent intent = new Intent(Intent.ACTION_VIEW, fileUri);
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
et merci à Ali Nemati Hayati d'être le premier à écrire Solution profil ali-nemati-hayati
Oui c'est possible. Mais pour cela vous avez besoin du téléphone pour installer les sources non vérifiées. Par exemple, slideMe. Je pense que la meilleure chose que vous pouvez faire est de vérifier si l'application est présente et envoyer une intention pour le marché Android. vous devriez utiliser quelque chose le schéma d'url pour android Market.
market://details?id=package.name
je ne sais pas exactement comment démarrer l'activité, mais si vous commencez une activité avec ce type d'url. Il devrait ouvrir le marché android et vous donner la le choix d'installer l'application.
il est intéressant de noter que si vous utilisez le DownloadManager
pour lancer votre téléchargement, assurez-vous de le sauvegarder à un endroit externe par exemple setDestinationInExternalFilesDir(c, null, "<your name here>).apk";
. L'intention avec un type de paquet-archive ne semble pas aimer le schéma content:
utilisé avec les téléchargements vers un emplacement interne, mais il fait comme file:
. (Essayer d'envelopper le chemin interne dans un objet fichier et ensuite obtenir le chemin ne fonctionne pas non plus, même si cela aboutit à une url file:
, car l'application ne va pas analyser l'apk; regarde comme il doit être externe.)
exemple:
int uriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
String downloadedPackageUriString = cursor.getString(uriIndex);
File mFile = new File(Uri.parse(downloadedPackageUriString).getPath());
Intent promptInstall = new Intent(Intent.ACTION_VIEW)
.setDataAndType(Uri.fromFile(mFile), "application/vnd.android.package-archive")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
appContext.startActivity(promptInstall);
une autre solution qui ne nécessite pas de code dur pour l'application réceptrice et qui est donc plus sûre:
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData( Uri.fromFile(new File(pathToApk)) );
startActivity(intent);
juste une extension, si quelqu'un a besoin d'une bibliothèque alors ce pourrait aider. Merci à Raghav
essayez cette
String filePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
String title = filePath.substring( filePath.lastIndexOf('/')+1, filePath.length() );
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(filePath)), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
MainActivity.this.startActivity(intent);
UpdateNode fournit une API pour Android pour installer des paquets APK à partir de l'intérieur d'une autre application.
Vous pouvez simplement définir votre mise à jour en ligne et intégrer L'API dans votre application - c'est tout.
Actuellement, l'API est en Beta, mais vous pouvez déjà faire quelques tests vous-même.
En plus de cela, UpdateNode offre également l'affichage de messages système très utile si vous voulez dire quelque chose d'important à vos utilisateurs.
Je fais partie de l'équipe de développement client et j'utilise au moins la fonctionnalité de message pour ma propre application Android.
essayez ceci - Écrire sur le Manifeste:
uses-permission android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions"
écrivez le Code:
File sdCard = Environment.getExternalStorageDirectory();
String fileStr = sdCard.getAbsolutePath() + "/Download";// + "app-release.apk";
File file = new File(fileStr, "app-release.apk");
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
startActivity(promptInstall);
ajouter D'abord la ligne suivante à AndroidManifest.xml:
<uses-permission android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions" />
ensuite, utilisez le code suivant pour installer apk:
File sdCard = Environment.getExternalStorageDirectory();
String fileStr = sdCard.getAbsolutePath() + "/MyApp";// + "app-release.apk";
File file = new File(fileStr, "TaghvimShamsi.apk");
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
startActivity(promptInstall);