Как программно обновить apk и перезапустить приложение?

Я пробовал много способов, заданных в StackOverFlow и на другом веб-сайте, но на самом деле это не работает.

Моя проблема в том, что у меня есть это приложение, которое мне нужно обновить и после обновления, оно должно автоматически снова включить то же приложение (обновленное).

Это мой код:

private synchronized void runRootUpdate() {    
    // Install Updated APK
    String command = "pm install -r " + downloadPath + apkFile;
    Process proc = Runtime.getRuntime().exec(new String[] {"su", "-c", command});
    int test = proc.waitFor(); // Error is here.

    if (proc.exitValue() == 0) {
        // Successfully installed updated app
        doRestart()
    } else {
        // Fail
        throw new Exception("Root installation failed");
    }
}

private void doRestart() {
    Intent mStartActivity = new Intent(context, MainActivity.class);
    int mPendingIntentId = 123456;
    PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
    System.exit(0);
}

Взгляните на мою "Ошибка здесь". Мое старое приложение установит новое обновленное приложение и убьет себя, поэтому нет proc.waitFor() и вернется на начальном экране, но обновляется новое обновленное приложение. Тем не менее, мне нужно, чтобы оно вернулось к самому себе. Могу ли я это сделать?

Ответ 1

Вместо того, чтобы устанавливать тревогу, для этого специально для этого зарегистрируйте Manifest зарегистрированный BroadcastReceiver. Он может либо слушать android.intent.action.PACKAGE_REPLACED (обратите внимание: в этой константе отсутствует действие слова) или android.intent.action.MY_PACKAGE_REPLACED

<receiver android:name="...">
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_REPLACED"></action>
        <data android:scheme="package" android:path="com.your.package" /> 
    </intent-filter>
</receiver>

После переустановки ресивер получит это сообщение, и вы сможете запустить Activity

Ответ 2

Обновление приложения связано с убийством всех его процессов. Вы должны установить будильник перед, запустив команду pm (с задержкой более 100 мс)

Ответ 3

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

Для немедленного обновления и запуска приложения необходимо выполнить следующие шаги.

Убедитесь, что у вас есть последний файл .apk на вашей SD-карте при обновлении приложения. Если он запускает его с помощью намерения, как показано ниже, для обновления

File file = new File(Environment.getExternalStorageDirectory(), "app-debug.apk"); // mention apk file path here
                if (file.exists()) {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
                    startActivity(intent);
                } else {
                    Toast.makeText(UpdateActivity.this, "file not exist", Toast.LENGTH_SHORT).show();
                }

Выше кода обновит ваше приложение по умолчанию для Android.

Создать широковещательный приемник, который будет знать, когда выполняется обновление

    <receiver android:name=".receiver.OnUpgradeReceiver">
                <intent-filter>
// Note: This intent can is available starting from API 12
                    <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
                </intent-filter>
            </receiver>

если вы используете api > 12 use

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

если вы используете api <= 12 use

  <action android:name="android.intent.action.PACKAGE_REPLACED" />
    <data android:scheme="package" android:path="your.app.package" />

Создайте широковещательный приемник для получения широковещательной передачи после действия обновления и запуска, который вы хотите

Пример:

public class OnUpgradeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
       // launch your fav activity from here.
    }
}

Выше радиовещательный приемник позволяет вам запускать приложение тихо.

Надеюсь, что это поможет вам.

Ответ 4

Хм... Зачем использовать этот жесткий метод, когда вы используете корневую установку? Почему бы не попробовать создать простую оболочку script для обновления приложения? Тогда вы не должны устанавливать тревогу и делать другие вещи:

Script (Как передать аргументы, Как запустить приложение из терминала):

am kill com.myapp.package
pm install -r $1
am start -n packageName/pkgName.ActivityName

Код приложения:

String command = "sh script.sh " + downloadPath + apkFile;
Process proc = Runtime.getRuntime().exec(new String[] {"su", "-c", command});

Ответ 5

используйте эти обновления встроенной библиотеки Play Core для достижения этой цели

dependencies {
implementation 'com.google.android.play:core:1.5.0'
...}