web-dev-qa-db-ja.com

AndroidでのAlwaysOnHotwordDetectorの例

Androidで新しいAlwaysOnHotwordDetectorクラスを使用する方法の例を誰かが提供できますか?

アプリをビルドしたいのですが、アプリがバックグラウンドで実行されているときに、「次へ」、「戻る」、「一時停止」などの起動ワードを検出できます。

30
Mark Rose

大きな盲点がない限り、サードパーティのアプリケーションがこのAPIを利用できるとは思いません。 AlwaysOnHotwordDetector(および関連クラスVoiceInteractionServiceなど)にパブリックアクセスが許可されているのは奇妙です。


特権アプリを構築している場合は、AOSPからこれらのテストプロジェクトを確認します。


これを機能させようとしているときに、私はこれに遭遇しました:

_AlwaysOnHotwordDetector's_コンストラクタ:

_/**
 * @param text The keyphrase text to get the detector for.
 * @param locale The Java locale for the detector.
 * @param callback A non-null Callback for receiving the recognition events.
 * @param voiceInteractionService The current voice interaction service.
 * @param modelManagementService A service that allows management of sound models.
 *
 * @hide
 */
public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback,
        KeyphraseEnrollmentInfo keyphraseEnrollmentInfo,
        IVoiceInteractionService voiceInteractionService,
        IVoiceInteractionManagerService modelManagementService) {
    mText = text;
    mLocale = locale;
    mKeyphraseEnrollmentInfo = keyphraseEnrollmentInfo;
    mKeyphraseMetadata = mKeyphraseEnrollmentInfo.getKeyphraseMetadata(text, locale);
    mExternalCallback = callback;
    mHandler = new MyHandler();
    mInternalCallback = new SoundTriggerListener(mHandler);
    mVoiceInteractionService = voiceInteractionService;
    mModelManagementService = modelManagementService;
    new RefreshAvailabiltyTask().execute();
}
_

ここで重要なステートメントは次のとおりです。

_mKeyphraseMetadata = mKeyphraseEnrollmentInfo.getKeyphraseMetadata(text, locale);
_

KeyphraseEnrollmentInfo#getKeyphraseMetadata(String, Locale)は何をしますか?

_/**
 * Gets the {@link KeyphraseMetadata} for the given keyphrase and locale, null if any metadata
 * isn't available for the given combination.
 *
 * @param keyphrase The keyphrase that the user needs to be enrolled to.
 * @param locale The locale for which the enrollment needs to be performed.
 *        This is a Java locale, for example "en_US".
 * @return The metadata, if the enrollment client supports the given keyphrase
 *         and locale, null otherwise.
 */
public KeyphraseMetadata getKeyphraseMetadata(String keyphrase, Locale locale) {
    if (mKeyphrases == null || mKeyphrases.length == 0) {
        Slog.w(TAG, "Enrollment application doesn't support keyphrases");
        return null;
    }
    for (KeyphraseMetadata keyphraseMetadata : mKeyphrases) {
        // Check if the given keyphrase is supported in the locale provided by
        // the enrollment application.
        if (keyphraseMetadata.supportsPhrase(keyphrase)
                && keyphraseMetadata.supportsLocale(locale)) {
            return keyphraseMetadata;
        }
    }
    Slog.w(TAG, "Enrollment application doesn't support the given keyphrase/locale");
    return null;
}
_

この時点で、私のサンプルプロジェクトは_Enrollment application doesn't support keyphrases_を教えてくれました。したがって、もう少し掘り下げます。キーフレーズをサポートするには、追加のメタデータを提供する必要があります。

_// Taken from class KeyphraseEnrollmentInfo
/**
 * Name under which a Hotword enrollment component publishes information about itself.
 * This meta-data should reference an XML resource containing a
 * <code>&lt;{@link
 * Android.R.styleable#VoiceEnrollmentApplication
 * voice-enrollment-application}&gt;</code> tag.
 */
private static final String VOICE_KEYPHRASE_META_DATA = "Android.voice_enrollment";
_

さらに、_Android.permission.MANAGE_VOICE_KEYPHRASES_権限が必要です。ここで、サンプルプロジェクトが行き詰まります。

_<!-- Must be required by hotword enrollment application,
     to ensure that only the system can interact with it.
     @hide <p>Not for use by third-party applications.</p> -->
<permission Android:name="Android.permission.MANAGE_VOICE_KEYPHRASES"
    Android:label="@string/permlab_manageVoiceKeyphrases"
    Android:description="@string/permdesc_manageVoiceKeyphrases"
    Android:protectionLevel="signature|system" />
_

起動ワードの検出をサポートするために必要な権限は、サードパーティのアプリケーションでは利用できません。それでも、パッケージ_Android.service.voice_パッケージがパブリックアクセス権を持っている理由がわかりません。おそらく私はここで何かを見逃している。

34
Vikram