I am trying to write a BroadcastReceiver that listens to events like insert, edit, delete to the native android calendar (ICS and above). So whenever one of these events occur the app should be able to at the least know that these events occurred.
Any one has an idea, how to do this or any reference links.
I have written my own broadcasterReceiver class that extends from BroadcastReceiver. Can't figure out the values in the manifest like, currently I have this which is not working:
<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>
Cheers,
Edit 1: Does anyone know a proper string for the data tag?, I think this is also required in the intent-filter.
Edit 2: Any hints about working with ContentObserver?
Finally found the solution after a lot of reading, this may help other finding a similar solution.
In the Manifest, you need to write these lines to be able to capture the changes:
<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>
Cheers,
In addition to the accepted answer:
The intent broadcasted by this code is send when any change is made to the calendar data:
<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>
Unfortunatly, it is also broadcasted when the device boots, or when the provider is created and there are no Extra's to read what so ever.
To make your app only handle insertion/deletion of event instances:
Keep track of the total number of event-instances (as SagiLow points out, this only works on add/delete and does not take updates into account). If it changed, re-validate your data based on the users calendar:
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();
}
}
来源:https://stackoverflow.com/questions/15217723/broadcastreceiver-for-android-calendar-events