I got Voice Input feature working.
To handle VoiceBegin, you have to first listen for a RemoteVoiceBegin message from the TV device. This message is sent in response to sending KEYCODE_SEARCH (84) to initiate the search.
The RemoteVoiceBegin message from the device contains a session_id and a package name, but only the session_id needs to be read, as it will be used in subsequent calls to VoiceBegin, VoicePayload, and VoiceEnd.
Upon receiving the RemoteVoiceBegin, a RemoteVoiceBegin message must be sent back with just the session_id. This step is necessary to enable the reception of Payload messages afterward.