Android PackageInstaller,在更新后重新打开应用程序

Jac*_*nti 7 android android-pendingintent device-owner packageinstaller cosu

我正在开发一个作为设备所有者运行的应用程序,我想在其中构建一个自动更新程序.

为此,我使用PackageInstaller,因为我拥有使用它的权限,因为我的设备所有者位置.

private void installPackage(InputStream inputStream)
        throws IOException {
    notifyLog("Inizio aggiornamento...");
    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
    int sessionId = packageInstaller.createSession(new PackageInstaller
            .SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));
    PackageInstaller.Session session = packageInstaller.openSession(sessionId);

    long sizeBytes = 0;

    OutputStream out = null;
    out = session.openWrite("my_app_session", 0, sizeBytes);

    int total = 0;
    byte[] buffer = new byte[65536];
    int c;
    while ((c = inputStream.read(buffer)) != -1) {
        total += c;
        out.write(buffer, 0, c);
    }
    session.fsync(out);
    inputStream.close();
    out.close();

    session.commit(createIntentSender(sessionId));
}

private IntentSender createIntentSender(int sessionId) {
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            context,
            sessionId,
            new Intent(LauncherReceiver.START_INTENT),
            0);
    return pendingIntent.getIntentSender();
}
Run Code Online (Sandbox Code Playgroud)

更新是正确的,但问题是它不会在更新后重新打开应用程序本身,即使我设置一个IntentSender将操作广播LauncherReceiver.START_INTENT到新的应用程序实例(这将启动它).

这是我的接收者:

public class LauncherReceiver extends BroadcastReceiver {

    public static final String START_INTENT = "com.aaa.aaa.action.START";

    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("CALL RECEIVER!!");
        Intent startIntent = new Intent(context, StartActivity.class);
        startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
        context.startActivity(startIntent);
    }
}
Run Code Online (Sandbox Code Playgroud)

它已在我的清单中注册:

    <receiver android:name=".receivers.LauncherReceiver" android:enabled="true" android:exported="true">
        <intent-filter>
            <action android:name="com.aaa.aaa.action.START"></action>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
Run Code Online (Sandbox Code Playgroud)

如果我通过CLI调用它,它可以工作:

am broadcast -a com.worldnet.gestitruck.action.START 
Run Code Online (Sandbox Code Playgroud)

所以接收器工作但由于某种原因它不能从Package Installer会话提交工作.该应用由于升级而关闭,但不会再次打开.

如果我改为createIntentSender:

private IntentSender createIntentSender(int sessionId) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:0123456789"));
    PendingIntent pendingIntent = PendingIntent.getActivity(context,sessionId,intent,0);
    return pendingIntent.getIntentSender();
}
Run Code Online (Sandbox Code Playgroud)

它实际上打开了电话服务.所以我认为问题在于升级生命周期,因为在生成广播操作时应用程序还没有准备好.

此外,我再次尝试,我创建了一个侧面应用程序,除了将广播操作调用到我的主应用程序之外什么都不做,所以我可以调用这个侧面应用程序并通过这个"双步"它实际上可以重新打开刚刚更新的应用程序.问题是我必须安装两个应用程序= /

有谁能够帮我?有没有办法重新打开刚刚更新的应用程序?

Dav*_*ser 12

从 Android 5 开始(我不知道确切的 API 级别),Android 将在您的应用更新后发送Intent带有 ACTION=的广播"android.intent.action.MY_PACKAGE_REPLACED"。只需添加

        <intent-filter>
            <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
        </intent-filter>
Run Code Online (Sandbox Code Playgroud)

到你的<receiver>声明,你应该能够听到这个并在onReceive().

  • 我传递给 ```session.commit()``` 的 PendingIntent 应该是什么样的?关于 API 级别,此方法应该对我有用,但我无法让它工作。应用程序关闭,安装完成后没有任何反应。/sf/ask/4413559531/ (3认同)