I'm trying to install APK in android 7 (samsung and sony) using regular Runtime.getRuntime.exec()
routine. The installation fails with the following exception in the logcat:
09-04 14:14:33.932 16623-16623/? D/AndroidRuntime: Calling main entry com.android.commands.pm.Pm
09-04 14:14:33.939 3695-3876/? D/PackageInstaller: installation of android.content.pm.PackageInstaller$SessionParams@a4d2f0e for non-container user 0
09-04 14:14:33.940 16623-16623/? E/Pm: Error
java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1699)
at android.os.Parcel.readException(Parcel.java:1646)
at android.content.pm.IPackageInstaller$Stub$Proxy.createSession(IPackageInstaller.java:249)
at com.android.commands.pm.Pm.doCreateSession(Pm.java:530)
at com.android.commands.pm.Pm.runInstall(Pm.java:369)
at com.android.commands.pm.Pm.run(Pm.java:142)
at com.android.commands.pm.Pm.main(Pm.java:99)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:301)
09-04 14:14:33.941 16623-16623/? I/art: System.exit called, status: 1
09-04 14:14:33.941 16623-16623/? I/AndroidRuntime: VM exiting with result code 1
I try to implement that so:
Process proc = Runtime.getRuntime().exec("pm install /sdcard/imo.apk");
and so:
Process proc = Runtime.getRuntime().exec(new String[]{"/system/bin/sh","-c","/system/bin/pm install /sdcard/imo.apk"});
But exception occurs in the both cases.
In androids less than 7 it works.
The permissions are:
declared permissions:
android.permission.INTERACT_ACROSS_USERS_FULL: prot=normal
requested permissions:
android.permission.BIND_NOTIFICATION_LISTENER_SERVICE
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_LOGS
User 0: ceDataInode=393939 installed=true hidden=false suspended=false stopped=false notLaunched=false enabled=0
gids=[1007]
runtime permissions:
android.permission.CLEAR_APP_USER_DATA: granted=true
android.permission.INSTALL_PACKAGES: granted=true
android.permission.READ_EXTERNAL_STORAGE: granted=true
android.permission.INTERACT_ACROSS_USERS_FULL: granted=true
android.permission.READ_LOGS: granted=true
android.permission.CLEAR_APP_CACHE: granted=true
android.permission.WRITE_EXTERNAL_STORAGE: granted=true
Installation does succeed thru the shell. Thanks in advance
I had the same issue but I solved it by a different way. My app is a launcher and it has system privileges. It is my solution.
Add to manifest header android:sharedUserId="android.uid.system"
Add this permission to mainifest android:name="android.permission.INSTALL_PACKAGES"
Add this code to some background thread
try { String cmd = "pm install -r -i " + LAUNCHER_PACKAGE_ID + " " + activity.getFileStreamPath(apkPath); Process p = Runtime.getRuntime().exec(cmd); p.waitFor(); } catch (Exception e) { Log.d(TAG, "SilentInstallActivity error: " + e); }
Sign your android application with system key.
I found the answer. Although I'm not sure what is the exact reason but this works. I referred to this blog https://shoewann0402.github.io/2017/06/27/android-n-installSilent-and-uninstallSilent/ , but it's all Chinese. In case you also understand Chinese or you use Google translation.
The new command should be like this:
pm install -i <you installer package name> --user 0 /sdcard/com.ifeng.news2.apk
This is some new security mechanism added by Google and it requires you to install using userId 0. Also you need to specify the installer package name.
Then in your installer app's manifest file, add android.permission.INTERACT_ACROSS_USERS_FULL
this permission. Then it should work. I saw there are some docs about the userId but just don't have enough time to dig into it. If you are interested, you can search by yourself.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.