반응형
Android의 날짜 및 시간 변경 리스너?
내 응용 프로그램에는 경보 서비스가 있으며 사용자가 날짜 또는 시간을 경과 시간으로 변경하면 알 수 있습니다. 예상 한 시간에 알람이 울리지 않습니다.
따라서 모든 알람을 다시 재설정해야 할 수도 있습니다. Android에 날짜 및 시간 변경 리스너가 있습니까?
인 텐트 필터 만들기 :
static {
s_intentFilter = new IntentFilter();
s_intentFilter.addAction(Intent.ACTION_TIME_TICK);
s_intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
s_intentFilter.addAction(Intent.ACTION_TIME_CHANGED);
}
및 방송 수신기 :
private final BroadcastReceiver m_timeChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_TIME_CHANGED) ||
action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
doWorkSon();
}
}
};
수신자 등록 :
public void onCreate() {
super.onCreate();
registerReceiver(m_timeChangedReceiver, s_intentFilter);
}
편집하다:
등록 취소 :
public void onDestroy() {
super.onDestroy();
unregisterReceiver(m_timeChangedReceiver);
}
받아 들여진 답변 외에
앱이 실행되지 않는 동안 시간 변경을 듣고 싶다면 매니페스트에 등록합니다.
<receiver android:name="com.your.pacakge.TimeChangeBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
</intent-filter>
</receiver>
이렇게하는 경우 registerReceiver
및로 코드에 수신자를 명시 적으로 등록하지 마십시오 unregisterReceiver
.
다시 말하지만 이것은 허용되는 답변에 추가 된 것입니다.
날짜 변경을 감지하려면 다음 작업에 등록해야합니다.
- Intent.ACTION_TIME_CHANGED- "시간이 설정되었습니다."
- Intent.ACTION_DATE_CHANGED- "날짜가 변경되었습니다."
- Intent.ACTION_TIMEZONE_CHANGED- "시간대가 변경되었습니다."
여기에 내가 작성한 한 가지 해결책이 있으므로 클래스를 확장하고 Activity / Fragment에 등록 및 등록 취소하기 만하면됩니다.
abstract class DateChangedBroadcastReceiver : BroadcastReceiver() {
private var curDate = LocalDate.now()
/**called when the receiver detected the date has changed. You should still check it yourself, because you might already be synced with the new date*/
abstract fun onDateChanged(previousDate: LocalDate, newDate: LocalDate)
@Suppress("MemberVisibilityCanBePrivate")
fun register(context: Context, date: LocalDate) {
curDate = date
val filter = IntentFilter()
filter.addAction(Intent.ACTION_TIME_CHANGED)
filter.addAction(Intent.ACTION_DATE_CHANGED)
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED)
context.registerReceiver(this, filter)
val newDate = LocalDate.now()
if (newDate != curDate) {
curDate = newDate
onDateChanged(date, newDate)
}
}
/**a convenient way to auto-unregister when activity/fragment has stopped. This should be called on the onResume method of the fragment/activity*/
fun registerOnResume(activity: AppCompatActivity, date: LocalDate, fragment: androidx.fragment.app.Fragment? = null) {
register(activity, date)
val lifecycle = fragment?.lifecycle ?: activity.lifecycle
lifecycle.addObserver(object : LifecycleObserver {
@Suppress("unused")
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun onPause() {
// Log.d("AppLog", "onPause, so unregistering")
lifecycle.removeObserver(this)
activity.unregisterReceiver(this@DateChangedBroadcastReceiver)
}
})
}
override fun onReceive(context: Context, intent: Intent) {
val newDate = LocalDate.now()
// Log.d("AppLog", "got intent:" + intent.action + " curDate:" + curDate + " newDate:" + newDate)
if (newDate != curDate) {
// Log.d("AppLog", "cur date is different, so posting event")
val previousDate = curDate
curDate = newDate
onDateChanged(previousDate, newDate)
}
}
}
LocalDate를 사용할 수없는 경우 (현재 약 21 %의 기기에서 사용되는 비교적 새로운 API : 26을 사용하기 때문에) 대신 다음을 사용할 수 있습니다.
abstract class DateChangedBroadcastReceiver : BroadcastReceiver() {
private var curDate = Calendar.getInstance()
/**called when the receiver detected the date has changed. You should still check it yourself, because you might already be synced with the new date*/
abstract fun onDateChanged(previousDate: Calendar, newDate: Calendar)
companion object {
fun toString(cal: Calendar): String {
return "${cal.get(Calendar.YEAR)}-${cal.get(Calendar.MONTH)}-${cal.get(Calendar.DAY_OF_MONTH)}"
}
fun resetDate(date: Calendar) {
date.set(Calendar.HOUR_OF_DAY, 0)
date.set(Calendar.MINUTE, 0)
date.set(Calendar.SECOND, 0)
date.set(Calendar.MILLISECOND, 0)
}
fun areOfSameDate(date: Calendar, otherDate: Calendar) =
date.get(Calendar.DAY_OF_YEAR) == otherDate.get(Calendar.DAY_OF_YEAR) &&
date.get(Calendar.YEAR) == otherDate.get(Calendar.YEAR)
}
@Suppress("MemberVisibilityCanBePrivate")
fun register(context: Context, date: Calendar) {
curDate = date.clone() as Calendar
resetDate(curDate)
val filter = IntentFilter()
filter.addAction(Intent.ACTION_TIME_CHANGED)
filter.addAction(Intent.ACTION_DATE_CHANGED)
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED)
context.registerReceiver(this, filter)
val newDate = Calendar.getInstance()
resetDate(newDate)
if (!areOfSameDate(newDate, curDate)) {
val previousDate = curDate.clone() as Calendar
curDate = newDate
onDateChanged(previousDate, curDate)
}
}
/**a convenient way to auto-unregister when activity/fragment has stopped. This should be called on the onResume method of the fragment/activity*/
fun registerOnResume(activity: AppCompatActivity, date: Calendar, fragment: Fragment? = null) {
register(activity as Context, date)
val lifecycle = fragment?.lifecycle ?: activity.lifecycle
lifecycle.addObserver(object : LifecycleObserver {
@Suppress("unused")
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun onPause() {
// Log.d("AppLog", "onPause, so unregistering")
lifecycle.removeObserver(this)
activity.unregisterReceiver(this@DateChangedBroadcastReceiver)
}
})
}
override fun onReceive(context: Context, intent: Intent) {
val newDate = Calendar.getInstance()
resetDate(newDate)
// Log.d("AppLog", "got intent:${intent.action} curDate:${toString(curDate)} newDate:${toString(newDate)}")
if (!areOfSameDate(newDate, curDate)) {
// Log.d("AppLog", "cur date is different, so posting event")
val previousDate = curDate.clone() as Calendar
curDate = newDate
onDateChanged(previousDate, newDate)
}
}
}
사용 예 :
class MainActivity : AppCompatActivity() {
var curDate = Calendar.getInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onResume() {
super.onResume()
object : DateChangedBroadcastReceiver() {
override fun onDateChanged(previousDate: Calendar, newDate: Calendar) {
Log.d("AppLog", "MainActivity: ${DateChangedBroadcastReceiver.toString(previousDate)} -> ${DateChangedBroadcastReceiver.toString(newDate)}")
curDate = newDate.clone() as Calendar
//TODO handle date change
}
}.registerOnResume(this, curDate)
}
}
참고 URL : https://stackoverflow.com/questions/5481386/date-and-time-change-listener-in-android
반응형
'Development Tip' 카테고리의 다른 글
사전을 변환하는 방법 (0) | 2020.11.27 |
---|---|
vim은 명확하게 존재하는 간단한 문구를 찾아서 대체하지 않습니다. (0) | 2020.11.27 |
SQL Server : Null VS 빈 문자열 (0) | 2020.11.27 |
벡터에서 가장 작은 값의 인덱스를 반환합니까? (0) | 2020.11.27 |
2 개의 JVM이 서로 통신하도록하는 방법 (0) | 2020.11.27 |