MainActivity의 버튼을 클릭하면 TimePickerDialog가 나오고 설정한 시간으로 알람을 설정하도록 해보겠습니다.
그 전에 TimePickerDialog 사용하는 방법입니다.
https://1d1cblog.tistory.com/40
안드로이드 스튜디오 TimePickerDialog 사용하기
TimerPickerDialog를 자바 코드에서 사용하는 방법입니다. public class MainActivity extends AppCompatActivity { ImageButton alarmButton; int alarmHour=0, alarmMinute=0; @Override protected void onCreat..
1d1cblog.tistory.com
먼저 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
잠자기 및 앱 대기 모드에 맞게 최적화하기 | Android 개발자 | Android Developers
앱에서 Android 6.0의 절전 기능을 테스트하고 최적화합니다.
developer.android.com
이제 알람 서비스를 수신할 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
안드로이드 스튜디오 Swipe Button 사용하기
먼저 build.gradle 파일을 아래와 같이 수정합니다. minSdkVersion을 16으로 수정하고 dependencies에 아래처럼 코드를 추가해줍니다. apply plugin: 'com.android.application' android { compileSdkVersion 28 d..
1d1cblog.tistory.com
https://1d1cblog.tistory.com/44
안드로이드 스튜디오 MediaPlayer 사용하기
먼저 res폴더에 우클릭을 하여 Android Resource Directory를 생성해줍니다. 이름과 type을 raw로 설정해줍니다. raw 폴더 안에 원하는 음악 파일을 넣어준 다음 Java 코드를 작성해줍니다. setLooping 값을 tru..
1d1cblog.tistory.com