99 votes

Installer des applications en silence, avec l'autorisation INSTALL_PACKAGES.

J'essaie d'installer silencieusement l'apk dans le système. Mon application est située dans /system/app et a obtenu la permission "Android.permission.INSTALL_PACKAGES".

Cependant, je ne trouve nulle part comment utiliser cette permission. J'ai essayé de copier des fichiers dans /data/app mais sans succès. J'ai également essayé d'utiliser ce code

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(
            Uri.parse("file:///sdcard/app.apk"),
            "application/vnd.android.package-archive");
    startActivity(intent);

Mais ce code ouvre le dialogue d'installation standard. Comment puis-je installer une application silencieusement sans Root avec des droits d'accès ? android.permission.INSTALL_PACKAGES ?

PS Je suis en train d'écrire une application qui installera de nombreux apks depuis un dossier dans le système au premier démarrage (en remplacement de l'assistant d'installation). J'en ai besoin pour alléger le firmware.

Si vous pensez que j'écris un virus : Tous les programmes sont installés dans /data/app. La permission Install_packages ne peut être accordée qu'aux programmes de niveau système situés dans /system/app ou signés avec la clé système. Donc le virus ne peut pas y accéder.

Comme dit http://www.mail-archive.com/Android-porting@googlegroups.com/msg06281.html Les applications PEUVENT être installées silencieusement si elles ont la permission install_packages. De plus, vous n'avez pas besoin de la permission Install_packages pour installer des paquets de manière non silencieuse. Plus http://www.androidzoom.com/android_applications/tools/silent-installer_wgqi.html

9 votes

Supposons qu'il fabrique un tel dispositif en tant que fabricant d'équipement d'origine ?

50 votes

@Fosco Qui s'en soucie ? C'est une question valable comme le décrit dascandy. C'est généralement improductif quand les gens répondent à ce genre de questions par "Vous ne devriez pas faire ça". Quelle compréhension acquiert-on avec ce genre de réponse ?

3 votes

En parlant d'improductivité tu as un peu plus de deux ans de retard sur cette fête Zach, et la question est bien différente de ce qu'elle était au départ.

63voto

inazaruk Points 37760

Votre premier pari est d'examiner les fonctions natives d'Android. PackageInstaller . Je vous recommande de modifier cette application comme vous le souhaitez, ou d'en extraire les fonctionnalités nécessaires.


Plus précisément, si vous regardez dans PackageInstallerActivity et sa méthode onClickListener :

 public void onClick(View v) {
    if(v == mOk) {
        // Start subactivity to actually install the application
        Intent newIntent = new Intent();
        ...
        newIntent.setClass(this, InstallAppProgress.class);
        ...
        startActivity(newIntent);
        finish();
    } else if(v == mCancel) {
        // Cancel and finish
        finish();
    }
}

Vous remarquerez alors que l'installateur actuel se trouve dans InstallAppProgress classe. En inspectant cette classe, vous constaterez que initView est la fonction principale de l'installateur, et la dernière chose qu'il fait est d'appeler à PackageManager 's installPackage fonction :

public void initView() {
...
pm.installPackage(mPackageURI, observer, installFlags, installerPackageName);
}

L'étape suivante consiste à inspecter PackageManager qui est une classe abstraite. Vous trouverez installPackage(...) à cet endroit. La mauvaise nouvelle est qu'elle est marquée par @hide. Cela signifie qu'elle n'est pas directement disponible (vous ne pourrez pas compiler avec un appel à cette méthode).

 /**
  * @hide
  * ....
  */
  public abstract void installPackage(Uri packageURI,
             IPackageInstallObserver observer, 
             int flags,String installerPackageName); 

Mais vous pourrez accéder à ces méthodes par réflexion.

Si vous souhaitez savoir comment PackageManager 's installPackage est mise en œuvre, jetez un coup d'œil à PackageManagerService .

Résumé

Vous devrez obtenir l'objet du gestionnaire de paquets via Context 's getPackageManager() . Ensuite, vous appellerez installPackage par réflexion.

2 votes

Au secours ! Cette technique a pour résultat : Causé par : java.lang.SecurityException : Ni l'utilisateur 10101 ni le processus actuel ne possèdent Android.permission.INSTALL_PACKAGES. Même si mon application possède cette permission

14 votes

Votre application demande cette permission, mais Android ne l'accorde pas aux applications tierces. Voir LogCat pour les journaux relatifs aux autorisations.

0 votes

@inazaruk j'ai lu que les applications installées dans /system/app obtiendront automatiquement la permission d'utiliser install_pakages mais comme décrit dans ce poste il semble que cela ne fonctionne pas. pouvez-vous me donner quelques conseils ?

