Android-「戻る」ボタンをオーバーライドして、アクティビティが完了()しないようにする方法は?


199

現在、アクティビティが表示されているときに、通知バーにも表示されるアクティビティがあります。

これは、ユーザーがホームを押してアクティビティがバックグラウンドにプッシュされると、通知を介してアクティビティに戻ることができるようにするためです。

この問題は、ユーザーが戻るボタンを押すと発生しますが、アクティビティは破棄されますが、ユーザーが押し戻して通知を介してアクティビティにアクセスできるようにしたいため、通知は残ります。しかし、ユーザーがこれを試行すると、古いアクティビティを取り戻すのではなく、新しいアクティビティを開始しようとしているとNullポインタが表示されます。

したがって、基本的には、[戻る]ボタンを[ホーム]ボタンとまったく同じように動作させたいので、これまでに試した方法を次に示します。


        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event)  {
            if (Integer.parseInt(android.os.Build.VERSION.SDK) < 5
                    && keyCode == KeyEvent.KEYCODE_BACK
                    && event.getRepeatCount() == 0) {
                Log.d("CDA", "onKeyDown Called");
                onBackPressed();
            }

            return super.onKeyDown(keyCode, event);
        }

        public void onBackPressed() {
            Log.d("CDA", "onBackPressed Called");
            Intent setIntent = new Intent(Intent.ACTION_MAIN);
            setIntent.addCategory(Intent.CATEGORY_HOME);
            setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(setIntent); 

            return;
        }   

しかし、上記のコードはまだ私のアクティビティを破棄できるようですが、戻るボタンが押されたときにアクティビティが破棄されないようにするにはどうすればよいですか?


同様の質問があります:stackoverflow.com/questions/2459848/...は
aleung


また、私は5>あなたが(Integer.parseInt(android.os.Build.VERSION.SDK)であれば`にあなたのコードを変更する必要が考える, the <`になるはず>
SudoPlz

1
これを解決しても、システムがアプリを強制終了する可能性を処理する必要がありますよね?つまり、ヌルケースはまだ可能ですか?または、システムが何らかの理由でアプリを強制終了した場合、通知も削除されますか?通知の目的はアプリが存在しない場合でも存在することなので、これは問題だと思います。
ToolmakerSteve 2016

ここでサンプルアプリケーションコードfreakyjolly.com/how-to-add-back-arrow-in-android-activityを
Code Spy

回答:


276

キーリスナーを削除するかtrue、使用しているときに戻りますKEY_BACK

バックキーをキャッチするには、次のコードが必要です(スーパーでを呼び出さないでくださいonBackPressed())。

また、サービスをバックグラウンドで実行することを計画している場合startForeground()は、確認して継続的な通知があることを確認してください。そうしないと、メモリを解放する必要がある場合、Androidによってサービスが強制終了されます。

@Override
public void onBackPressed() {
   Log.d("CDA", "onBackPressed Called");
   Intent setIntent = new Intent(Intent.ACTION_MAIN);
   setIntent.addCategory(Intent.CATEGORY_HOME);
   setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(setIntent);
}

70

コードを1行だけで実装する方が簡単でした。

@Override
public void onBackPressed() {
   moveTaskToBack(true);
}

これは受け入れられる答えになるはずです。これは、質問がまさに求めていることを行い、クリーンな組み込み機能を使用しています。
Shadoninja 2017

ありがとう:)その背後にあるコンセプトを詳しく説明できますか?
Farrukh Faizy

1
onBackPressed()イベントをオーバーライドするだけで、アクティビティが後ろに移動します。
Squirrelkiller 2017

1
このソリューションでは、ホーム画面からアプリを再起動しても、アクティビティが元に戻りません(タスクスタックに別のアクティビティがある場合)。
IgorGanapolsky 2017

12

私はあなたが望むのは戻るボタンをオーバーライドすることではなく(それは単に良い考えのように思えない-Android OSがその動作を定義し、なぜそれを変更するのか)ではなく、アクティビティライフサイクルを使用して設定/データをonSaveInstanceState(Bundle)イベント。

@Override
onSaveInstanceState(Bundle frozenState) {
    frozenState.putSerializable("object_key",
        someSerializableClassYouWantToPersist);
    // etc. until you have everything important stored in the bundle
}

次に使用します onCreate(Bundle)をして、永続化されたバンドルからすべてを取り出し、状態を再作成します。

