15

我正在尝试编写一个 BroadcastReceiver 来侦听诸如插入、编辑、删除本机 android 日历(ICS 及更高版本)之类的事件。因此,每当这些事件之一发生时,应用程序至少应该能够知道这些事件发生了。

任何人都有想法,如何做到这一点或任何参考链接。

我已经编写了自己的广播接收器类,它从广播接收器扩展而来。无法弄清楚清单中的值,例如,目前我有这个不起作用:

 <receiver
    android:name=".NativeEventChangeReceiver">
     <intent-filter>
        <action android:name="android.intent.action.EDIT"/>
        <action android:name="android.intent.action.INSERT"/>
        <action android:name="android.intent.action.DELETE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="vnd.android.cursor.dir/event"/>
     </intent-filter>
  </receiver>

干杯,

编辑1:有人知道数据标签的正确字符串吗?我认​​为这在意图过滤器中也是必需的。

编辑 2:关于使用 ContentObserver 的任何提示?

4

2 回答 2

27

经过大量阅读终于找到了解决方案,这可能有助于其他人找到类似的解决方案。

在 Manifest 中,您需要编写这些行才能捕获更改:

<receiver
   android:name=".NativeEventChangeReceiver">
        <intent-filter>
            <action android:name="android.intent.action.PROVIDER_CHANGED"/>
            <data android:scheme="content"/>
            <data android:host="com.android.calendar"/>
        </intent-filter>
</receiver>

干杯,

于 2013-03-06T01:25:44.947 回答
4

除了接受的答案:

当对日历数据进行任何更改时,将发送此代码广播的意图:

<receiver
   android:name=".NativeEventChangeReceiver">
        <intent-filter>
            <action android:name="android.intent.action.PROVIDER_CHANGED"/>
            <data android:scheme="content"/>
            <data android:host="com.android.calendar"/>
        </intent-filter>
</receiver>

不幸的是,它也会在设备启动时广播,或者在创建提供程序并且没有额外的内容可以读取时广播。

要使您的应用程序仅处理事件实例的插入/删除:

跟踪事件实例的总数(正如 SagiLow 指出的那样,这仅适用于添加/删除,不考虑更新)。如果更改,请根据用户日历重新验证您的数据:

public class CalendarChangedReceiver extends BroadcastReceiver
{
    private static final String TAG = "CalendarChangedReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        //Check number of instances
        final SharedPreferences prefs = context.getSharedPreferences(Enums.Config.USER_CONSTANTS, Context.MODE_PRIVATE);`enter code here`
        long lastTimeValidated =  prefs.getLong(AppData.LONG_LAST_TIME_VALIDATED, 0);


      int numRowsLastTimeValidated =  prefs.getInt(AppData.INT_NUM_ROWS_LAST_TIME_VALIDATED, 0);
        int numberOfInstances = getNumberOfInstances(lastTimeValidated, context);
        if(numberOfInstances != numRowsLastTimeValidated) {                    

            /* Do somethng here, for instance:
            Intent serviceIntent = new Intent(context, ValidateCalendarEventsService.class);
            context.startService(serviceIntent);    
            */

        }
    }

    private int getNumberOfInstances(long lastTimeValidated, Context context) {
        Calendar beginTime = Calendar.getInstance();


   beginTime.setTimeInMillis(lastTimeValidated);
        Calendar endTime = Calendar.getInstance();
        endTime.add(Calendar.YEAR, 1);
        endTime.add(Calendar.DAY_OF_MONTH, 1);//now + 366
        long startMillis = beginTime.getTimeInMillis();
        long endMillis = endTime.getTimeInMillis();
        Cursor cur = null;
        ContentResolver cr = context.getContentResolver();
        // Construct the query with the desired date range.
        Uri.Builder builder = CalendarContract.Instances.CONTENT_URI.buildUpon();
        ContentUris.appendId(builder, startMillis);
        ContentUris.appendId(builder, endMillis);
        // Submit the query
        cur = cr.query(builder.build(), null, null, null, null);
        //handle results
        return cur.getCount();
    }
}
于 2014-11-04T00:23:22.780 回答