Controlling my Android phone by voice
| speech, android, speechtotextI want to be able to use voice control to do things on my phone while I'm busy washing dishes, putting things away, knitting, or just keeping my hands warm. It'll also be handy to have a way to get things out of my head when the kiddo is koala-ing me. I've been using my Google Pixel 8's voice interface to set timers, send text messages, and do quick web searches. Building on my recent thoughts on wearable computing, I decided to spend some more time investigating the Google Assistant and Voice Access features in Android and setting up other voice shortcuts.
Tasker routines
I switched back to Google Assistant from Gemini so that I could run Tasker routines. I also found out that I needed to switch the language from English/Canada to English/US in order for my Tasker scripts to run instead of Google Assistant treating them as web searches. Once that was sorted out, I could run Tasker tasks with "Hey Google, run {task-name} in Tasker" and parameterize them with "Hey Google, run {task-name} with {parameter} in Tasker."
Voice Access
Learning how to use Voice Access to navigate, click, and type on my phone was straightforward. "Scroll down" works for webpages, while "scroll right" works for the e-books I have in Libby. Tapping items by text usually works. When it doesn't, I can use "show labels", "show numbers", or "show grid." The speech-to-text of "type …" isn't as good as Whisper, so I probably won't use it for a lot of dictation, but it's fine for quick notes. I can keep recording in the background so that I have the raw audio in case I want to review it or grab the WhisperX transcripts instead.
For some reason, saying "Hey Google, voice access" to start up voice access has been leaving the Assistant dialog on the screen, which makes it difficult to interact with the screen I'm looking at. I added a Tasker routine to start voice access, wait a second, and tap on the screen to dismiss the Assistant dialog.
Start Voice.tsk.xml - Import via Taskernet
Start Voice.tsk.xml
<TaskerData sr="" dvi="1" tv="6.3.13"> <Task sr="task24"> <cdate>1737565479418</cdate> <edate>1737566416661</edate> <id>24</id> <nme>Start Voice</nme> <pri>1000</pri> <Share sr="Share"> <b>false</b> <d>Start voice access and dismiss the assistant dialog</d> <g>Accessibility,AutoInput</g> <p>true</p> <t></t> </Share> <Action sr="act0" ve="7"> <code>20</code> <App sr="arg0"> <appClass>com.google.android.apps.accessibility.voiceaccess.LauncherActivity</appClass> <appPkg>com.google.android.apps.accessibility.voiceaccess</appPkg> <label>Voice Access</label> </App> <Str sr="arg1" ve="3"/> <Int sr="arg2" val="0"/> <Int sr="arg3" val="0"/> </Action> <Action sr="act1" ve="7"> <code>30</code> <Int sr="arg0" val="0"/> <Int sr="arg1" val="1"/> <Int sr="arg2" val="0"/> <Int sr="arg3" val="0"/> <Int sr="arg4" val="0"/> </Action> <Action sr="act2" ve="7"> <code>107361459</code> <Bundle sr="arg0"> <Vals sr="val"> <EnableDisableAccessibilityService><null></EnableDisableAccessibilityService> <EnableDisableAccessibilityService-type>java.lang.String</EnableDisableAccessibilityService-type> <Password><null></Password> <Password-type>java.lang.String</Password-type> <com.twofortyfouram.locale.intent.extra.BLURB>Actions To Perform: click(point,564\,1045) Not In AutoInput: true Not In Tasker: true Separator: , Check Millis: 1000</com.twofortyfouram.locale.intent.extra.BLURB> <com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type> <net.dinglisch.android.tasker.JSON_ENCODED_KEYS>parameters</net.dinglisch.android.tasker.JSON_ENCODED_KEYS> <net.dinglisch.android.tasker.JSON_ENCODED_KEYS-type>java.lang.String</net.dinglisch.android.tasker.JSON_ENCODED_KEYS-type> <net.dinglisch.android.tasker.RELEVANT_VARIABLES><StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%ailastbounds Last Bounds Bounds (left,top,right,bottom) of the item that the action last interacted with</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%ailastcoordinates Last Coordinates Center coordinates (x,y) of the item that the action last interacted with</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2>%err Error Code Only available if you select &lt;b&gt;Continue Task After Error&lt;/b&gt; and the action ends in error</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3>%errmsg Error Message Only available if you select &lt;b&gt;Continue Task After Error&lt;/b&gt; and the action ends in error</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3></StringArray></net.dinglisch.android.tasker.RELEVANT_VARIABLES> <net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type> <net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>parameters plugininstanceid plugintypeid </net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS> <net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type> <net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled> <net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type> <parameters>{"_action":"click(point,564\\,1045)","_additionalOptions":{"checkMs":"1000","separator":",","withCoordinates":false},"_whenToPerformAction":{"notInAutoInput":true,"notInTasker":true},"generatedValues":{}}</parameters> <parameters-type>java.lang.String</parameters-type> <plugininstanceid>b46b8afc-c840-40ad-9283-3946c57a1018</plugininstanceid> <plugininstanceid-type>java.lang.String</plugininstanceid-type> <plugintypeid>com.joaomgcd.autoinput.intent.IntentActionv2</plugintypeid> <plugintypeid-type>java.lang.String</plugintypeid-type> </Vals> </Bundle> <Str sr="arg1" ve="3">com.joaomgcd.autoinput</Str> <Str sr="arg2" ve="3">com.joaomgcd.autoinput.activity.ActivityConfigActionv2</Str> <Int sr="arg3" val="60"/> <Int sr="arg4" val="1"/> </Action> </Task> </TaskerData>
I can use "Hey Google, read aloud" to read a webpage. I can use "Hey Google, skip ahead 2 minutes" or "Hey Google, rewind 30 seconds." Not sure how I can navigate by text, though. It would be nice to get an overview of headings and then jump to the one I want, or search for text and continue from there.
Autoplay an emacs.tv video
I wanted to be able to play random emacs.tv videos without needing to touch my phone. I added autoplay support to the web interface so that you can open https://emacs.tv?autoplay=1 and have it autoplay videos when you select the next random one by clicking on the site logo, "Lucky pick", or the dice icon. The first video doesn't autoplay because YouTube requires user interaction in order to autoplay unmuted videos, but I can work around that with a Tasker script that loads the URL, waits a few seconds, and clicks on the heading with AutoInput.
Emacs TV.tsk.xml - Import via Taskernet
Emacs TV.tsk.xml
<TaskerData sr="" dvi="1" tv="6.3.13"> <Task sr="task18"> <cdate>1737558964554</cdate> <edate>1737562488128</edate> <id>18</id> <nme>Emacs TV</nme> <pri>1000</pri> <Share sr="Share"> <b>false</b> <d>Play random Emacs video</d> <g>Watch</g> <p>true</p> <t></t> </Share> <Action sr="act0" ve="7"> <code>104</code> <Str sr="arg0" ve="3">https://emacs.tv?autoplay=1</Str> <App sr="arg1"/> <Int sr="arg2" val="0"/> <Str sr="arg3" ve="3"/> </Action> <Action sr="act1" ve="7"> <code>30</code> <Int sr="arg0" val="0"/> <Int sr="arg1" val="3"/> <Int sr="arg2" val="0"/> <Int sr="arg3" val="0"/> <Int sr="arg4" val="0"/> </Action> <Action sr="act2" ve="7"> <code>107361459</code> <Bundle sr="arg0"> <Vals sr="val"> <EnableDisableAccessibilityService><null></EnableDisableAccessibilityService> <EnableDisableAccessibilityService-type>java.lang.String</EnableDisableAccessibilityService-type> <Password><null></Password> <Password-type>java.lang.String</Password-type> <com.twofortyfouram.locale.intent.extra.BLURB>Actions To Perform: click(point,229\,417) Not In AutoInput: true Not In Tasker: true Separator: , Check Millis: 1000</com.twofortyfouram.locale.intent.extra.BLURB> <com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type> <net.dinglisch.android.tasker.JSON_ENCODED_KEYS>parameters</net.dinglisch.android.tasker.JSON_ENCODED_KEYS> <net.dinglisch.android.tasker.JSON_ENCODED_KEYS-type>java.lang.String</net.dinglisch.android.tasker.JSON_ENCODED_KEYS-type> <net.dinglisch.android.tasker.RELEVANT_VARIABLES><StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%ailastbounds Last Bounds Bounds (left,top,right,bottom) of the item that the action last interacted with</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%ailastcoordinates Last Coordinates Center coordinates (x,y) of the item that the action last interacted with</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2>%err Error Code Only available if you select &lt;b&gt;Continue Task After Error&lt;/b&gt; and the action ends in error</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3>%errmsg Error Message Only available if you select &lt;b&gt;Continue Task After Error&lt;/b&gt; and the action ends in error</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3></StringArray></net.dinglisch.android.tasker.RELEVANT_VARIABLES> <net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type> <net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>parameters plugininstanceid plugintypeid </net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS> <net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type> <net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled> <net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type> <parameters>{"_action":"click(point,229\\,417)","_additionalOptions":{"checkMs":"1000","separator":",","withCoordinates":false},"_whenToPerformAction":{"notInAutoInput":true,"notInTasker":true},"generatedValues":{}}</parameters> <parameters-type>java.lang.String</parameters-type> <plugininstanceid>45ce7a83-47e5-48fb-8c3e-20655e668353</plugininstanceid> <plugininstanceid-type>java.lang.String</plugininstanceid-type> <plugintypeid>com.joaomgcd.autoinput.intent.IntentActionv2</plugintypeid> <plugintypeid-type>java.lang.String</plugintypeid-type> </Vals> </Bundle> <Str sr="arg1" ve="3">com.joaomgcd.autoinput</Str> <Str sr="arg2" ve="3">com.joaomgcd.autoinput.activity.ActivityConfigActionv2</Str> <Int sr="arg3" val="60"/> <Int sr="arg4" val="1"/> </Action> </Task> </TaskerData>
Then I set up a Google Assistant routine with the triggers "teach me" or "Emacs TV" and the action "run Emacs TV in Tasker. Now I can say "Hey Google, teach me" and it'll play a random Emacs video for me. I can repeat "Hey Google, teach me" to get a different video, and I can pause with "Hey Google, pause video".
This was actually my second approach. The first
time I tried to implement this, I thought about
using Voice Access to interact with the buttons.
Strangely, I couldn't get Voice Access to click on
the header links or the buttons even when I had
aria-label
, role="button"
, and tabindex
attributes set on them. As a hacky workaround, I
made the site logo pick a new random video when
clicked, so I can at least use it as a large touch
target when I use "display grid" in Voice Access.
("Tap 5" will load the next video.)
There doesn't seem to be a way to add custom voice access commands to a webpage in a way that hooks into Android Voice Access and iOS Voice Control, but maybe I'm just missing something obvious when it comes to ARIA attributes.
Open my Org agenda and scroll through it
There were some words that I couldn't get Google Assistant or Voice Access to understand, like "open Orgzly Revived". Fortunately, "Open Revived" worked just fine.
I wanted to be able to see my Org Agenda. After some fiddling around (see the resources in this section), I figured out this AutoShare intent that runs an agenda search:
orgzly-revived-search.intent
{ "target": "Activity", "appname": "Orgzly Revived", "action": "android.intent.action.MAIN", "package": "com.orgzlyrevived", "class": "com.orgzly.android.ui.main.MainActivity", "extras": [ { "type": "String", "key": "com.orgzly.intent.extra.QUERY_STRING", "name": "Query" } ], "name": "Search", "id": "Orgzly-search" }
Then I defined a Tasker task called "Search Orgzly Revived":
Download Search Orgzly Revived.tsk.xml
Search Orgzly Revived.tsk.xml
<TaskerData sr="" dvi="1" tv="6.3.13"> <Task sr="task16"> <cdate>1676823952566</cdate> <edate>1737567565538</edate> <id>16</id> <nme>Search Orgzly Revived</nme> <pri>100</pri> <Share sr="Share"> <b>false</b> <d>Search Orgzly Revived</d> <g>Work,Well-Being</g> <p>false</p> <t></t> </Share> <Action sr="act0" ve="7"> <code>18</code> <App sr="arg0"> <appClass>com.orgzly.android.ui.LauncherActivity</appClass> <appPkg>com.orgzlyrevived</appPkg> <label>Orgzly Revived</label> </App> <Int sr="arg1" val="0"/> </Action> <Action sr="act1" ve="7"> <code>547</code> <Str sr="arg0" ve="3">%extra</Str> <Str sr="arg1" ve="3">com.orgzly.intent.extra.QUERY_STRING:%par1</Str> <Int sr="arg2" val="0"/> <Int sr="arg3" val="0"/> <Int sr="arg4" val="0"/> <Int sr="arg5" val="3"/> <Int sr="arg6" val="1"/> </Action> <Action sr="act2" ve="7"> <code>877</code> <Str sr="arg0" ve="3">android.intent.action.MAIN</Str> <Int sr="arg1" val="0"/> <Str sr="arg2" ve="3"/> <Str sr="arg3" ve="3"/> <Str sr="arg4" ve="3">%extra</Str> <Str sr="arg5" ve="3"/> <Str sr="arg6" ve="3"/> <Str sr="arg7" ve="3">com.orgzlyrevived</Str> <Str sr="arg8" ve="3">com.orgzly.android.ui.main.MainActivity</Str> <Int sr="arg9" val="1"/> </Action> <Img sr="icn" ve="2"> <nme>mw_action_today</nme> </Img> </Task> </TaskerData>
I made a Google Assistant routine that uses "show my agenda" as the trigger and "run search orgzly revived in Tasker" as the action. After a quick "Hey Google, show my agenda; Hey Google, voice access", I can use "scroll down" to page through the list. "Back" gets me to the list of notebooks, and "inbox" opens my inbox.
Resources:
Add and open notes in Orgzly Revived
When I'm looking at an Orgzly Revived notebook with Voice Access turned on, "plus" starts a new note. Anything that isn't a label gets typed, so I can just start saying the title of my note (or use "type …"). If I want to add the content, I have to use "hide keyboard", "tap content", and then "type …"). "Tap scheduled time; Tomorrow" works if the scheduled time widget is visible, so I just need to use "scroll down" if the title is long. "Tap done; one" saves it.
Adding a note could be simpler - maybe a Tasker task that prompts me for text and adds it. I could use Tasker to prepend to my Inbox.org and then reload it in Orgzly. It would be more elegant to figure out the intent for adding a note, though. Maybe in the Orgzly Android intent receiver documentation?
When I'm looking at the Orgzly notebook and I say part of the text in a note without a link, it opens the note. If the note has a link, it seems to open the link directly. Tapping by numbers also goes to the link, but tapping by grid opens the note.
I'd love to speech-enable this someday so that I can hear Orgzly Revived step through my agenda and use my voice to mark things as cancelled/done, schedule them for today/tomorrow/next week, or add extra notes to the body.
Add items to OurGroceries
W+ and I use the OurGroceries app. As it turns out, "Hey Google, ask OurGroceries to add milk" still works. Also, Voice Access works fine with OurGroceries. I can say "Plus", dictate an item, and tap "Add." I configured the cross-off action to be swipes instead of taps to minimize accidental crossing-off at the store, so I can say "swipe right on apples" to mark that as done.
Track time
I added a Tasker task to update my personal time-tracking system, and I added some Google Assistant routines for common categories like writing or routines. I can also use "run track with {category} in Tasker" to track a less-common category. The kiddo likes to get picked up and hugged a lot, so I added a "Hey Google, koala time" routine to clock into childcare in a more fun way. I have to enunciate that one clearly or it'll get turned into "Call into …", which doesn't work.
Toggle recording
Since I was tinkering around with Tasker a lot, I
decided to try moving my voice recording into it.
I want to save timestamped recordings into my
~/sync/recordings
directory so that they're
automatically synchronized with Syncthing, and
then they can feed into my WhisperX workflow. This
feels a little more responsive and reliable than
Fossify Voice Recorder, actually, since that one
tended to become unresponsive from time to time.
Download Toggle Recording.tsk.xml - Import via Taskernet
Toggle Recording.tsk.xml
<TaskerData sr="" dvi="1" tv="6.3.13"> <Task sr="task12"> <cdate>1737504717303</cdate> <edate>1737572159218</edate> <id>12</id> <nme>Toggle Recording</nme> <pri>100</pri> <Share sr="Share"> <b>false</b> <d>Toggle recording on and off; save timestamped file to sync/recordings</d> <g>Sound</g> <p>true</p> <t></t> </Share> <Action sr="act0" ve="7"> <code>37</code> <ConditionList sr="if"> <Condition sr="c0" ve="3"> <lhs>%RECORDING</lhs> <op>12</op> <rhs></rhs> </Condition> </ConditionList> </Action> <Action sr="act1" ve="7"> <code>549</code> <Str sr="arg0" ve="3">%RECORDING</Str> <Int sr="arg1" val="0"/> <Int sr="arg2" val="0"/> <Int sr="arg3" val="0"/> </Action> <Action sr="act10" ve="7"> <code>166160670</code> <Bundle sr="arg0"> <Vals sr="val"> <ActionIconString1><null></ActionIconString1> <ActionIconString1-type>java.lang.String</ActionIconString1-type> <ActionIconString2><null></ActionIconString2> <ActionIconString2-type>java.lang.String</ActionIconString2-type> <ActionIconString3><null></ActionIconString3> <ActionIconString3-type>java.lang.String</ActionIconString3-type> <ActionIconString4><null></ActionIconString4> <ActionIconString4-type>java.lang.String</ActionIconString4-type> <ActionIconString5><null></ActionIconString5> <ActionIconString5-type>java.lang.String</ActionIconString5-type> <AppendTexts>false</AppendTexts> <AppendTexts-type>java.lang.Boolean</AppendTexts-type> <BackgroundColor><null></BackgroundColor> <BackgroundColor-type>java.lang.String</BackgroundColor-type> <BadgeType><null></BadgeType> <BadgeType-type>java.lang.String</BadgeType-type> <Button1UnlockScreen>false</Button1UnlockScreen> <Button1UnlockScreen-type>java.lang.Boolean</Button1UnlockScreen-type> <Button2UnlockScreen>false</Button2UnlockScreen> <Button2UnlockScreen-type>java.lang.Boolean</Button2UnlockScreen-type> <Button3UnlockScreen>false</Button3UnlockScreen> <Button3UnlockScreen-type>java.lang.Boolean</Button3UnlockScreen-type> <Button4UnlockScreen>false</Button4UnlockScreen> <Button4UnlockScreen-type>java.lang.Boolean</Button4UnlockScreen-type> <Button5UnlockScreen>false</Button5UnlockScreen> <Button5UnlockScreen-type>java.lang.Boolean</Button5UnlockScreen-type> <ChronometerCountDown>false</ChronometerCountDown> <ChronometerCountDown-type>java.lang.Boolean</ChronometerCountDown-type> <Colorize>false</Colorize> <Colorize-type>java.lang.Boolean</Colorize-type> <DismissOnTouchVariable><null></DismissOnTouchVariable> <DismissOnTouchVariable-type>java.lang.String</DismissOnTouchVariable-type> <ExtraInfo><null></ExtraInfo> <ExtraInfo-type>java.lang.String</ExtraInfo-type> <GroupAlertBehaviour><null></GroupAlertBehaviour> <GroupAlertBehaviour-type>java.lang.String</GroupAlertBehaviour-type> <GroupKey><null></GroupKey> <GroupKey-type>java.lang.String</GroupKey-type> <IconExpanded><null></IconExpanded> <IconExpanded-type>java.lang.String</IconExpanded-type> <IsGroupSummary>false</IsGroupSummary> <IsGroupSummary-type>java.lang.Boolean</IsGroupSummary-type> <IsGroupVariable><null></IsGroupVariable> <IsGroupVariable-type>java.lang.String</IsGroupVariable-type> <MediaAlbum><null></MediaAlbum> <MediaAlbum-type>java.lang.String</MediaAlbum-type> <MediaArtist><null></MediaArtist> <MediaArtist-type>java.lang.String</MediaArtist-type> <MediaDuration><null></MediaDuration> <MediaDuration-type>java.lang.String</MediaDuration-type> <MediaIcon><null></MediaIcon> <MediaIcon-type>java.lang.String</MediaIcon-type> <MediaLayout>false</MediaLayout> <MediaLayout-type>java.lang.Boolean</MediaLayout-type> <MediaNextCommand><null></MediaNextCommand> <MediaNextCommand-type>java.lang.String</MediaNextCommand-type> <MediaPauseCommand><null></MediaPauseCommand> <MediaPauseCommand-type>java.lang.String</MediaPauseCommand-type> <MediaPlayCommand><null></MediaPlayCommand> <MediaPlayCommand-type>java.lang.String</MediaPlayCommand-type> <MediaPlaybackState><null></MediaPlaybackState> <MediaPlaybackState-type>java.lang.String</MediaPlaybackState-type> <MediaPosition><null></MediaPosition> <MediaPosition-type>java.lang.String</MediaPosition-type> <MediaPreviousCommand><null></MediaPreviousCommand> <MediaPreviousCommand-type>java.lang.String</MediaPreviousCommand-type> <MediaTrack><null></MediaTrack> <MediaTrack-type>java.lang.String</MediaTrack-type> <MessagingImages><null></MessagingImages> <MessagingImages-type>java.lang.String</MessagingImages-type> <MessagingOwnIcon><null></MessagingOwnIcon> <MessagingOwnIcon-type>java.lang.String</MessagingOwnIcon-type> <MessagingOwnName><null></MessagingOwnName> <MessagingOwnName-type>java.lang.String</MessagingOwnName-type> <MessagingPersonBot><null></MessagingPersonBot> <MessagingPersonBot-type>java.lang.String</MessagingPersonBot-type> <MessagingPersonIcons><null></MessagingPersonIcons> <MessagingPersonIcons-type>java.lang.String</MessagingPersonIcons-type> <MessagingPersonImportant><null></MessagingPersonImportant> <MessagingPersonImportant-type>java.lang.String</MessagingPersonImportant-type> <MessagingPersonNames><null></MessagingPersonNames> <MessagingPersonNames-type>java.lang.String</MessagingPersonNames-type> <MessagingPersonUri><null></MessagingPersonUri> <MessagingPersonUri-type>java.lang.String</MessagingPersonUri-type> <MessagingSeparator><null></MessagingSeparator> <MessagingSeparator-type>java.lang.String</MessagingSeparator-type> <MessagingTexts><null></MessagingTexts> <MessagingTexts-type>java.lang.String</MessagingTexts-type> <NotificationChannelBypassDnd>false</NotificationChannelBypassDnd> <NotificationChannelBypassDnd-type>java.lang.Boolean</NotificationChannelBypassDnd-type> <NotificationChannelDescription><null></NotificationChannelDescription> <NotificationChannelDescription-type>java.lang.String</NotificationChannelDescription-type> <NotificationChannelId><null></NotificationChannelId> <NotificationChannelId-type>java.lang.String</NotificationChannelId-type> <NotificationChannelImportance><null></NotificationChannelImportance> <NotificationChannelImportance-type>java.lang.String</NotificationChannelImportance-type> <NotificationChannelName><null></NotificationChannelName> <NotificationChannelName-type>java.lang.String</NotificationChannelName-type> <NotificationChannelShowBadge>false</NotificationChannelShowBadge> <NotificationChannelShowBadge-type>java.lang.Boolean</NotificationChannelShowBadge-type> <PersistentVariable><null></PersistentVariable> <PersistentVariable-type>java.lang.String</PersistentVariable-type> <PhoneOnly>false</PhoneOnly> <PhoneOnly-type>java.lang.Boolean</PhoneOnly-type> <PriorityVariable><null></PriorityVariable> <PriorityVariable-type>java.lang.String</PriorityVariable-type> <PublicVersion><null></PublicVersion> <PublicVersion-type>java.lang.String</PublicVersion-type> <ReplyAction><null></ReplyAction> <ReplyAction-type>java.lang.String</ReplyAction-type> <ReplyChoices><null></ReplyChoices> <ReplyChoices-type>java.lang.String</ReplyChoices-type> <ReplyLabel><null></ReplyLabel> <ReplyLabel-type>java.lang.String</ReplyLabel-type> <ShareButtonsVariable><null></ShareButtonsVariable> <ShareButtonsVariable-type>java.lang.String</ShareButtonsVariable-type> <SkipPictureCache>false</SkipPictureCache> <SkipPictureCache-type>java.lang.Boolean</SkipPictureCache-type> <SoundPath><null></SoundPath> <SoundPath-type>java.lang.String</SoundPath-type> <StatusBarIconString><null></StatusBarIconString> <StatusBarIconString-type>java.lang.String</StatusBarIconString-type> <StatusBarTextSize>16</StatusBarTextSize> <StatusBarTextSize-type>java.lang.String</StatusBarTextSize-type> <TextExpanded><null></TextExpanded> <TextExpanded-type>java.lang.String</TextExpanded-type> <Time><null></Time> <Time-type>java.lang.String</Time-type> <TimeFormat><null></TimeFormat> <TimeFormat-type>java.lang.String</TimeFormat-type> <Timeout><null></Timeout> <Timeout-type>java.lang.String</Timeout-type> <TitleExpanded><null></TitleExpanded> <TitleExpanded-type>java.lang.String</TitleExpanded-type> <UpdateNotification>false</UpdateNotification> <UpdateNotification-type>java.lang.Boolean</UpdateNotification-type> <UseChronometer>false</UseChronometer> <UseChronometer-type>java.lang.Boolean</UseChronometer-type> <UseHTML>false</UseHTML> <UseHTML-type>java.lang.Boolean</UseHTML-type> <Visibility><null></Visibility> <Visibility-type>java.lang.String</Visibility-type> <com.twofortyfouram.locale.intent.extra.BLURB>Title: my recording Action on Touch: stop recording Status Bar Text Size: 16 Id: my-recording Dismiss on Touch: true Priority: -1 Separator: ,</com.twofortyfouram.locale.intent.extra.BLURB> <com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type> <config_action_1_icon><null></config_action_1_icon> <config_action_1_icon-type>java.lang.String</config_action_1_icon-type> <config_action_2_icon><null></config_action_2_icon> <config_action_2_icon-type>java.lang.String</config_action_2_icon-type> <config_action_3_icon><null></config_action_3_icon> <config_action_3_icon-type>java.lang.String</config_action_3_icon-type> <config_action_4_icon><null></config_action_4_icon> <config_action_4_icon-type>java.lang.String</config_action_4_icon-type> <config_action_5_icon><null></config_action_5_icon> <config_action_5_icon-type>java.lang.String</config_action_5_icon-type> <config_notification_action>stop recording</config_notification_action> <config_notification_action-type>java.lang.String</config_notification_action-type> <config_notification_action_button1><null></config_notification_action_button1> <config_notification_action_button1-type>java.lang.String</config_notification_action_button1-type> <config_notification_action_button2><null></config_notification_action_button2> <config_notification_action_button2-type>java.lang.String</config_notification_action_button2-type> <config_notification_action_button3><null></config_notification_action_button3> <config_notification_action_button3-type>java.lang.String</config_notification_action_button3-type> <config_notification_action_button4><null></config_notification_action_button4> <config_notification_action_button4-type>java.lang.String</config_notification_action_button4-type> <config_notification_action_button5><null></config_notification_action_button5> <config_notification_action_button5-type>java.lang.String</config_notification_action_button5-type> <config_notification_action_label1><null></config_notification_action_label1> <config_notification_action_label1-type>java.lang.String</config_notification_action_label1-type> <config_notification_action_label2><null></config_notification_action_label2> <config_notification_action_label2-type>java.lang.String</config_notification_action_label2-type> <config_notification_action_label3><null></config_notification_action_label3> <config_notification_action_label3-type>java.lang.String</config_notification_action_label3-type> <config_notification_action_on_dismiss><null></config_notification_action_on_dismiss> <config_notification_action_on_dismiss-type>java.lang.String</config_notification_action_on_dismiss-type> <config_notification_action_share>false</config_notification_action_share> <config_notification_action_share-type>java.lang.Boolean</config_notification_action_share-type> <config_notification_command><null></config_notification_command> <config_notification_command-type>java.lang.String</config_notification_command-type> <config_notification_content_info><null></config_notification_content_info> <config_notification_content_info-type>java.lang.String</config_notification_content_info-type> <config_notification_dismiss_on_touch>true</config_notification_dismiss_on_touch> <config_notification_dismiss_on_touch-type>java.lang.Boolean</config_notification_dismiss_on_touch-type> <config_notification_icon><null></config_notification_icon> <config_notification_icon-type>java.lang.String</config_notification_icon-type> <config_notification_indeterminate_progress>false</config_notification_indeterminate_progress> <config_notification_indeterminate_progress-type>java.lang.Boolean</config_notification_indeterminate_progress-type> <config_notification_led_color><null></config_notification_led_color> <config_notification_led_color-type>java.lang.String</config_notification_led_color-type> <config_notification_led_off><null></config_notification_led_off> <config_notification_led_off-type>java.lang.String</config_notification_led_off-type> <config_notification_led_on><null></config_notification_led_on> <config_notification_led_on-type>java.lang.String</config_notification_led_on-type> <config_notification_max_progress><null></config_notification_max_progress> <config_notification_max_progress-type>java.lang.String</config_notification_max_progress-type> <config_notification_number><null></config_notification_number> <config_notification_number-type>java.lang.String</config_notification_number-type> <config_notification_persistent>true</config_notification_persistent> <config_notification_persistent-type>java.lang.Boolean</config_notification_persistent-type> <config_notification_picture><null></config_notification_picture> <config_notification_picture-type>java.lang.String</config_notification_picture-type> <config_notification_priority>-1</config_notification_priority> <config_notification_priority-type>java.lang.String</config_notification_priority-type> <config_notification_progress><null></config_notification_progress> <config_notification_progress-type>java.lang.String</config_notification_progress-type> <config_notification_subtext><null></config_notification_subtext> <config_notification_subtext-type>java.lang.String</config_notification_subtext-type> <config_notification_text><null></config_notification_text> <config_notification_text-type>java.lang.String</config_notification_text-type> <config_notification_ticker><null></config_notification_ticker> <config_notification_ticker-type>java.lang.String</config_notification_ticker-type> <config_notification_title>my recording</config_notification_title> <config_notification_title-type>java.lang.String</config_notification_title-type> <config_notification_url><null></config_notification_url> <config_notification_url-type>java.lang.String</config_notification_url-type> <config_notification_vibration><null></config_notification_vibration> <config_notification_vibration-type>java.lang.String</config_notification_vibration-type> <config_status_bar_icon><null></config_status_bar_icon> <config_status_bar_icon-type>java.lang.String</config_status_bar_icon-type> <net.dinglisch.android.tasker.RELEVANT_VARIABLES><StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%err Error Code Only available if you select &lt;b&gt;Continue Task After Error&lt;/b&gt; and the action ends in error</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%errmsg Error Message Only available if you select &lt;b&gt;Continue Task After Error&lt;/b&gt; and the action ends in error</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1></StringArray></net.dinglisch.android.tasker.RELEVANT_VARIABLES> <net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type> <net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>StatusBarTextSize config_notification_title config_notification_action notificaitionid config_notification_priority plugininstanceid plugintypeid </net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS> <net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type> <net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled> <net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type> <notificaitionid>my-recording</notificaitionid> <notificaitionid-type>java.lang.String</notificaitionid-type> <notificaitionsound><null></notificaitionsound> <notificaitionsound-type>java.lang.String</notificaitionsound-type> <plugininstanceid>9fca7d3a-cca6-4bfb-8ec4-a991054350c5</plugininstanceid> <plugininstanceid-type>java.lang.String</plugininstanceid-type> <plugintypeid>com.joaomgcd.autonotification.intent.IntentNotification</plugintypeid> <plugintypeid-type>java.lang.String</plugintypeid-type> </Vals> </Bundle> <Str sr="arg1" ve="3">com.joaomgcd.autonotification</Str> <Str sr="arg2" ve="3">com.joaomgcd.autonotification.activity.ActivityConfigNotify</Str> <Int sr="arg3" val="0"/> <Int sr="arg4" val="1"/> </Action> <Action sr="act11" ve="7"> <code>559</code> <Str sr="arg0" ve="3">Go</Str> <Str sr="arg1" ve="3">default:default</Str> <Int sr="arg2" val="3"/> <Int sr="arg3" val="5"/> <Int sr="arg4" val="5"/> <Int sr="arg5" val="1"/> <Int sr="arg6" val="0"/> <Int sr="arg7" val="0"/> </Action> <Action sr="act12" ve="7"> <code>455</code> <Str sr="arg0" ve="3">sync/recordings/%filename</Str> <Int sr="arg1" val="0"/> <Int sr="arg2" val="0"/> <Int sr="arg3" val="0"/> <Int sr="arg4" val="0"/> </Action> <Action sr="act13" ve="7"> <code>38</code> </Action> <Action sr="act2" ve="7"> <code>657</code> </Action> <Action sr="act3" ve="7"> <code>559</code> <Str sr="arg0" ve="3">Done</Str> <Str sr="arg1" ve="3">default:default</Str> <Int sr="arg2" val="3"/> <Int sr="arg3" val="5"/> <Int sr="arg4" val="5"/> <Int sr="arg5" val="1"/> <Int sr="arg6" val="0"/> <Int sr="arg7" val="0"/> </Action> <Action sr="act4" ve="7"> <code>2046367074</code> <Bundle sr="arg0"> <Vals sr="val"> <App><null></App> <App-type>java.lang.String</App-type> <CancelAll>false</CancelAll> <CancelAll-type>java.lang.Boolean</CancelAll-type> <CancelPersistent>false</CancelPersistent> <CancelPersistent-type>java.lang.Boolean</CancelPersistent-type> <CaseinsensitiveApp>false</CaseinsensitiveApp> <CaseinsensitiveApp-type>java.lang.Boolean</CaseinsensitiveApp-type> <CaseinsensitivePackage>false</CaseinsensitivePackage> <CaseinsensitivePackage-type>java.lang.Boolean</CaseinsensitivePackage-type> <CaseinsensitiveText>false</CaseinsensitiveText> <CaseinsensitiveText-type>java.lang.Boolean</CaseinsensitiveText-type> <CaseinsensitiveTitle>false</CaseinsensitiveTitle> <CaseinsensitiveTitle-type>java.lang.Boolean</CaseinsensitiveTitle-type> <ExactApp>false</ExactApp> <ExactApp-type>java.lang.Boolean</ExactApp-type> <ExactPackage>false</ExactPackage> <ExactPackage-type>java.lang.Boolean</ExactPackage-type> <ExactText>false</ExactText> <ExactText-type>java.lang.Boolean</ExactText-type> <ExactTitle>false</ExactTitle> <ExactTitle-type>java.lang.Boolean</ExactTitle-type> <InterceptApps><StringArray sr=""/></InterceptApps> <InterceptApps-type>[Ljava.lang.String;</InterceptApps-type> <InvertApp>false</InvertApp> <InvertApp-type>java.lang.Boolean</InvertApp-type> <InvertPackage>false</InvertPackage> <InvertPackage-type>java.lang.Boolean</InvertPackage-type> <InvertText>false</InvertText> <InvertText-type>java.lang.Boolean</InvertText-type> <InvertTitle>false</InvertTitle> <InvertTitle-type>java.lang.Boolean</InvertTitle-type> <OtherId><null></OtherId> <OtherId-type>java.lang.String</OtherId-type> <OtherPackage><null></OtherPackage> <OtherPackage-type>java.lang.String</OtherPackage-type> <OtherTag><null></OtherTag> <OtherTag-type>java.lang.String</OtherTag-type> <PackageName><null></PackageName> <PackageName-type>java.lang.String</PackageName-type> <RegexApp>false</RegexApp> <RegexApp-type>java.lang.Boolean</RegexApp-type> <RegexPackage>false</RegexPackage> <RegexPackage-type>java.lang.Boolean</RegexPackage-type> <RegexText>false</RegexText> <RegexText-type>java.lang.Boolean</RegexText-type> <RegexTitle>false</RegexTitle> <RegexTitle-type>java.lang.Boolean</RegexTitle-type> <Text><null></Text> <Text-type>java.lang.String</Text-type> <Title><null></Title> <Title-type>java.lang.String</Title-type> <com.twofortyfouram.locale.intent.extra.BLURB>Id: my-recording</com.twofortyfouram.locale.intent.extra.BLURB> <com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type> <net.dinglisch.android.tasker.RELEVANT_VARIABLES><StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%err Error Code Only available if you select &lt;b&gt;Continue Task After Error&lt;/b&gt; and the action ends in error</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%errmsg Error Message Only available if you select &lt;b&gt;Continue Task After Error&lt;/b&gt; and the action ends in error</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1></StringArray></net.dinglisch.android.tasker.RELEVANT_VARIABLES> <net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type> <net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>notificaitionid plugininstanceid plugintypeid </net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS> <net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type> <net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled> <net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type> <notificaitionid>my-recording</notificaitionid> <notificaitionid-type>java.lang.String</notificaitionid-type> <plugininstanceid>da51b00c-7f2a-483d-864c-7fee8ac384aa</plugininstanceid> <plugininstanceid-type>java.lang.String</plugininstanceid-type> <plugintypeid>com.joaomgcd.autonotification.intent.IntentCancelNotification</plugintypeid> <plugintypeid-type>java.lang.String</plugintypeid-type> </Vals> </Bundle> <Str sr="arg1" ve="3">com.joaomgcd.autonotification</Str> <Str sr="arg2" ve="3">com.joaomgcd.autonotification.activity.ActivityConfigCancelNotification</Str> <Int sr="arg3" val="0"/> <Int sr="arg4" val="1"/> </Action> <Action sr="act5" ve="7"> <code>43</code> </Action> <Action sr="act6" ve="7"> <code>394</code> <Bundle sr="arg0"> <Vals sr="val"> <net.dinglisch.android.tasker.RELEVANT_VARIABLES><StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%current_time 00. Current time </_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%dt_millis 1. MilliSeconds Milliseconds Since Epoch</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2>%dt_seconds 2. Seconds Seconds Since Epoch</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3>%dt_day_of_month 3. Day Of Month </_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4>%dt_month_of_year 4. Month Of Year </_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES5>%dt_year 5. Year </_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES5></StringArray></net.dinglisch.android.tasker.RELEVANT_VARIABLES> <net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type> </Vals> </Bundle> <Int sr="arg1" val="1"/> <Int sr="arg10" val="0"/> <Str sr="arg11" ve="3"/> <Str sr="arg12" ve="3"/> <Str sr="arg2" ve="3"/> <Str sr="arg3" ve="3"/> <Str sr="arg4" ve="3"/> <Str sr="arg5" ve="3">yyyy_MM_dd_HH_MM_SS</Str> <Str sr="arg6" ve="3"/> <Str sr="arg7" ve="3">current_time</Str> <Int sr="arg8" val="0"/> <Int sr="arg9" val="0"/> </Action> <Action sr="act7" ve="7"> <code>547</code> <Str sr="arg0" ve="3">%filename</Str> <Str sr="arg1" ve="3">%current_time.mp4</Str> <Int sr="arg2" val="0"/> <Int sr="arg3" val="0"/> <Int sr="arg4" val="0"/> <Int sr="arg5" val="3"/> <Int sr="arg6" val="1"/> </Action> <Action sr="act8" ve="7"> <code>547</code> <Str sr="arg0" ve="3">%RECORDING</Str> <Str sr="arg1" ve="3">1</Str> <Int sr="arg2" val="0"/> <Int sr="arg3" val="0"/> <Int sr="arg4" val="0"/> <Int sr="arg5" val="3"/> <Int sr="arg6" val="1"/> </Action> <Action sr="act9" ve="7"> <code>548</code> <Str sr="arg0" ve="3">%filename</Str> <Int sr="arg1" val="0"/> <Str sr="arg10" ve="3"/> <Int sr="arg11" val="1"/> <Int sr="arg12" val="0"/> <Str sr="arg13" ve="3"/> <Int sr="arg14" val="0"/> <Str sr="arg15" ve="3"/> <Int sr="arg2" val="0"/> <Str sr="arg3" ve="3"/> <Str sr="arg4" ve="3"/> <Str sr="arg5" ve="3"/> <Str sr="arg6" ve="3"/> <Str sr="arg7" ve="3"/> <Str sr="arg8" ve="3"/> <Int sr="arg9" val="1"/> </Action> </Task> </TaskerData>
Overall, next steps
It looks like there are plenty of things I can do by voice. If I can talk, then I can record a braindump. If I can't talk but I can listen to things, then Emacs TV might be a good choice. If I want to read, I can read webpages or e-books. If my hands are busy, I can still add items to my grocery list or my Orgzly notebook. I just need to practice.
I can experiment with ARIA labels or Web Speech API interfaces on a simpler website, since emacs.tv is a bit complicated. If that doesn't let me do the speech interfaces I'm thinking of, then I might need to look into making a simple Android app.
I'd like to learn more about Orgzly Revived intents. At some point, I should probably learn more about Android programming too. There are a bunch of tweaks I might like to make to Orgzly Revived and the Emacs port of Android.
Also somewhat tempted by the idea of adding voice control or voice input to Emacs and/or Linux. If I'm on my computer already, I can usually just type, but it might be handy for using it hands-free while I'm in the kitchen. Besides, exploring accessibility early will also probably pay off when it comes to age-related changes. There's the ffmpeg+Whisper approach, there's a more sophisticated dictation mode with a voice cursor, there are some tools for Emacs tools for working with Talon or Dragonfly… There's been a lot of work in this area, so I might be able to find something that fits.
Promising!