Reputation: 221
I know this has been asked previously in this forum, but I tried everything written here and still nothing works for me. What I want to do is to insert an event to the calendar. Since there are several calendar applications on my device, I want to enable the user to choose which calendar application should contain the new event, similar to what happens when the user attempts to view a location using a map application (the user can select whether to activate google maps, the internet, ...). For this reason, I have to use an Intent.
BTW, I'm aware that inserting new events to the calendar using Intents is allowed only on devices with SDK version 14 or higher. My device has an API level of 15, so it supports the calendar API.
Here's my code:
Intent calendarIntent = new Intent(Intent.ACTION_INSERT);
calendarIntent.setData(Events.CONTENT_URI);
calendarIntent.putExtra(Events.TITLE, "title");
calendarIntent.putExtra(Events.EVENT_LOCATION, "address");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.YEAR, 2013);
cal.set(Calendar.HOUR_OF_DAY, 20);
cal.set(Calendar.MINUTE, 0);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, cal.getTime().getTime());
cal.set(Calendar.HOUR_OF_DAY, 20);
cal.set(Calendar.MINUTE, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, cal.getTime().getTime());
ctx.startActivity(calendarIntent);
I get this exception:
02-04 17:55:23.957: E/AndroidRuntime(3781): FATAL EXCEPTION: main
02-04 17:55:23.957: E/AndroidRuntime(3781): java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.applicat.meuchedet/com.applicat.meuchedet.MainScreenActivity}: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.INSERT dat=content://com.android.calendar/events (has extras) }
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1968)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1993)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.ActivityThread.access$600(ActivityThread.java:127)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1159)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.os.Handler.dispatchMessage(Handler.java:99)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.os.Looper.loop(Looper.java:137)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.ActivityThread.main(ActivityThread.java:4507)
02-04 17:55:23.957: E/AndroidRuntime(3781): at java.lang.reflect.Method.invokeNative(Native Method)
02-04 17:55:23.957: E/AndroidRuntime(3781): at java.lang.reflect.Method.invoke(Method.java:511)
02-04 17:55:23.957: E/AndroidRuntime(3781): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
02-04 17:55:23.957: E/AndroidRuntime(3781): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
02-04 17:55:23.957: E/AndroidRuntime(3781): at dalvik.system.NativeStart.main(Native Method)
02-04 17:55:23.957: E/AndroidRuntime(3781): Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.INSERT dat=content://com.android.calendar/events (has extras) }
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1535)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1387)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.Activity.startActivityForResult(Activity.java:3190)
02-04 17:55:23.957: E/AndroidRuntime(3781): at com.applicat.meuchedet.Screen.startActivity(Screen.java:433)
02-04 17:55:23.957: E/AndroidRuntime(3781): at com.applicat.meuchedet.CalendarAppointmentScheduler.writeAppointmentToCalendar(CalendarAppointmentScheduler.java:137)
02-04 17:55:23.957: E/AndroidRuntime(3781): at com.applicat.meuchedet.MainScreenActivity.onCreate(MainScreenActivity.java:258)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.Activity.performCreate(Activity.java:4465)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
02-04 17:55:23.957: E/AndroidRuntime(3781): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1932)
02-04 17:55:23.957: E/AndroidRuntime(3781): ... 11 more
What am I doing wrong?
Thanx
Upvotes: 14
Views: 20576
Reputation: 291
This is relevant for Android 11 and above devices, that on the top of steps mentioned in Common Intents - Add Event, we have to add the intent in the <queries>
block in the Android Manifest file.
Do note that adding an <intent-filter>
on Activity which launches the calendar intent won't work as it adds that Activity as a receiver of such intents, but rather adding following snippet in manifest file does the trick:
<queries>
<intent>
<action android:name="android.intent.action.INSERT" />
<data android:mimeType="vnd.android.cursor.dir/event" />
</intent>
</queries>
For me this trick worked for my Android 11 device, and it was already working fine for devices before that!
Upvotes: 0
Reputation: 1160
From the developers documentation here is the way you can add the event to the Calendar, opening the Calendar apps chooser:
fun addEvent(title: String, location: String, begin: Long, end: Long) {
val intent = Intent(Intent.ACTION_INSERT).apply {
data = Events.CONTENT_URI
putExtra(Events.TITLE, title)
putExtra(Events.EVENT_LOCATION, location)
putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end)
}
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
You can specify various event details using extras defined.
The key point is intent.resolveActivity(packageManager) != null
which will always return null from the Android API 30. So you need to add the intent-filter
for the activity that you are using with the INSERT
action and the specified mime type.
<activity ...>
<intent-filter>
<action android:name="android.intent.action.INSERT" />
<data android:mimeType="vnd.android.cursor.dir/event" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Data URI = Events.CONTENT_URI
MIME Type = "vnd.android.cursor.dir/event"
Upvotes: 2
Reputation: 1482
You can use this code as it checks first if there is available apps that can handle this intent.
fun addToCalenderAction(ctx: Context, session: ItemSession) {
val intent = Intent(Intent.ACTION_INSERT).apply {
data = CalendarContract.Events.CONTENT_URI
putExtra(CalendarContract.Events.TITLE, session.title ?: "AA")
putExtra(CalendarContract.Events.EVENT_LOCATION, session.location
?: "Egypt, ALex, ST23")
putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, parseTimeOfFirebase(session.startTime
?: "2021-05-31T19:56:22.636+0000"))
putExtra(CalendarContract.EXTRA_EVENT_END_TIME, parseTimeOfFirebase(endTime
?: "2021-05-31T21:56:22.636+0000"))
}
if (intent.resolveActivity(ctx.packageManager) != null) {
ctx.startActivity(intent)
}
}
NOTE: session is object that hold some data, you can use your own data
Upvotes: 0
Reputation: 10232
Insert an Event like this
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 0, 19, 8, 30);
Intent intent = new Intent(Intent.ACTION_INSERT)
.setData(Events.CONTENT_URI)
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME,
beginTime.getTimeInMillis())
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME,
endTime.getTimeInMillis())
.putExtra(Events.TITLE, "Yoga")
.putExtra(Events.DESCRIPTION, "Group class")
.putExtra(Events.EVENT_LOCATION, "The gym")
.putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
.putExtra(Intent.EXTRA_EMAIL, "[email protected],[email protected]");
startActivity(intent);
Upvotes: 10
Reputation: 571
You caught ActivityNotFoundException because any activity can't handle your action.
Instead using Intent.ACTION_INSERT try to do like this :
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event");
intent.putExtra(Events.TITLE, strTitle);
intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME,
startDateMillis);
intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME,
endDateMillis);
intent.putExtra(Events.ALL_DAY, false);// periodicity
intent.putExtra(Events.DESCRIPTION,strDescription));
You can check in developer documentation for other attributes.
Upvotes: 26