마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

타임피커로 설정한 시간에 이벤트가 발생하게 하려면 어떻게 해야하나요?

0 추천

xml의 주요형식은

두개의 타임피커와 하나의 버튼으로 구성되어있고 버튼을 클릭하면 두개의 타임피커 시간정보를 전달하여 설정한 시간이 되면 오디오모드를 첫번째 타임피커에서는 무음모드로 전환하게하고, 두번째 타임피커는 다시 원래의 상태로 되돌리는 오디오세팅을 만들려고 하고있습니다.

 

btn_save.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(getApplicationContext(), "클릭 되었습니다.", Toast.LENGTH_SHORT).show();
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            hour = tp_start_time.getHour();
            minute = tp_start_time.getMinute();
            hour = tp_end_time.getHour();
            minute = tp_end_time.getMinute();
            if(getTime == hour + ":" + minute) {               mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
            }
        } else {
            hour = tp_start_time.getCurrentHour();
            minute = tp_start_time.getCurrentMinute();
            hour = tp_end_time.getCurrentHour();
            minute = tp_end_time.getCurrentMinute();
        }
    }
});

 

if문으로 먼저 작성해봤는데 현재시간과 설정한 시간이 다르면 실행이 되지않습니다. 특정시간에 이벤트 발생하게 하는 방법을 알려주실 수 있을까요!!

kcoder (330 포인트) 님이 2021년 12월 9일 질문

1개의 답변

+1 추천
 
채택된 답변

버튼 클릭을 할 때 TimePicker에서 설정한 시간에 맞춰서 작업이 실행되도록 하시려는 거죠? 이걸 scheduliing이라고 하는데, 버튼 클릭을 할 때 바로 작업을 실행하는 것이 아니라 사용자가 입력한 시간을 가지고 작업을 돌릴 수 있도록 설정해야 합니다.

안드로이드에서는 API레벨에 따라 권장하는 방법이 바뀌어 왔는데요, 최근에 권장하는 방법은 WorkManager입니다. 
https://developer.android.com/topic/libraries/architecture/workmanager(한글버전도 있을 겁니다.)

아니면 AlarmManager를 이용해도 될 겁니다. scheduling을 하는 코드는 너무 많이 나와 있어서 구글로 간단히 검색하면 엄청 많은 결과가 나올 겁니다. 위에서 말씀드린 링크에도 예제가 있고 구글의 Github page (https://github.com/android)에도 예제를 찾으실 수 있을 겁니다. 일단 개발자 문서도 좀 참조하시고 샘플들도 확인하셔서 처리해 보시기 바랍니다.  기본적으로 scheduling이 어떻게 돌아가는지 이해를 하지 않으시면 추후에 문제가 있거나 할 때 해결이 힘들어 지니 기본 문서는 확인하시고 진행하시기 바랍니다.

int startHour, startMinute, endHour, endMinute;

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            startHour = tp_start_time.getHour();
            startMinute = tp_start_time.getMinute();
            endHour = tp_end_time.getHour();
            endMinute = tp_end_time.getMinute();
 } else {
            startHour = tp_start_time.getCurrentHour();
            startMinute = tp_start_time.getCurrentMinute();
            endHour = tp_end_time.getCurrentHour();
            endMinute = tp_end_time.getCurrentMinute();
 }


Calendar startCalendar = getCalendar(startHour, startMinute);
Calendar endCalendar = getCalendar(endHour, endMinute);

scheduleMuteWork(startCalendar.getTimesInMills() - System.currentTimeMillis())
scheduleUnmuteWork(endCalendar.getTimesInMills() - System.currentTimeMillis())

