Android系统日期更改事件

时间:2014-05-29 07:50:49

标签: android broadcastreceiver android-date

我知道这个问题已被多次询问,但我无法找到正确的方向。我已注册BroadcastReceiver,当Android System Date自动更改但未触发时,我想触发该IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_TIME_CHANGED); registerReceiver(new DateTimeChangeReceiver (), intentFilter); 。我使用了以下方法:

1

<receiver android:name=".DateTimeChangeReceiver ">
<intent_filter>
    <action android:name="android.intent.action.DATE_CHANGED"/>
</intent_filter>
</receiver>

2→的AndroidManifest.xml

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();
    }

}

DateTimeChangeReceiver

{{1}}

在这两种情况下,都没有触发接收器。它仅在设置手动时间时显示通知。任何人都可以指出我缺少的东西吗?

提前致谢。

2 个答案:

答案 0 :(得分:2)

这些活动有广播。 ACTION_TIME_CHANGED和ACTION_DATE_CHANGED 行动文档位于http://developer.android.com/reference/android/content/Intent.html#ACTION_DATE_CHANGED

http://code.google.com/p/android/issues/detail?id=2880

提供的潜在错误和一些实施细节

答案 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>