I'm getting problems creating a new Calendar event from my Android app. Here's my code:
ContentResolver cr = getActivity().getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, dtStart.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());
values.put(CalendarContract.Events.DTEND, dtEnd.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());
values.put(CalendarContract.Events.TITLE, edittext.getText().toString());
values.put(CalendarContract.Events.CALENDAR_ID, calId);
values.put(CalendarContract.Events.VISIBLE, 0);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.WRITE_CALENDAR},
MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
}
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
In my manifest I have:
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
I'm getting the following error:
java.lang.IllegalArgumentException: Only the provider may write to visible
I've had a good look around but can't find anything I'm doing wrong, all the code examples I've seen are basically the same as the above. Any help much appreciated.
I don't think you can modify the visibility of an event via a ContentResolver. Comment out the line
values.put(CalendarContract.Events.VISIBLE, 0);
and try again.
Building up from this Android documentation
Writing to Events
Related
When changing the timezone of an event with both EVENT_TIMEZONE and EVENT_END_TIMEZONE set, for all calendar apps I tried (aCalendar 0.99.8, Google's default calendar 4.4.2), EVENT_END_TIMEZONE is not updated to the new timezone, although the end time is displayed according to the new timezone.
Why isn't the end timezone set to the same value as the start/regular timezone? Am I missing some other timezone-related fields that have to be set in order for EVENT_END_TIMEZONE to be used / updated?
As I was asked to provide some code, here is one possible way to define an event showing the described behavior (note that, depending on the context of your code, you may need to use a different URI and/or add additional fields):
final ContentResolver cr = /* ... */;
final long calendarId = /* ... */;
final ContentValues values = new ContentValues();
values.put(CalendarContract.Events.CALENDAR_ID, calendarId);
values.put(CalendarContract.Events.TITLE, "Test");
values.put(CalendarContract.Events.DTSTART, 1428307200000L);
values.put(CalendarContract.Events.EVENT_TIMEZONE, "Europe/Berlin");
values.put(CalendarContract.Events.DTEND, 1428314400000L);
values.put(CalendarContract.Events.EVENT_END_TIMEZONE,"Europe/Berlin");
final Uri result = cr.insert(CalendarContract.Events.CONTENT_URI, values);
Once the event is changed to another timezone using any of the two apps listed above, its EVENT_END_TIMEZONE is preserved ("Europe/Berlin"), while the event's end is displayed relative to the new timezone (something different from "Europe/Berlin").
I am just learning how to work with the Android Calendars. So far, I am able to display the info about existing calendars. I can also create my own local calendars -- the test code like:
private void createCalendarTest()
{
Uri.Builder builder = Calendars.CONTENT_URI.buildUpon();
builder.appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(Calendars.ACCOUNT_NAME, "private")
.appendQueryParameter(Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
Uri uri = builder.build();
ContentValues values = new ContentValues();
values.put(Calendars.NAME, "TEST");
values.put(Calendars.CALENDAR_DISPLAY_NAME, "Calendar named TEST");
values.put(Calendars.SYNC_EVENTS, false);
values.put(Calendars.VISIBLE, true);
getContentResolver().insert(uri, values);
}
Actually, I can create many calendars that differ only in _ID. I have read elsewhere that I can create a calendar only when using the sync adapter. Now, how can I delete the calendar? I expect the URI must also contain the sync adapter info, and the _ID of the deleted calendar. I tried the following code, but I was unsuccessful:
private void deleteCalendarTest()
{
Uri.Builder builder = Calendars.CONTENT_URI.buildUpon();
builder.appendPath("6") // here for testing; I know the calender has this ID
.appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(Calendars.ACCOUNT_NAME, "private")
.appendQueryParameter(Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
Uri uri = builder.build();
getContentResolver().delete(uri, null, null);
Toast.makeText(this, "??? deleteCalendarTest() not working", Toast.LENGTH_SHORT).show();
}
How can I fix it?
After reading with more attention the documentation, i found out you should add to the content values the following fields too:
values.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
values.put(CalendarContract.Calendars.ACCOUNT_NAME, "private");
values.put(CalendarContract.Calendars.ACCOUNT_TYPE,CalendarContract.ACCOUNT_TYPE_LOCAL);
Then everything else should be fine and you should be able to delete the inserted calendar! ;)
"andrea-rinaldi" was right. The below code snippet worked for me. The "calendarHandler" is an instance of the helper class that extends AsyncQueryHandler, the one you used to create the calendar.
Uri calUri = CalendarContract.Calendars.CONTENT_URI;
calUri = calUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, BuildConfig.APPLICATION_ID)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL)
.build();
calendarHandler.startDelete(0,-1,calUri,null,null);
This Kotlin solution worked for me:
val uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, calendarId.toLong())
contentResolver.delete(uri, null, null)
I'm removing the calendar with the application (not a SyncAdapter) so there's no need to append any query parameters. Just append the calender's id to the content uri and use a ContentResolver to delete the calendar.
I'm just getting up to speed on Android, and I want to send calendar event to others from mobile. Same as whatsapp sending contacts. For sending Contact in chat (XMPP) I've used vCard. So for sending calendar event in chat what should I use?
I have searched a lot. But can't find something fruitful.
Please suggest the library or code snippet for sending calendar event in XMPP.
Thanks in advance.
You may refer to iCal Import Export allows you to import iCalender files to your calender without using google synchronization services.
Using this you can import all calendar events to iCalendar files and also export those events back to calendar. Using Calendar Provider you can fetch all calendar data, but requires android API level 14 or above while using iCal Import Export you can fetch all calendar data for lower API levels too.
manifest
<uses-permission android:name="android.permission.READ_CALENDAR" />
Code:
Cursor cursor = cr.query(Uri.parse("content://calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
cursor.moveToFirst();
String[] CalNames = new String[cursor.getCount()];
int[] CalIds = new int[cursor.getCount()];
for (int i = 0; i < CalNames.length; i++) {
CalIds[i] = cursor.getInt(0);
CalNames[i] = cursor.getString(1);
cursor.moveToNext();
}
cursor.close();
Fetching all events, and particular event is done by specifying range
ContentResolver contentResolver = getContentResolver();
Uri.Builder builder = Uri.parse(getCalendarUriBase() + "/instances/when").buildUpon();
long now = new Date().getTime();
ContentUris.appendId(builder, now - DateUtils.MILLIS_PER_DAY*10000);
ContentUris.appendId(builder, now + DateUtils.MILLIS_PER_DAY * 10000);
and then let's say you wish to log events ID from calendar with ID = 1
Cursor eventCursor = contentResolver.query(builder.build(),
new String[] { "event_id"}, "Calendars._id=" + 1,
null, "startDay ASC, startMinute ASC");
// For a full list of available columns see http://tinyurl.com/yfbg76w
while (eventCursor.moveToNext()) {
String uid2 = eventCursor.getString(0);
Log.v("eventID : ", uid2);
}
Now display this event in Listview select one of this for send as a text messsage and on receiver side :
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event");
intent.putExtra("beginTime", cal.getTimeInMillis());
intent.putExtra("allDay", true);
intent.putExtra("rrule", "FREQ=YEARLY");
intent.putExtra("endTime", cal.getTimeInMillis()+60*60*1000);
intent.putExtra("title", HERE MSG WHICH YOU RECEIVE);
startActivity(intent);
There is no library AFAIK and it's really just a matter of retrieving the calender event and transforming it's data into XML. Unfortunately there is also no XEP on how calendar events should be represented in XMPP/XML so you have to come up with your own representation.
iCalendar/vCalendar is the calendar file format similar to vCard
You can add new field in vcard that save calender info example
VCard vCard = new VCard();
vCard.setField("calender","calender info");
calender info should be a sting, it can be a json format string.
user who receives it can load your vcard and use method
vCard.load(connection, Jid);
String string=vCard.getField("calender");
You really don't need any specific library for that purpose.
You can check out Calendar Provider
They have an awesome example on it too!
Be sure to use these permissions in your manifest.xml
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
And if you wish to send contacts then check this out Android: How to import contact from phone?
Vote this up if it helped you! I really need it. :)
Hi stackoverflow I'm trying to develop an application to add SMS to prrogrammatically, I'm using the following code to add SMS
private void addSMS()
{
Uri uri = Uri.parse("content://sms/");
ContentValues cv2 = new ContentValues();
cv2.put("address", "+91956322222");
cv2.put("date", "1309632433677");
cv2.put("read", 1);
cv2.put("type", 2);
cv2.put("body", "Hey");
getContentResolver().insert(uri, cv2);
cv2.clear();
}
Permissions :
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
Problem is the Time of the message, it's displaying the time we added the message, but not the date we have passed in the list of messages, but when I open the message we added then the time will be correct as our input, please help me to solve this riddle.
Thanks.
This is a known problem I think. Try to add this line in the end:
getContentResolver().delete(Uri.parse("content://sms/conversations/-1"), null, null);
If you want more explanation you should check this out!
Here is the working code, Thanks to #Amulya Khare
private void addSMS()
{
Uri uri = Uri.parse("content://sms/");
ContentValues cv2 = new ContentValues();
cv2.put("address", "+91956322222");
cv2.put("date", "1309632433677");
cv2.put("read", 1);
cv2.put("type", 2);
cv2.put("body", "Hey");
getContentResolver().insert(uri, cv2);
/** This is very important line to solve the problem */
getContentResolver().delete(Uri.parse("content://sms/conversations/-1"), null, null);
cv2.clear();
}
Please follow the link to get more information Android programatically inserted SMS have incorrect timestamp in Messaging apps
I'm trying to create an event using the new Calendar API and while it creates an event locally, it never shows up on the Google Calendar. I tried to manually create an event in the same calendar and that synced perfectly. I've seen quite a few similar posts, but none of the answers seem to do the trick.
Here's the code I'm using for Android 4.0+:
ContentValues values = new ContentValues();
values.put(Events.DTSTART, info.getStartTime());
values.put(Events.DTEND, info.getEndTime());
values.put(Events.TITLE, info.getTitle());
values.put(Events.DESCRIPTION, info.getDescription());
values.put(Events.CALENDAR_ID, this.getCalendarInfo().getId()); //hardcoded to 1, which is my default calendar
values.put(Events.EVENT_TIMEZONE, info.getTimeZone());
values.put(Events.STATUS, Events.STATUS_CONFIRMED);
values.put(Events.HAS_ALARM, 0);
this.getContentResolver().insert(Events.CONTENT_URI, values);
I'm not quite sure what's wrong and I hope someone can help me out! Thanks!
My Solution is request sync for calendar provider, it's work for me:
private void requestCalendarSync()
{
AccountManager aM = AccountManager.get(this);
Account[] accounts = aM.getAccounts();
for (Account account : accounts)
{
int isSyncable = ContentResolver.getIsSyncable(account, CalendarContract.AUTHORITY);
if (isSyncable > 0)
{
Bundle extras = new Bundle();
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(accounts[0], CalendarContract.AUTHORITY, extras);
}
}
}
permission:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
enter code hereits easy, the line
values.put(Events.CALENDAR_ID, this.getCalendarInfo().getId()); //hardcoded to 1, which is my default calendar
actually tells android to add event to LOCAL android calendar .... i assume that you would like to add it to calendar synced to your gmail account .... so instead of
values.put(Events.CALENDAR_ID, this.getCalendarInfo().getId());
try
values.put(Events.CALENDAR_ID, 2);