private static Calendar getCalendar(int hour, int minute) {
     Calendar calendar = Calendar.getInstance();
     calendar.set(Calendar.HOUR_OF_DAY, hour);
     calendar.set(Calendar.MINUTE, minute);
     calendar.set(Calendar.SECOND, 0);
     return calendar;
}

 

 참고로 WorkManager로 Scheduling을 하는 샘플코드인데 제가 요즘은 코틀린만 사용하기 때문에 WorkManager 관련코드는 코틀린으로 작성하였습니다. 제 코드가 급하게 작성한 코드라 좋은 코드라고 하긴 그렇고 이런 식으로 한다만 참고하시고 코드는 공부를 하셔서 님이 직접 작성하시면 좋을 것 같습니다.

class MuteWorker(
    appContext: Context,
    workerParams: WorkerParameters
) : Worker(appContext, workerParams) {

    override fun doWork(): Result {
        // 무음으로 만드는 코드
        return Result.success()
    }
}

class UnmuteWorker(
    appContext: Context,
    workerParams: WorkerParameters
) : Worker(appContext, workerParams) {

    override fun doWork(): Result {
        //원래대로 돌리는 코드
        return Result.success()
    }
}

 

private fun scheduleMuteWork(initialDelayInMills: Long) {
    WorkManager.getInstance(this).enqueue(muteWorkRequest(initialDelayInMills))
}


private fun muteWorkRequest(initialDelayInMills: Long): WorkRequest {
    return OneTimeWorkRequestBuilder<MuteWorker>()
            .setInitialDelay(initialDelayInMills, TimeUnit.MILLISECONDS)
            .addTag("MuteWork")
            .build()
}


private fun scheduleUnmuteWork(initialDelayInMills: Long) {
    WorkManager.getInstance(this).enqueue(unmuteWorkRequest(initialDelayInMills))
}

private fun unmuteWorkRequest(initialDelayInMills: Long): WorkRequest {
    return OneTimeWorkRequestBuilder<UnmuteWorker>()
            .setInitialDelay(initialDelayInMills, TimeUnit.MILLISECONDS)
            .addTag("UnmuteWork")
            .build()
}

 

spark (224,800 포인트) 님이 2021년 12월 9일 답변
kcoder님이 2021년 12월 11일 채택됨
btn_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "클릭 되었습니다.", Toast.LENGTH_SHORT).show();

                defaultState = mAudioManager.getRingerMode();

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    starthour = tp_start_time.getHour();
                    startminute = tp_start_time.getMinute();
                    endhour = tp_end_time.getHour();
                    endminute = tp_end_time.getMinute();
                } else {
                    starthour = tp_start_time.getCurrentHour();
                    startminute = tp_start_time.getCurrentMinute();
                    endhour = tp_end_time.getCurrentHour();
                    endminute = tp_end_time.getCurrentMinute();
                }
                SilenceWorker
            }
        });
    }

    Calendar startCalendar = getCalendar(starthour, startminute);
    Calendar endCalendar = getCalendar(endhour, endminute);

    public class SilenceWorker extends Worker {
        public SilenceWorker(@NonNull Context context, @NonNull WorkerParameters params) {
            super(context, params);
        }

        @Override
        public Result doWork() {
            Calendar currentCalendar = getCalendar(Calendar.HOUR_OF_DAY, Calendar.MINUTE);
            if (currentCalendar == startCalendar) {
                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
                return Result.success();
            }
            return Result.retry();
        }
    }

    public class UnSilenceWorker extends Worker {
        public UnSilenceWorker(@NonNull Context context, @NonNull WorkerParameters params) {
            super(context, params);
        }

        @Override
        public Result doWork() {
            Calendar currentCalendar = getCalendar(Calendar.HOUR_OF_DAY, Calendar.MINUTE);
            if (currentCalendar == endCalendar) {
                mAudioManager.setRingerMode(defaultState);
                return Result.success();
            }
            return Result.retry();
        }
    }

    private static Calendar getCalendar(int hour, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, 0);
        return calendar;
    }
}

함수는 만들었는데 이걸 어떻게 onClick 함수에 적용하는지 모르겠어요 ㅜㅜ
...