これは、数分(3分など)後にユーザーの非アクティブを処理する完全なソリューションです。これにより、タイムアウト時にアプリがバックグラウンドにあるときにアクティビティがフォアグラウンドにジャンプするなどの一般的な問題が解決されます。
まず、他のすべてのアクティビティが拡張できるBaseActivityを作成します。
これはBaseActivityコードです。
package com.example.timeout;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import javax.annotation.Nullable;
public class BaseActivity extends AppCompatActivity implements LogoutListener {
    private Boolean isUserTimedOut = false;
    private static Dialog mDialog;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((TimeOutApp) getApplication()).registerSessionListener(this);
        ((TimeOutApp) getApplication()).startUserSession();
    }
    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
    }
    @Override
    protected void onResume() {
        super.onResume();
        if (isUserTimedOut) {
            //show TimerOut dialog
            showTimedOutWindow("Time Out!", this);
        } else {
            ((TimeOutApp) getApplication()).onUserInteracted();
        }
    }
    @Override
    public void onSessionLogout() {
        isUserTimedOut = true;
    }
    public void showTimedOutWindow(String message, Context context) {
        if (mDialog != null) {
            mDialog.dismiss();
        }
        mDialog = new Dialog(context);
        mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        mDialog.setContentView(R.layout.dialog_window);
        mDialog.setCancelable(false);
        mDialog.setCanceledOnTouchOutside(false);
        TextView mOkButton = (TextView) mDialog.findViewById(R.id.text_ok);
        TextView text_msg = (TextView) mDialog.findViewById(R.id.text_msg);
        if (message != null && (!TextUtils.isEmpty(message)) && (!message.equalsIgnoreCase("null"))) {
            text_msg.setText(message);
        }
        mOkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mDialog != null){
                    mDialog.dismiss();
                    Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(intent);
                    finish();
                }
            }
        });
        if(!((Activity) context).isFinishing())
        {
            //show dialog
            mDialog.show();
        }
    }
}
次に、「ログアウトリスナー」のインターフェースを作成します。
package com.example.timeout;
public interface LogoutListener {
    void onSessionLogout();
}
最後に、「アプリケーション」を拡張するJavaクラスを作成します
package com.example.timeout;
import android.app.Application;
import java.util.Timer;
import java.util.TimerTask;
public class TimeOutApp extends Application {
    private LogoutListener listener;
    private Timer timer;
    private static final long INACTIVE_TIMEOUT = 180000; // 3 min
    public void startUserSession () {
        cancelTimer ();
        timer = new Timer ();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                listener.onSessionLogout ();
            }
        }, INACTIVE_TIMEOUT);
    }
    private void cancelTimer () {
        if (timer !=null) timer.cancel();
    }
    public void registerSessionListener(LogoutListener listener){
        this.listener = listener;
    }
    public void onUserInteracted () {
        startUserSession();
    }
}
注:マニフェストファイル内のアプリケーションタグに「TimeOutApp」クラスを追加することを忘れないでください
<application
        android:name=".TimeOutApp">
        </application>