【问题标题】:Launch application after PackageInstaller finished (self) updatingPackageInstaller 完成(自我)更新后启动应用程序
【发布时间】:2020-07-23 09:14:52
【问题描述】:

PackageInstaller 成功(自我)更新应用程序后,应用程序关闭且不再启动。

可能重复:Android PackageInstaller, re-open the app after it updates itself

情况差不多,先给个代码sn-ps吧。

AndroidManifest.xml

<receiver android:name=".UpdateReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
</receiver>

我的 PackageInstaller 会话在 AsyncTask 中运行:


PackageInstaller packageInstaller = ctx.getPackageManager().getPackageInstaller();
        PackageInstaller.SessionParams parameters = new PackageInstaller.SessionParams(
                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
        parameters.setAppPackageName(StaticData.TerminalPackageName);

        progressChanged(10);

        try {
            int sessionId = packageInstaller.createSession(parameters);
            PackageInstaller.Session session = packageInstaller.openSession(sessionId);

            ProgressApproximatorHandler progress = startProgressApproximator(10, 100, 5);

            OutputStream installerStream = session.openWrite("INSTALL_TERMINAL", 0, mApplicationLength);
            installerStream.write(firmwareData, 0, mApplicationLength);

            // This call ensures every byte on the stream is committed to disk.
            session.fsync(installerStream);
            installerStream.close();

            Intent intent = new Intent(ctx, UpdateReceiver.class);
            intent.setAction(Intents.APK_INSTALL_FINISHED_INTENT);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(
                    mContext.get(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

            // Sealing the session.
            session.commit(pendingIntent.getIntentSender());
            session.close();
            progress.stop();

        } catch (IOException e) {
            Logger.error(mLogTag, e, "Failed to create an installer session.");
            return false;
        }

在这个sn-p的最后,你可以看到一个Intent to send的设置。我尝试了很多变体,但没有一个奏效。例如:

Intent intent = new Intent(Intents.APK_INSTALL_FINISHED_INTENT);

Intent intent = new Intent("android.intent.action.MY_PACKAGE_REPLACED");

我的接收者永远不会收到意图。

public class UpdateReceiver extends BroadcastReceiver {
    private static final String TAG = "UPDATE";
    @Override
    public void onReceive(Context context, Intent intent) {
        Logger.info(TAG, "Intent action: " + intent.getAction());
        Logger.info(TAG, "updated");
    }
}

编辑:不知何故,我设法自动重启了应用程序,但它在 1-3 秒后被杀死。在系统的logcat中发现如下错误。

W/ActivityManager: Unable to send startActivity intent
    java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.MY_PACKAGE_REPLACED from pid=-1, uid=10071
        at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:18195)
        at com.android.server.am.ActivityManagerService.broadcastIntentInPackage(ActivityManagerService.java:18777)
        at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:308)
        at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:205)
        at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:7409)
        at android.content.IntentSender.sendIntent(IntentSender.java:190)
        at android.content.IntentSender.sendIntent(IntentSender.java:154)
        at com.android.server.pm.PackageInstallerService$PackageInstallObserverAdapter.onPackageInstalled(PackageInstallerService.java:1069)
        at android.app.PackageInstallObserver$1.onPackageInstalled(PackageInstallObserver.java:34)
        at com.android.server.pm.PackageInstallerSession.dispatchSessionFinished(PackageInstallerSession.java:1137)
        at com.android.server.pm.PackageInstallerSession.-wrap2(PackageInstallerSession.java)
        at com.android.server.pm.PackageInstallerSession$4.onPackageInstalled(PackageInstallerSession.java:648)
        at com.android.server.pm.PackageManagerService.handlePackagePostInstall(PackageManagerService.java:1809)
        at com.android.server.pm.PackageManagerService.-wrap25(PackageManagerService.java)
        at com.android.server.pm.PackageManagerService$PackageHandler.doHandleMessage(PackageManagerService.java:1438)
        at com.android.server.pm.PackageManagerService$PackageHandler.handleMessage(PackageManagerService.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.os.HandlerThread.run(HandlerThread.java:61)
        at com.android.server.ServiceThread.run(ServiceThread.java:46)

我不确定这是不是这个原因。

EDIT2:现在我收到了意图,因此应用程序正在运行。现在的问题是它在后台堆栈中。

我有一个启动器应用,可以重新启动主(更新)应用,但对我来说这听起来不是干净的代码。

EDIT3:

我尝试了大卫的回答,但收到以下错误:

E/ActivityManager: Failure starting process com.example.myapp
    java.lang.SecurityException: Package com.example.myapp is currently frozen!
        at com.android.server.pm.PackageManagerService.checkPackageStartable(PackageManagerService.java:3197)
        at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3789)
        at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3749)
        at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3630)
        at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:1255)
        at com.android.server.am.BroadcastQueue$BroadcastHandler.handleMessage(BroadcastQueue.java:172)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.os.HandlerThread.run(HandlerThread.java:61)
        at com.android.server.ServiceThread.run(ServiceThread.java:46)

请注意,这是由 android 系统引发的,而不是由我的应用程序引发的。

【问题讨论】:

  • MY_PACKAGE_REPLACED Intent 在您的应用更新后由 Android 广播。安装/更新成功了吗?
  • @DavidWasser 是的,它成功了。我用更多信息编辑了这个问题。

标签: android android-pendingintent device-owner packageinstaller cosu


【解决方案1】:

MY_PACKAGE_REPLACEDIntent 在您的应用更新后由 Android 广播。

要在更新后重新启动您的应用,您可以将启动 Intent 传递给 PackageInstaller,如下所示:

Intent intent = getPackageManager().getLaunchIntentForPackage("my.package.name");
PendingIntent pendingIntent = PendingIntent.getActivity(
                mContext.get(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());

这应该会导致您的应用在更新完成后重新启动。

【讨论】:

  • ActivityManager 抛出异常。我根据this编辑了问题。
  • 看起来有东西正在尝试启动您的应用,而 Android 仍在进行更新。
  • 但是如果您使用IntentPackageManager 重新启动您的应用程序,您可能不需要响应MY_PACKAGE_REPLACED 广播。尝试删除它,看看是否有帮助
【解决方案2】:

虽然 David Wasser 的回答可能是正确的。我正在结束我的案件,因为我有非常奇怪和未定义的行为,我很确定那是因为我使用的是自定义 ROM

【讨论】:

  • 这不是一个真正的答案。您应该编辑您的问题并将您的 cmets 添加到其中。
  • @DavidWasser 你是对的,稍后我会写一个更长的解释什么对我有用。感谢您的意见。
猜你喜欢
  • 2017-10-11
  • 2011-05-15
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 2012-02-15
  • 1970-01-01
  • 2021-06-01
  • 2014-12-06
相关资源
最近更新 更多