MainActivity의 버튼을 클릭하면 TimePickerDialog가 나오고 설정한 시간으로 알람을 설정하도록 해보겠습니다.
그 전에 TimePickerDialog 사용하는 방법입니다.
https://1d1cblog.tistory.com/40
먼저 activity_main.xml 파일입니다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/alarmButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginStart="165dp"
android:layout_marginLeft="165dp"
android:layout_marginTop="344dp"
android:text="알람설정" />
</RelativeLayout>
간단하게 화면의 한 가운데 버튼을 만들어줬습니다.
다음으로 MainActivity.java 파일입니다.
public class MainActivity extends AppCompatActivity {
Button alarmButton;
int alarmHour, alarmMinute;
Calendar alarmCalendar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
alarmButton = (Button) findViewById(R.id.alarmButton);
alarmButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TimePickerDialog timePickerDialog
= new TimePickerDialog(getApplicationContext()
, new TimePickerDialog.OnTimeSetListener() {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
alarmHour = hourOfDay;
alarmMinute = minute;
setAlarm();
}
},alarmHour, alarmMinute, false);
}
});
}
void setAlarm() {
alarmCalendar = Calendar.getInstance();
alarmCalendar.setTimeInMillis(System.currentTimeMillis());
alarmCalendar.set(Calendar.HOUR_OF_DAY, alarmHour);
alarmCalendar.set(Calendar.MINUTE, alarmMinute);
alarmCalendar.set(Calendar.SECOND, 0);
// TimePickerDialog 에서 설정한 시간을 알람 시간으로 설정
if (alarmCalendar.before(Calendar.getInstance())) alarmCalendar.add(Calendar.DATE, 1);
// 알람 시간이 현재시간보다 빠를 때 하루 뒤로 맞춤
Intent alarmIntent = new Intent(getApplicationContext(), AlarmReceiver.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmIntent.setAction(AlarmReceiver.ACTION_RESTART_SERVICE);
PendingIntent alarmCallPendingIntent
= PendingIntent.getBroadcast
(MainActivity.this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
alarmManager.setExactAndAllowWhileIdle
(AlarmManager.RTC_WAKEUP, alarmCalendar.getTimeInMillis(), alarmCallPendingIntent);
else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
alarmManager.setExact
(AlarmManager.RTC_WAKEUP, alarmCalendar.getTimeInMillis(), alarmCallPendingIntent);
} // 알람 설정
}
SDK의 버전이 마쉬멜로(23) 이상이면 setExactAndAllowWhileIdle 함수를 사용해야 Doze 모드에서 제대로 실행될 수 있습니다.
https://developer.android.com/training/monitoring-device-state/doze-standby?hl=ko#restrictions
이제 알람 서비스를 수신할 AlarmReceiver.java 파일과 서비스를 해 줄 AlarmService.java 파일입니다. AlarmReceiver.java, AlarmService.java를 사용하기 위해서는 AndroidManifest.xml 파일에 아래 코드를 추가해줘야 합니다.
<service
android:name=".AlarmService"
android:enabled="true"
android:exported="true" />
<receiver android:name=".AlarmReceiver" />
AlarmReceiver.java 파일입니다.
public class AlarmReceiver extends BroadcastReceiver {
public static final String ACTION_RESTART_SERVICE = "Restart";
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(ACTION_RESTART_SERVICE)) {
Intent in = new Intent(context, AlarmService.class);
context.startService(in);
}
}
}
AlarmService.java 파일입니다.
public class AlarmService extends Service {
String TAG = "TAG+Service";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "AlarmService");
Intent alarmIntent = new Intent(getApplicationContext(), AlarmActivity.class);
startActivity(alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
return super.onStartCommand(intent, flags, startId);
}
}
마지막으로 설정한 알람시간이 되었을때 실행할 AlarmActivity.java입니다.
public class AlarmActivity extends AppCompatActivity {
Calendar calendar;
SwipeButton swipeButton;
TextView timeText;
MediaPlayer mediaPlayer;
boolean flag = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
calendar = Calendar.getInstance();
swipeButton = (SwipeButton) findViewById(R.id.swipe_btn);
timeText = (TextView) findViewById(R.id.time);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
// 잠금 화면 위로 activity 띄워줌
mediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.beep); // 소리를 재생할 MediaPlayer
mediaPlayer.setLooping(true); // 무한반복
mediaPlayer.start();
new Thread(new Runnable() {
@Override
public void run() {
while (flag == true) {
try {
calendar = Calendar.getInstance();
if (calendar.get(Calendar.HOUR_OF_DAY) > 0 && calendar.get(Calendar.HOUR_OF_DAY) < 12) {
timeText.setText("AM " + calendar.get(Calendar.HOUR_OF_DAY) + "시 " + calendar.get(Calendar.MINUTE) + "분 " + calendar.get(Calendar.SECOND) + "초");
} else if (calendar.get(Calendar.HOUR_OF_DAY) == 12) {
timeText.setText("PM " + calendar.get(Calendar.HOUR_OF_DAY) + "시 " + calendar.get(Calendar.MINUTE) + "분 " + calendar.get(Calendar.SECOND) + "초");
} else if (calendar.get(Calendar.HOUR_OF_DAY) > 12 && calendar.get(Calendar.HOUR_OF_DAY) < 24) {
timeText.setText("PM " + (calendar.get(Calendar.HOUR_OF_DAY) - 12) + "시 " + calendar.get(Calendar.MINUTE) + "분 " + calendar.get(Calendar.SECOND) + "초");
} else if (calendar.get(Calendar.HOUR_OF_DAY) == 0) {
timeText.setText("AM 0시 " + calendar.get(Calendar.MINUTE) + "분 " + calendar.get(Calendar.SECOND) + "초");
}
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
}
}).start(); // 실시간으로 시계 출력
swipeButton.setOnStateChangeListener(new OnStateChangeListener() {
@Override
public void onStateChange(boolean active) {
mediaPlayer.stop();
flag=false;
finish();
}
}); // Swipe Button 밀어서 해제
}
}
알람이 실행되면 지정한 노래가 실행되게 하였습니다. 실시간으로 화면 상단에 시계를 출력하며 하단에는 Swipe Button을 넣어 밀어서 해제하면 알람이 꺼지도록 만들었습니다.
15~18열의 getWindow()는 화면이 잠겨있거나 꺼져있어도 알람이 실행되면서 화면을 띄울 수 있게 해줍니다.
https://1d1cblog.tistory.com/43
https://1d1cblog.tistory.com/44
'Programming > Android' 카테고리의 다른 글
안드로이드 스튜디오 공공데이터포털 XML 파싱하기 (6) | 2020.03.07 |
---|---|
안드로이드 스튜디오 notification 소리 진동 설정 (0) | 2020.03.04 |
안드로이드 스튜디오 뒤로가기 버튼으로 홈으로 이동하기 (0) | 2019.12.04 |
안드로이드 스튜디오 MediaPlayer 사용하기 (0) | 2019.11.28 |
안드로이드 스튜디오 Swipe Button 사용하기 (0) | 2019.11.28 |