Merge "Create SampleVisualQueryDetectionService"
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
|
||||
<application android:label="@string/app_name">
|
||||
<profileable android:shell="true"/>
|
||||
<activity android:name=".MainActivity">
|
||||
<activity android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
@@ -12,7 +13,8 @@
|
||||
<service
|
||||
android:name=".SampleVoiceInteractionService"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_VOICE_INTERACTION">
|
||||
android:permission="android.permission.BIND_VOICE_INTERACTION"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.voice.VoiceInteractionService" />
|
||||
</intent-filter>
|
||||
@@ -26,6 +28,12 @@
|
||||
android:isolatedProcess="true"
|
||||
android:exported="true">
|
||||
</service>
|
||||
<service
|
||||
android:name=".SampleVisualQueryDetectionService"
|
||||
android:permission="android.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE"
|
||||
android:isolatedProcess="true"
|
||||
android:exported="true">
|
||||
</service>
|
||||
</application>
|
||||
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
setup:
|
||||
|
||||
(If a log error "VisualQueryDetector is only available if multiple detectors are allowed" , set target_sdk_version: "10000" in Android.bp for now.)
|
||||
1. Set the KEYPHRASE constant in SampleVoiceInteractionService.java to something the device's
|
||||
default assistant supports.
|
||||
2. m -j SampleVoiceInteractor
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:sessionService=""
|
||||
android:hotwordDetectionService="com.example.android.voiceinteractor.SampleHotwordDetectionService"
|
||||
android:visualQueryDetectionService="com.example.android.voiceinteractor.SampleVisualQueryDetectionService"
|
||||
android:recognitionService=""
|
||||
android:settingsActivity=""
|
||||
android:supportsAssist="true"
|
||||
android:supportsLocalInteraction="true" />
|
||||
android:supportsLocalInteraction="true" />
|
||||
@@ -54,7 +54,7 @@ public class MainActivity extends Activity {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.mDetector.startRecognition();
|
||||
mService.mHotwordDetector.startRecognition();
|
||||
} catch (HotwordDetector.IllegalDetectorStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public class MainActivity extends Activity {
|
||||
Log.e(TAG, "No service");
|
||||
return;
|
||||
}
|
||||
mService.mCallback.onDetected(mService.mLastPayload, true);
|
||||
mService.mHotwordDetectorCallback.onDetected(mService.mLastPayload, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.voiceinteractor;
|
||||
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.SharedMemory;
|
||||
import android.service.voice.VisualQueryDetectionService;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
public class SampleVisualQueryDetectionService extends VisualQueryDetectionService {
|
||||
static final String TAG = "SVisualQueryDetectionSrvc";
|
||||
|
||||
@Override
|
||||
public void onUpdateState(@Nullable PersistableBundle options,
|
||||
@Nullable SharedMemory sharedMemory, long callbackTimeoutMillis,
|
||||
@Nullable IntConsumer statusCallback) {
|
||||
Log.i(TAG, "onUpdateState");
|
||||
if (statusCallback != null) {
|
||||
statusCallback.accept(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import android.service.voice.AlwaysOnHotwordDetector.EventPayload;
|
||||
import android.service.voice.HotwordDetector;
|
||||
import android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
import android.service.voice.HotwordRejectedResult;
|
||||
import android.service.voice.VisualQueryDetector;
|
||||
import android.service.voice.VoiceInteractionService;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -42,6 +43,7 @@ import androidx.annotation.NonNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
public static final String DSP_MODEL_KEYPHRASE = "X Google";
|
||||
@@ -56,8 +58,10 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
|
||||
private final IBinder binder = new LocalBinder();
|
||||
|
||||
HotwordDetector mDetector;
|
||||
Callback mCallback;
|
||||
HotwordDetector mHotwordDetector;
|
||||
VisualQueryDetector mVisualQueryDetector;
|
||||
Callback mHotwordDetectorCallback;
|
||||
VisualQueryDetector.Callback mVisualQueryDetectorCallback;
|
||||
Bundle mData = new Bundle();
|
||||
AudioFormat mAudioFormat;
|
||||
EventPayload mLastPayload;
|
||||
@@ -94,9 +98,12 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
public void onReady() {
|
||||
super.onReady();
|
||||
Log.i(TAG, "onReady");
|
||||
mCallback = new Callback();
|
||||
mDetector = createAlwaysOnHotwordDetector(DSP_MODEL_KEYPHRASE, DSP_MODEL_LOCALE, null, null,
|
||||
mCallback);
|
||||
mHotwordDetectorCallback = new Callback();
|
||||
mVisualQueryDetectorCallback = new VisualQueryDetectorCallback();
|
||||
mHotwordDetector = createAlwaysOnHotwordDetector(DSP_MODEL_KEYPHRASE, DSP_MODEL_LOCALE, null, null,
|
||||
mHotwordDetectorCallback);
|
||||
mVisualQueryDetector = createVisualQueryDetector(null, null,
|
||||
Executors.newSingleThreadExecutor(), mVisualQueryDetectorCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,6 +119,38 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
}
|
||||
}
|
||||
|
||||
static class VisualQueryDetectorCallback implements VisualQueryDetector.Callback {
|
||||
@Override
|
||||
public void onQueryDetected(@NonNull String partialQuery) {
|
||||
Log.i(TAG, "VQD partial query detected: "+ partialQuery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryRejected() {
|
||||
Log.i(TAG, "VQD query rejected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryFinished() {
|
||||
Log.i(TAG, "VQD query finished");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVisualQueryDetectionServiceInitialized(int status) {
|
||||
Log.i(TAG, "VQD init: "+ status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVisualQueryDetectionServiceRestarted() {
|
||||
Log.i(TAG, "VQD restarted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
Log.i(TAG, "VQD error");
|
||||
}
|
||||
};
|
||||
|
||||
class Callback extends AlwaysOnHotwordDetector.Callback {
|
||||
|
||||
private boolean mAvailable = false;
|
||||
@@ -131,7 +170,7 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
if (status == STATE_KEYPHRASE_UNENROLLED) {
|
||||
Intent enrollIntent = null;
|
||||
try {
|
||||
enrollIntent = ((AlwaysOnHotwordDetector) mDetector).createEnrollIntent();
|
||||
enrollIntent = ((AlwaysOnHotwordDetector) mHotwordDetector).createEnrollIntent();
|
||||
} catch (IllegalDetectorStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -152,7 +191,7 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
@Override
|
||||
public void onRejected(@NonNull HotwordRejectedResult result) {
|
||||
try {
|
||||
mDetector.startRecognition();
|
||||
mHotwordDetector.startRecognition();
|
||||
} catch (IllegalDetectorStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -198,7 +237,7 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
record.getState());
|
||||
Log.e(TAG, "Failed to init first AudioRecord.");
|
||||
try {
|
||||
mDetector.startRecognition();
|
||||
mHotwordDetector.startRecognition();
|
||||
} catch (IllegalDetectorStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -231,7 +270,7 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
mLastPayload = eventPayload;
|
||||
|
||||
try {
|
||||
mDetector.startRecognition();
|
||||
mHotwordDetector.startRecognition();
|
||||
} catch (IllegalDetectorStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -241,7 +280,7 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
public void onError() {
|
||||
Log.i(TAG, "onError");
|
||||
try {
|
||||
mDetector.startRecognition();
|
||||
mHotwordDetector.startRecognition();
|
||||
} catch (IllegalDetectorStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -263,7 +302,7 @@ public class SampleVoiceInteractionService extends VoiceInteractionService {
|
||||
+ ". mAvailable=" + mAvailable);
|
||||
if (mAvailable) {
|
||||
try {
|
||||
mDetector.startRecognition();
|
||||
mHotwordDetector.startRecognition();
|
||||
} catch (IllegalDetectorStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user