Закройте приложение и удалите из последних приложений/

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

Что я хочу:

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

Некоторые ответы, которые я нашел:

use System.exit(0); //doesn't clear app from recents
OR
use android.os.Process.killProcess(android.os.Process.myPid()); //doesn't clear app from recents
OR
use finish() or this.finish() or Activity.finish();// doesn't clear app from recents

И одно общее предложение, которое я вижу в каждом ответе, который добавляет ниже код в манифест:

android:excludeFromRecents //I think this is wrong approach.

потому что после добавления этого, когда пользователь нажимает кнопку "домой" во время работы моего приложения, пользователь не может видеть мое приложение в последнем списке приложений.

И многие другие предложения по этому поводу, но ни один из них не выполняет обе задачи закрывать приложение и очищать приложение из списка последних приложений. Также, если вы заходите в Settings>Apps>yourApp>your Application, смотрите, что все еще он запрашивает "принудительный останов", означает, что приложение запущено!

Ответ 1

Я основал мое решение для гостей выше, а также комментарии gilsaints88 ниже (для совместимости с Android L):

Добавьте эту активность в файл AndroidManifest.xml:

<activity
    android:name="com.example.ExitActivity"
    android:theme="@android:style/Theme.NoDisplay"
    android:autoRemoveFromRecents="true"/>

Затем создайте класс ExitActivity.java:

public class ExitActivity extends Activity
{
    @Override protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        if(android.os.Build.VERSION.SDK_INT >= 21)
        {
            finishAndRemoveTask();
        }
        else
        {
            finish();
        }
    }

    public static void exitApplication(Context context)
    {
        Intent intent = new Intent(context, ExitActivity.class);

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);

        context.startActivity(intent);
    }
}

Затем, когда вы хотите принудительно закрыть приложение и удалить его из последнего списка, вызовите:

ExitActivity.exitApplication(context);

Это решение работает для меня, а не для объявления android: excludeFromRecents = "true", потому что я хочу, чтобы пользователь мог видеть приложение в списке повторов, пока не будет запущено приложение, которое будет запущено.

Ответ 2

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

Теперь, когда это с моей стороны, с моей дрянной идеей для этого. Суть его в том, чтобы заменить задачу, которую вы хотите выйти, с той, которую система исключит из последнего списка приложений.

  • Определите действие (я назову его Exiter), который сразу завершится.
    • Вызов finish() в onCreate(Bundle).
    • Из вопроса, похоже, что OP также захочет вызвать System.exit(int) тоже. Но для других людей, читающих этот ответ, вам обычно не нужно убивать процесс.
    • Используйте android:theme="@android:style/Theme.NoDisplay", чтобы это не вызвало кучу избыточных переходов.
  • Установите android:taskAffinity, чтобы Exiter выполнил задачу, которую вы хотите выполнить. Или нет: по умолчанию неуказанный taskAffinity делает так, чтобы все действия имели общий анонимный taskAffinity.
  • Когда вы хотите выйти, используйте startActivity(Intent) для запуска Exiter со следующими флагами:
    • Intent.FLAG_ACTIVITY_NEW_TASK - Хотя мы хотим начать работу в одной и той же задаче, для других флагов требуется этот флаг. К счастью, taskAffinity не позволит системе фактически начать новую задачу.
    • Intent.FLAG_ACTIVITY_CLEAR_TASK - Это завершает все действия над задачей. Вам не нужно будет вызывать finish() везде, только в Exiter.
    • Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS - Задача не будет отображаться в списке последних приложений. Поскольку это та же самая задача, что и выход, этот флаг удаляет задачу из списка.

https://gist.github.com/anonymous/9884978

Ответ 3

finishAndRemoveTask(); работал у меня, чтобы удалить приложение из панели задач. После закрытия приложения.

Ответ 4

Добавьте это в свою деятельность:

@Override
public void finish() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        super.finishAndRemoveTask();
    }
    else {
        super.finish();
    }
}

finishAndRemoveTask()

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

Ответ 5

Решение для Котлина.

ExitHelper.kt

fun Activity.finishAndRemoveTaskCompat() {
    if (android.os.Build.VERSION.SDK_INT >= 21) {
        finishAndRemoveTask()
    } else {
        val intent = Intent(this, ExitAndRemoveFromRecentAppsDummyActivity::class.java)

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
                Intent.FLAG_ACTIVITY_CLEAR_TASK or
                Intent.FLAG_ACTIVITY_NO_ANIMATION or
                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)

        startActivity(intent)
    }
}

class ExitAndRemoveFromRecentAppsDummyActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        finish()
    }
}

Mainfest.xml

    <activity
        android:name=".ExitAndRemoveFromRecentAppsDummyActivity"
        android:theme="@android:style/Theme.NoDisplay"
        />

Затем просто используйте его как метод usuall в своей деятельности:

override fun boo() {
    foo()
    finishAndRemoveTaskCompat()
}