Android PackageInstaller, заново откройте приложение после его обновления

Я занимаюсь разработкой приложения, которое работает как владелец устройства, и я хочу создать в нем автоматическое обновление.

Для этого я использую 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();
}

Обновление идет правильно, но проблема в том, что оно не открывает приложение само после обновления, даже если я настроил 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);
    }
}

И это прописано в моем манифесте:

    <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>

Если я называю это CLI, это работает:

am broadcast -a com.worldnet.gestitruck.action.START 

Таким образом, получатель работает, но по какой-то причине он не работает с фиксацией сеанса 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();
}

это фактически открывает телефонный сервис. Поэтому я думаю, что проблема заключается в жизненном цикле обновления, так как приложение не готово, когда запускается широковещательное действие.

Более того, я сделал еще одну попытку и создал побочное приложение, которое не вызывает ничего, кроме вызова действия широковещания для моего основного приложения, поэтому я могу вызвать это побочное приложение, и с помощью этого "двойного шага" оно может фактически заново открыть только что обновленное приложение. Проблема в том, что мне нужно установить два приложения =/

Кто-нибудь может мне помочь? Есть ли способ повторно открыть только что обновленное приложение?

1 ответ

Решение

Начиная примерно с Android 5 (я не знаю точный уровень API), Android будет отправлять трансляцию Intent с действием ="android.intent.action.MY_PACKAGE_REPLACED" после обновления вашего приложения. Просто добавь

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

на ваш <receiver> объявление, и вы должны быть в состоянии прослушать это и перезапустить приложение в onReceive(),

Другие вопросы по тегам