HotwordDetector using VoiceInteractionService in android
Asked Answered
B

1

10

I am creating the voice recognition service like "Ok Google" with custom command. For this I have used the VoiceInteractionService and I refered the code from here. Also, I am getting the STATE_HARDWARE_UNAVAILABLE error in onAvailabilityChanged.

public class VoiceCommandService extends VoiceInteractionService {
private static final String TAG = "AlwaysOnHotwordDetector";
Locale locale = new Locale("en-US");
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;

public final Callback mHotwordCallback = new Callback() {
    @Override
    public void onAvailabilityChanged(int status) {
        Log.i(TAG, "onAvailabilityChanged(" + status + ")");
        hotwordAvailabilityChangeHelper(status);
    }

    @Override
    public void onDetected(EventPayload eventPayload) {
        Log.i(TAG, "onDetected");
    }

    @Override
    public void onError() {
        Log.i(TAG, "onError");
    }

    @Override
    public void onRecognitionPaused() {
        Log.i(TAG, "onRecognitionPaused");
    }

    @Override
    public void onRecognitionResumed() {
        Log.i(TAG, "onRecognitionResumed");
    }
};

private AlwaysOnHotwordDetector mHotwordDetector;

@Override
public void onCreate(){
    Log.d(TAG, "Entered on create");
    super.onCreate();
}

@Override
public void onReady() {
    super.onReady();
    Log.i(TAG, "Creating " + this);
    mHotwordDetector = createAlwaysOnHotwordDetector(
            "Hello", Locale.forLanguageTag("en-US"), mHotwordCallback);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Bundle args = new Bundle();
    args.putParcelable("intent", new Intent(this, MainActivity.class));
    showSession(args, 0);
    stopSelf(startId);
    return START_NOT_STICKY;
}

private void hotwordAvailabilityChangeHelper(int availability) {
    Log.i(TAG, "Hotword availability = " + availability);
    switch (availability) {
        case AlwaysOnHotwordDetector.STATE_HARDWARE_UNAVAILABLE:
            Log.i(TAG, "STATE_HARDWARE_UNAVAILABLE");
            break;
        case AlwaysOnHotwordDetector.STATE_KEYPHRASE_UNSUPPORTED:
            Log.i(TAG, "STATE_KEYPHRASE_UNSUPPORTED");
            break;
        case AlwaysOnHotwordDetector.STATE_KEYPHRASE_UNENROLLED:
            Log.i(TAG, "STATE_KEYPHRASE_UNENROLLED");
            Intent enroll = mHotwordDetector.createEnrollIntent();
            Log.i(TAG, "Need to enroll with " + enroll);
            break;
        case AlwaysOnHotwordDetector.STATE_KEYPHRASE_ENROLLED:
            Log.i(TAG, "STATE_KEYPHRASE_ENROLLED - starting recognition");
            if (mHotwordDetector.startRecognition(0)) {
                Log.i(TAG, "startRecognition succeeded");
            } else {
                Log.i(TAG, "startRecognition failed");
            }
            break;
    }
}}
Bathtub answered 12/4, 2017 at 14:3 Comment(9)
What mobile are you usingRumple
Using Moto X playBathtub
I am new to android. Is this correct way?Bathtub
Ever get this working?Ketcham
did you ever find an answer to this question ?Nightshade
STATE_HARDWARE_UNAVAILABLE comes when 1.) no dspModuleProperties are available for SoundTrigger service - usually missing sound triggers models too. 2.) Voice enrollment metadata is missing (system permission needed)Selfappointed
Aside from that class, which ones more do you have? All the others that are on the link? Could you post how you have them? (If you still remember and are reading.) I'm trying now a second time to do this, but I'm having some issues with old classes on that link, even though it's from Google.Finitude
@Selfappointed Would you know why it would complain about no DSP modules? Because the Google app works, so why doesn't mine? (or the OP's, or whoever's) I'm confused. Are you able to turn on a light around ahah? Also, do you know what is the DSP module they talk about? Not that it matters much, but I got curious. The main question is the other one, because I don't get it. I don't get why this doesn't work at all if the Google app does. Weird.Finitude
@DADi590 DSP modules are proprietary SoundTrigger AI speech/voice binary models to detect hotword sounds. Usually from Qualcomm (chipset) or Google. When doing custom VoiceInteractionService - some steps need to be done and checked -> custom keywords enrollment linked to DSP models, and/or SoundTrigger HAL update with audio device configurations of bus/channels (AudioFlinger). It is a low level platform thingy - nothing resolvable only via upper VoiceInteractorService.Selfappointed
K
0

VoiceInteractionService need android.permission.BIND_VOICE_INTERACTION in AndroidManifests

Knew answered 17/5, 2017 at 3:40 Comment(8)
Yes, I already used this permission android:permission="android.permission.BIND_VOICE_INTERACTION" in AndroidManifest.Bathtub
I don't know why but android is a bit strange. You can install the app with this permission as a normal app, but in real android didn't gave your app this permission. So you also have to install the App as System AppEros
@Eros Not really. This permission is to ensure only a package (app) with that permission can invoke the service. So not any app can bind to that service --> only the systemFinitude
@DADi590 I didn't understand your point?Eros
@Eros I mean you don't need to hold the permission for that to work. That's just an indicator that means that whoever wants to take control of the service must be holding that permission. So if I want to start that service, I must be a system app with the permission. Anyone else (even system apps) without that permission won't be able to control the service. You don't have to hold the permission. Someone else has to. It doesn't need to be a system permission though. You could want that the service is started by apps with INTERNET permission only or something. Hopefully it's better now?Finitude
So you say that the permission is not for my app to be able to use the service. It's for the app/service that starts my app to give me the permission to access the service?Eros
@Eros Sorry for the "delay"... Only noticed this now! (Because I'm after answers again, even though I advanced a bit on it, but not enough) Still not that ahah, but almost there. It's a way to ensure that only authorized apps can start your app (in this case, only an app that holds the BIND_VOICE_INTERACTION permission - your app or a component of it, like an activity, receiver or service). It doesn't grant you the permission nor you have to hold it. And it's the system that checks it. If the app attempting to start your app holds the permission, it can start it, else it won't be able toFinitude
@DADi590 also when configuring platform a default system role holder for assistant is to be in place - so that your custom VoiceInteractionService gets selectable via Settings by user - or is by default selected there.Selfappointed

© 2022 - 2024 — McMap. All rights reserved.