Reputation: 1582
I have system-level app with android:sharedUserId="android.uid.system" (UID: 1000).
Device is not rooted! INSTALL_PACKAGES permission is included to Manifest.
Can I install downloaded *.apk silently?
Upvotes: 40
Views: 51807
Reputation: 343
In order to autoupdate your app silently, you have 2 options.
Use PackageInstaller class for autoupdate.
private boolean installPackage(Context context, String packageName, String apkPath) throws IOException {
File f = new File(apkPath);
if(!f.exists()){
Log.i(TAG, "[installPackage] Apk file cannot be updated because file is not available. apkPath:"+apkPath);
return false;
}
FileInputStream in = null;
OutputStream out = null;
PackageInstaller.Session session = null;
int sessionId = 0;
try{
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
params.setAppPackageName(packageName);
// set params
sessionId = packageInstaller.createSession(params);
session = packageInstaller.openSession(sessionId);
// Copy APK file bytes into OutputStream provided by install Session
out = session.openWrite(packageName, 0, -1);
in = new FileInputStream(f);
byte[] buffer = new byte[1024];
int c;
while ((c = in.read(buffer)) > 0) {
out.write(buffer, 0, c);
}
out.flush();
session.fsync(out);
}catch (Exception e){
Log.e(TAG, "[installPackage] apkPath:"+apkPath+", error:", e);
return false;
}finally {
StreamUtil.closeSilently(out, in);
out = null;
in = null;
System.gc();
}
try{
// The app gets killed after installation session commit
session.commit(PendingIntent.getBroadcast(context, sessionId, new Intent("android.intent.action.MAIN"), getPendingIntentFlag(0)).getIntentSender());
session.close();
}catch (Exception e){
Log.e(TAG, "[installPackage] session commit error:", e);
return false;
}
return true;
}
public int getPendingIntentFlag(int flag){
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? (PendingIntent.FLAG_IMMUTABLE | flag) : flag;
}
Upvotes: 1
Reputation: 1582
I`ve found the issue.
android.permission.INSTALL_PACKAGES
" permission.signapk.jar
" with certificate that I`ve got from manufacturer of my device. pm install /.../app.apk
" without "su". It works!
P.S. Updating application using just "pm install" doesn`t replace existing application with new one, but returns exit_value = 0. So to update there are two ways:
pm install -r /.../app.apk
";pm uninstall com.mydomain.myapp
" (you need "android.permission.DELETE_PACKAGES
" permission) and then install new one.Upvotes: 45
Reputation: 82563
No, you cannot. Simply having the same UID isn't enough. You must also be signed with the same key as the ROM itself.
Silently installing apps, or updates to your own app, isn't allowed for security reasons.
Upvotes: 6