13voto

frankkie12345 Points 171

J'ai vérifié comment ADB installe les applications.
- Il copie l'APK à /data/local/tmp
- il exécute "shell:pm install /data/local/tmp/app.apk".

J'ai essayé de reproduire ce comportement en faisant ce qui suit : (sur PC, en utilisant un câble USB)
adb push app.apk /sdcard/app.apk
adb shell
$ pm install /sdcard/app.apk
Cela fonctionne. L'application est installée.

J'ai créé une application (nommée AppInstall) qui doit installer l'autre application.
(installé normalement, appareil non rooté)
C'est le cas :
Runtime.getRuntime().exec("pm install /sdcard/app.apk").waitFor();
Mais cela donne l'erreur :
java.lang.SecurityException: Neither user 10019 nor current process has android.permission.INSTALL_PACKAGES.
Il semble que l'erreur soit générée par pm, pas par AppInstall.
Parce que le SecurityException n'est pas attrapé par AppInstall et l'application ne se plante pas.

J'ai essayé la même chose sur un appareil enraciné (même application et AppInstall) et ça a marché comme sur des roulettes.
(également installé normalement, pas dans /system ou autre)
AppInstall n'a même pas demandé l'autorisation de Root.
Mais c'est parce que l'enveloppe est toujours # au lieu de $ sur cet appareil.

En fait, vous avez besoin de Root pour installer une application dans /system, n'est-ce pas ?
J'ai essayé adb remount sur l'appareil non rooté et j'ai obtenu :
remount failed: Operation not permitted.
C'est pourquoi je n'ai pas pu essayer le truc /system sur l'appareil non rooté.

Conclusion : vous devez utiliser un appareil enraciné
J'espère que cela vous aidera :)

0 votes

Je n'arrive pas à le faire fonctionner. Il est intéressant de noter que la commande fonctionne bien dans l'interpréteur de commandes ADB, mais qu'elle ne semble pas fonctionner lorsque j'essaie de l'exécuter par programme.

0 votes

Oui, j'ai le même problème - ça marche dans le shell, mais pas quand on l'appelle depuis mon application, même si je l'appelle via su )

0 votes

Existe-t-il un autre moyen de travailler avec les appareils Google, par exemple en obtenant des droits d'administrateur ?

9voto

iLRedEiMAtTi Points 101

Vous devez définir

<uses-permission
    android:name="android.permission.INSTALL_PACKAGES" />

dans votre manifeste, alors si vous êtes dans la partition système (/system/app) ou si vous avez votre application signée par le fabricant, vous allez avoir la permission INSTALL_PACKAGES.

Ma suggestion est de créer un petit projet Android avec un niveau de compatibilité 1.5 utilisé pour appeler installPackages via la réflexion et d'exporter un jar avec des méthodes pour installer les paquets et pour appeler les méthodes réelles. Ensuite, en important le jar dans votre projet, vous serez prêt à installer des paquets.

5voto

Vladimir Points 71

J'ai essayé sur Android 4.2.2 rooté et cette méthode fonctionne pour moi :

private void installApk(String filename) {
    File file = new File(filename); 
    if(file.exists()){
        try {   
            final String command = "pm install -r " + file.getAbsolutePath();
            Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
            proc.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
     }
}

2 votes

La question portait sur l'installation d'applications sans Root, mais avec la permission du système "INSTALL_PACKAGES". Je vois "su" dans votre réponse, donc cela nécessite Root.

0 votes

Merci beaucoup pour cette réponse ! J'avais le même code mais j'utilisais "adb install -r" au lieu de "pm install -r" et cela ne fonctionnait PAS pour moi. Vous m'avez fait gagner beaucoup de temps !

0 votes

@Vladmir j'ai besoin de votre aide. Pouvez-vous me donner un peu de temps. Je vous en serai très reconnaissant.

4voto

POMATu Points 907

Je n'avais aucune idée de la façon de procéder, car personne ne m'a répondu à ce moment-là, et je n'ai trouvé aucune documentation sur cette permission. J'ai donc trouvé ma propre solution. Elle est plus mauvaise que la vôtre, mais c'est quand même une solution.

J'ai installé busybox, qui a mis la permission 777 sur /data/app (je ne me soucie pas de la sécurité). Puis j'ai exécuté "busybox install" à partir de l'application. Cela fonctionne, mais a une grande fuite de sécurité. Si vous définissez les permissions 777, aucun Root n'est nécessaire.

3 votes

Avez-vous utilisé un code comme celui-ci ? Process install; install = Runtime.getRuntime().exec("/system/bin/busybox install " + myAPK.getAbsolutePath()); int iSuccess = install.waitFor();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X