개요
이 글에서는 안드로이드 앱에서 사용자가 5초 동안 아무런 조작을 하지 않는 비활성 상태를 감지하는 방법을 단계별로 살펴봅니다. 핵심 아이디어는 Activity에 내장된 onUserInteraction() 콜백과 Handler 타이머를 조합하는 것입니다.
동작 원리
onUserInteraction()은 사용자가 화면을 터치하거나 버튼을 누르는 등 어떤 형태로든 앱과 상호작용할 때마다 자동으로 호출되는 콜백입니다. 이 메서드 안에서 타이머를 계속 초기화하다가, 설정한 시간(5초) 동안 한 번도 초기화되지 않으면 사용자가 비활성 상태라고 판단하는 구조입니다.
1단계 — 새 프로젝트 만들기
Android Studio에서 File → New Project를 선택한 후, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.
2단계 — 레이아웃 작성 (res/layout/activity_main.xml)
레이아웃 파일에는 간단한 TextView 하나만 배치하면 충분합니다.
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
3단계 — MainActivity.java 작성
package com.app.sample;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Handler handler;
private Runnable r;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler(Looper.getMainLooper());
r = new Runnable() {
@Override
public void run() {
// 5초 동안 사용자 상호작용이 없으면 실행됩니다.
Toast.makeText(MainActivity.this,
"사용자가 5초 동안 비활성 상태입니다",
Toast.LENGTH_SHORT).show();
}
};
startHandler();
}
@Override
public void onUserInteraction() {
super.onUserInteraction();
stopHandler(); // 기존 타이머 취소
startHandler(); // 타이머 재시작
}
public void stopHandler() {
handler.removeCallbacks(r);
}
public void startHandler() {
handler.postDelayed(r, 5 * 1000); // 5000ms = 5초
}
}
코드 설명
- Handler / Runnable: 비활성 여부를 판정하는 타이머 역할을 하며, Runnable 안의 코드는 지정한 지연 시간이 지난 뒤 실행됩니다.
- startHandler():
postDelayed()로 5초(5 × 1000ms) 후에 Runnable이 실행되도록 예약합니다. - stopHandler():
removeCallbacks()로 예약된 작업을 취소합니다. - onUserInteraction(): 사용자가 조작할 때마다 기존 타이머를 취소하고 새로 시작하여, 5초가 온전히 지났을 때만 알림이 뜨도록 합니다.
참고: API 30부터 new Handler() 기본 생성자는 deprecated되었으므로, 위 코드처럼 new Handler(Looper.getMainLooper())를 사용하는 것이 좋습니다.
4단계 — 매니페스트 설정 (AndroidManifest.xml)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="https://schemas.android.com/apk/res/android" package="com.app.sample"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
앱 실행 및 결과 확인
실제 안드로이드 기기를 컴퓨터에 연결했다고 가정하고 진행합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 버튼을 클릭하고, 목록에서 본인의 모바일 기기를 선택하면 기본 화면이 표시됩니다.
앱을 실행한 뒤 5초 동안 아무것도 건드리지 않으면 '사용자가 5초 동안 비활성 상태입니다'라는 토스트 메시지가 나타납니다. 반대로 화면을 터치하는 순간 타이머가 초기화되어 다시 5초를 세기 시작합니다.
