我知道这个问题已被多次询问,但我无法找到正确的方向。我已注册BroadcastReceiver
,当Android System Date
自动更改但未触发时,我想触发该IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_TIME_CHANGED);
registerReceiver(new DateTimeChangeReceiver (), intentFilter);
。我使用了以下方法:
<receiver android:name=".DateTimeChangeReceiver ">
<intent_filter>
<action android:name="android.intent.action.DATE_CHANGED"/>
</intent_filter>
</receiver>
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class DateTimeChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "Date changed", Toast.LENGTH_SHORT).show();
}
}
{{1}}
在这两种情况下,都没有触发接收器。它仅在设置手动时间时显示通知。任何人都可以指出我缺少的东西吗?
提前致谢。
答案 0 :(得分:2)
这些活动有广播。 ACTION_TIME_CHANGED和ACTION_DATE_CHANGED 行动文档位于http://developer.android.com/reference/android/content/Intent.html#ACTION_DATE_CHANGED
提供的潜在错误和一些实施细节答案 1 :(得分:1)
当日期发生变化时,我已经很好地检测并更新了UI。它基于broadcastReceiver,它应该在onStart方法上注册,并在onStop方法上取消注册(取消注册在我的代码中自动完成)。
<强>的build.gradle 强>
implementation 'com.jakewharton.threetenabp:threetenabp:1.0.5'
<强> LocalDateEx.kt 强>
object LocalDateEx {
/**an alternative of LocalDate.now(), as it requires initialization using AndroidThreeTen.init(context), which takes a bit time (loads a file)*/
@JvmStatic
fun getNow(): LocalDate = Calendar.getInstance().toLocalDate()
}
fun Calendar.toLocalDate(): LocalDate = LocalDate.of(get(Calendar.YEAR), get(Calendar.MONTH) + 1, get(Calendar.DAY_OF_MONTH))
<强> DateChangedBroadcastReceiver.kt 强>
abstract class DateChangedBroadcastReceiver : BroadcastReceiver() {
private var curDate = LocalDateEx.getNow()
/**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 = LocalDateEx.getNow()
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 onStart method of the fragment/activity*/
fun registerOnStart(activity: AppCompatActivity, date: LocalDate, fragment: Fragment? = null) {
register(activity, date)
val lifecycle = fragment?.lifecycle ?: activity.lifecycle
lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onStop() {
Log.d("AppLog", "onStop, so unregistering")
lifecycle.removeObserver(this)
activity.unregisterReceiver(this@DateChangedBroadcastReceiver)
}
})
}
override fun onReceive(context: Context, intent: Intent) {
val newDate = LocalDateEx.getNow()
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)
}
}
}
<强> MainActivity.kt 强>
class MainActivity : AppCompatActivity() {
var today = LocalDateEx.getNow()
val receiver = object : DateChangedBroadcastReceiver() {
override fun onDateChanged(previousDate: LocalDate, newDate: LocalDate) {
Log.d("AppLog", "onDateChangedEvent:" + newDate + " previousDate:" + previousDate)
if (newDate != today) {
today = newDate
textView.text = "date updated:" + today
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("AppLog", "onCreate")
setContentView(R.layout.activity_main)
textView.text = today.toString()
}
override fun onStart() {
super.onStart()
receiver.registerOnStart(this, today)
}
}
<强> activity_main.xml中强>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
<TextView
android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>