4

我想通过使用PackageInstaller和PackageManager API在我的设备上安装软件包(来自运行在其上的设备所有者应用程序)。我一直在寻找例子,但找不到符合我需要的任何东西。Android Lollipop - PackageInstaller.Session commit()

这里是我的代码安装Facebook应用程序的示例:

PackageManager pm = getPackageManager(); 
PackageInstaller mPackageInstaller = pm.getPackageInstaller(); 
PackageInstaller.SessionParams mSessionParams = new PackageInstaller.SessionParams(SessionParams.MODE_FULL_INSTALL); 

mSessionParams.setReferrerUri(Uri.parse("file:///mnt/sdcard/Download/Facebook.apk")); 
int mSessionId = mPackageInstaller.createSession(mSessionParams); 

PackageInstaller.Session mPkgSession = PackageInstaller.openSession(mSessionId); 
OutputStream mOStream = mPkgSession.openWrite("com.facebook.katana", 0, -1); 
mPkgSession.fsync(mOStream); 

我想,下一个功能我需要启动一个“提交(IntentSender statusReceiver)”。

那么请告诉我如何使用commit(),特别是如何声明一个合适的IntentSender来安装存储在/ sdcard中的APK。

谢谢!

回答

0

您不能在具有PackageInstaller.Session.commit()的新创建的用户中不安静地安装第三方应用程序,而没有特定的“权限”。 您需要:

INSTALL_PACKAGES权限。但是,此权限不适用于第三方应用程序。因此,即使使用您的个人资料所有者应用程序,您也不会获得此特定权限 以ROOT_UID的身份运行进程。这意味着你必须根据设备。

+0

由于我lanching从设备所有者应用这些功能,以下权限似乎是确定: <使用的许可机器人:名称=“ANDROID.PERMISSION .INSTALL_PACKAGES“/> – CyrBt

+1

我可以实现无提示安装吗?如果我的应用程序是使用制造商的signed.jar签名的,并且安装为系统应用程序? – beginner

1

因此,经过几天寻找一种使用IntentSender的方法,我发现它实际上包含在PendingIntent中。

下面是可以使用的一个代码:

Intent coucou = new Intent(this, ReceivedCommitActivity.class); 
coucou.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

PendingIntent pCoucou = PendingIntent.getActivity(this, 0, coucou,0); 
IntentSender mIntentSender = pCoucou.getIntentSender(); 

mPkgSession.commit(mIntentSender); 
3

这是可能的从在Android 6.0及以上。

  • 让您的应用成为设备所有者。

一旦您的应用获得设备所有者权限,我们就可以安装,卸载和更新,无需任何用户干预。

public static boolean installPackage(Context context, InputStream in, String packageName) 
     throws IOException { 
    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); 
    PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
      PackageInstaller.SessionParams.MODE_FULL_INSTALL); 
    params.setAppPackageName(packageName); 
    // set params 
    int sessionId = packageInstaller.createSession(params); 
    PackageInstaller.Session session = packageInstaller.openSession(sessionId); 
    OutputStream out = session.openWrite("COSU", 0, -1); 
    byte[] buffer = new byte[65536]; 
    int c; 
    while ((c = in.read(buffer)) != -1) { 
     out.write(buffer, 0, c); 
    } 
    session.fsync(out); 
    in.close(); 
    out.close(); 

    session.commit(createIntentSender(context, sessionId)); 
    return true; 
} 

卸载:

String appPackage = "com.your.app.package"; 
Intent intent = new Intent(getActivity(), getActivity().getClass()); 
PendingIntent sender = PendingIntent.getActivity(getActivity(), 0, intent, 0); 
PackageInstaller mPackageInstaller = getActivity().getPackageManager().getPackageInstaller(); 
mPackageInstaller.uninstall(appPackage, sender.getIntentSender()); 
+0

我可以通过OTA(Over The Air)使用此功能更新app1中的app2吗? – beginner

+0

是的,先生。 @初学者。事实上,在github上有一个例子(github上的testdpc)..还有一个指南。https://codelabs.developers.google.com/codelabs/cosu/#0 – amalBit

+1

整个代码正在运行没有错误..但我看不到安装在我的设备中的应用程序。 –

相关问题