@Override
onCreate(Bundle savedInstanceState) {
    if(savedInstanceState!=null){ //It could be null if starting the app.
        mCustomObject = savedInstanceState.getSerializable("object_key");
    }
    // etc. until you have reloaded everything you stored
}

上記の擬似コードを参考にして、正しい方向に向けてください。アクティビティライフサイクルを読むと、探しているものを達成するための最良の方法を判断するのに役立ちます。


こんにちはKiswa、これは本当です、私はデフォルトの動作を変更したくありません。onSavedInstanceStateを使用してみましたが、機能しませんでしたが、今はエラーを見つけたと思います。ありがとう
Donal Rafferty 2010年

5
実際に新しいアクティビティを開始せずに、標準のアクティビティスタックの動作をシミュレートしたい状況が少なくともいくつかありました。これらのケースでは、デフォルトのonBackPressed()動作をオーバーライドするのが適切だと思います。ただし、一般的には、私は同意します。上書きしないでください。
MattBriançon、

4
@マットに同意します。現在、NDKを使用するクロスプラットフォームゲームに取り組んでいます。そのため、すべてが1つのアクティビティである場合が最も簡単です。このため、戻るボタンのデフォルトの動作はアプリケーションをエスケープすることですが、これはほとんどのユーザーが期待していることではありません。そのため、ユーザーが実際に別のアクティビティに行って、特定の状況でのみアプリを終了したかのように、アクティビティの動作を変更するには、デフォルトの動作を上書きする必要がありました。
Leif Andersen

1
onSaveInstanceStateとデータの保存はまったく別の質問ではありませんか?
テッド

@Ted-onSaveInstanceStateに加えて、非UIアプリデータを永続化するコードも必要であると言っている場合は、同意します。フォアグラウンドを放棄するとすぐに、アプリは警告なしで終了する可能性があります。重要なものは常に保存する必要があります。一方、アプリを非表示にするために使用する手法に関係なく、アプリのライフサイクルメソッドが呼び出されると思いますが、この方法だけで保存ロジックを追加する必要はありません。アプリは、適切な場所に関係なく、そのコードを必要とします。
ToolmakerSteve 2016

11

単にこれを行う。

@Override
public void onBackPressed() {
    //super.onBackPressed();
}

//super.onBackPressed();をコメント化する トリックを行います


1
便利な観察ですが、これにより、[戻る]ボタンが壊れたかのように、何も実行されませんか?これは良いことではありません-ユーザーを混乱させ、煩わしくさせます。IMHOは、別の回答からロジックを追加して、問題の要求されたホームボタンのように機能させる必要があります。受け入れられた回答、それらが意図的にスーパーメソッドを呼び出さなかったと述べています。
ToolmakerSteve 2016

はい、あなたは完全に正しいです。戻るボタンをオーバーライドするだけで、ロジックを配置するまで何もしません。ボタンを2回押してアプリケーションを閉じるか、進行中の操作(進行ダイアログ)などを無効にしたいが、要件に完全に依存している可能性があります。
androCoder-BD

5

これを試して:

@Override
public void onBackPressed() {
    finish();
}

3

戻るボタン(電話の下部にある)とホームボタン(アクションバーの左側にあるボタン)の動作を処理する場合に備えて、プロジェクトで使用しているこのカスタムアクティビティが役立つ場合があります。 。

import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;

/**
 * Activity where the home action bar button behaves like back by default
 */
public class BackActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupHomeButton();
    }

    private void setupHomeButton() {
        final ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeButtonEnabled(true);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                onMenuHomePressed();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    protected void onMenuHomePressed() {
        onBackPressed();
    }
}

アクティビティでの使用例:

public class SomeActivity extends BackActivity {

    // ....

    @Override
    public void onBackPressed()
    {
        // Example of logic
        if ( yourConditionToOverride ) {
            // ... do your logic ...
        } else {
            super.onBackPressed();
        }
    }    
}

1
@Override
public void onBackPressed() {
// Put your code here.
}

//I had to go back to the dashboard. Hence,

@Override
public void onBackPressed() {
    Intent intent = new Intent(this,Dashboard.class);
    startActivity(intent);
}
Just write this above or below the onCreate Method(within the class)

0

コトリンでは:

val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
    // Handle the back button event
}

詳細については、これを確認できます。

Kotlinの[戻る]ボタンを上書きすることに関する特定の質問もあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.