termux-calendar?
It would be useful to have a command like this:
termux-calendar add \
--title 'My meeting' \
--id 'Google:Work Calendar' \
--start "$unix_time_start" \
--stop "$unix_time_stop" \
--location "$latitude,$longitude" \
--description 'A long horrible meeting' \
--all-day 'false'
It seems straightforward with the intents documented here https://developer.android.com/guide/topics/providers/calendar-provider.html#intents, but I don't have much experience packaging code like this into java/kotlin apps, so not sure how to start. I tried this with the adb/termux am command, but I think it is getting rejected b/c of permissions.
@rjdang Did you ever find a way to get a calendar entry done from within Termux? I was looking for way to do this the other day.
Hi,
Yes and no. I was able to get it working in two less than ideal ways:
- Installing khal and vdirsyncer on a linux server (vdirsyncer uses hard links so it can’t be installed on Android), and using ssh to add events on the server with khal, then putting vdirsyncer in a cronjob to sync my calendar edits from that server to my calendar provider, and then letting Android’s calendar interface sync down to my phone. The problem with this is that vdirsyncer is unmaintained now (but still works really well for me so far) and is much slower than Android’s native calendar syncing. The slowness (~1 minute to sync b/c of cron) is fine for some situations, but for some scripts I wanted real time syncing. The other issue with this approach is that you need to have internet to get the syncing. I tried also installing khal locally on Android (khal does work in termux), and then using rsync to sync up events when I’m back online, but it didn’t feel that robust despite getting the job done.
vdirsyncer: https://github.com/pimutils/vdirsyncer/ khal: https://github.com/pimutils/khal
- Sending an intent to Tasker. This is much better performance wise as it has been extremely reliable and leverages Android’s calendar interface, which is fast and syncs nearly instantly locally and remotely. I really don’t like relying Tasker because it’s not open source, but this does work (xml profile and task for tasker part is attached). The script will send an intent, which triggers the profile to run whatever task is requested by the intent, in this case the task add_to_calendar. I had quoting issues with events with complex strings, so I punted on sending the data via intent and just write to and read from tmp files:
#!/usr/bin/env bash
termux_app=/data/data/com.termux
termux_files=$termux_app/files
termux_bin=$termux_files/usr/bin
title="$1"
description="$2"
location="$3"
calendar="$4"
start_time="$5"
stop_time="$6"
now="$(date +%s)"
in_seconds="$((start_time - now))"
in_minutes="$((in_seconds / 60))"
duration_seconds="$((stop_time - start_time))"
duration_minutes="$((duration_seconds / 60))"
tasker_tmp=/sdcard/Tasker/tmp
mkdir -p "$tasker_tmp"
printf %s "$title" > "$tasker_tmp/last_calendar_title"
printf %s "$description" > "$tasker_tmp/last_calendar_description"
printf %s "$location" > "$tasker_tmp/last_calendar_location"
printf %s "$calendar" > "$tasker_tmp/calendar"
"$termux_bin/am" broadcast --user 0 -a net.dinglisch.android.tasker.run_task \
-e task_name 'add_to_calendar' \
-e par1 "$in_minutes" \
-e par2 "$duration_minutes"
- My failed attempt at sending an intent directly to the calendar is here, but it doesn’t work. I found the documentation for all this almost impossible to understand without trial and error, and I unfortunately don’t have an Android build flow in my workflow so I can’t try it natively, which I think would be easier.
#!/usr/bin/env bash
termux_app=/data/data/com.termux
termux_files=$termux_app/files
termux_bin=$termux_files/usr/bin
title="$1"
description="$2"
location="$3"
calendar="$4"
start_time="$5"
stop_time="$6"
all_day=0
event_start_ms="$((start_time * 1000))"
event_stop_ms="$((stop_time * 1000))"
$termux_bin/am broadcast --user 0 -a android.intent.action.EDIT \
-c android.intent.category.DEFAULT \
-d 'content://calendar/events' \
-t 'vnd.android.cursor.dir/event' \
-n com.android.calendar/.ACTION_EDIT \
--es CALENDAR_ID "$calendar" \
--es TITLE "$title" \
--es EVENT_LOCATION "$location" \
--es DESCRIPTION "$description" \
--el EXTRA_EVENT_BEGIN_TIME "$event_start_ms" \
--el EXTRA_EVENT_END_TIME "$event_stop_ms" \
--es ALL_DAY "$all_day" \
--grant-read-uri-permission \
--grant-write-uri-permission
Any advice on how to get this intent working or how to go about officially adding it into the Termux API would defintely be definitely appreciated.
Thanks for sharing, these solutions seem complicated... was hoping for something like a portable self-contained golang utility aarch64 binary like pup or yq... Did you happen to try gcalcli? (I know Python is installable on Termux)
I needed non-google calendars, so gcalcli wouldn't do it for my use case. I also wanted offline modifications to sync correctly when back online, and for other apps that read Android's calendar to reflect the changes in real time.
@rjdang if you have a caldav calender you could use calcurse{-caldav} to edit the calendar in termux and sync it, and then use for example davx5 to sync to the android calendar
@rjdang makes sense. Gcalcli errors out (https://github.com/insanum/gcalcli/issues/481) with AttributeError: module 'locale' has no attribute 'nl_langinfo'
In my case I'm trying to do Google Calendar, so @Grimler91 your suggestion might help rjdang, but won't help me as Google doesn't support industry standards like CalDav. Thanks Google! :disappointed:
@jcrowgey fixed the issue with nl_langinfo in master, I got my oauth token and was able to quick add some appointments from the Termux console, so I'm good
gcalcli list
gcalcli --default-calendar [email protected] quick "Go to HD @ 7:15pm"
is there anyway to access the calendar data in android's calendar accounts using termux?