You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Voice Interactor运行时空指针异常问题求助

Android Voice Interactor 空指针问题排查求助

我正在Android项目里实现Voice Interactor功能,想让用户说出类似“Ok Google”的指令来唤起特定功能(比如导航)。照着教程写了代码后,运行时直接抛出Runtime Exception,下面是我的代码片段和错误信息,麻烦帮忙排查一下!

Manifest 文件

<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:largeHeap="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name="com.ivy.ivyvoicebot.MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.ivy.ivyvoicebot.MY_ACTION_INTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.VOICE" />
</intent-filter>
<intent-filter>
<action android:name="android.media.action.STILL_IMAGE_CAMERA"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.VOICE"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.VOICE"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="com.google.android.voicesearch.SELF_NOTE" />
</intent-filter>
</activity>
</application>

MainActivity 代码

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
startVoiceTrigger();
} else {
Toast.makeText(this, "Device not supported", Toast.LENGTH_SHORT).show();
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void startVoiceTrigger() {
VoiceInteractor.PickOptionRequest.Option option1 = new VoiceInteractor.PickOptionRequest.Option("cheese", 1);
option1.addSynonym("ready");
option1.addSynonym("go");
option1.addSynonym("take it");
option1.addSynonym("ok");
VoiceInteractor.Prompt prompt = new VoiceInteractor.Prompt("Say Cheese");
VoiceInteractor voiceInteractor = getVoiceInteractor();
voiceInteractor.submitRequest(new VoiceInteractor.PickOptionRequest(prompt, new VoiceInteractor.PickOptionRequest.Option[]{option1}, null) {
@Override
public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
if (finished && selections.length == 1) {
Message message = Message.obtain();
message.obj = result;
Toast.makeText(MainActivity.this, "Navigate To next screen", Toast.LENGTH_SHORT).show();
} else {
getActivity().finish();
}
}
@Override
public void onCancel() {
Toast.makeText(MainActivity.this, "Didn't work", Toast.LENGTH_SHORT).show();
getActivity().finish();
}
});
}
}

错误日志

2020-06-19 17:02:51.633 23588-23588/com.ivy.ivyvoicebot E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ivy.ivyvoicebot, PID: 23588
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ivy.ivyvoicebot/com.ivy.ivyvoicebot.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.app.VoiceInteractor.submitRequest(android.app.VoiceInteractor$Request)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3375)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3514)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2110)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7697)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.app.VoiceInteractor.submitRequest(android.app.VoiceInteractor$Request)' on a null object reference
at com.ivy.ivyvoicebot.MainActivity.startVoiceTrigger(MainActivity.java:259)
at com.ivy.ivyvoicebot.MainActivity.onCreate(MainActivity.java:85)
at android.app.Activity.performCreate(Activity.java:7815)
at android.app.Activity.performCreate(Activity.java:7804)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1325)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3350)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3514)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2110)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7697)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
2020-06-19 17:02:51.640 23588-23588/com.ivy.ivyvoicebot I/Process: Sending signal. PID: 23588 SIG: 9

问题分析和解决方案

核心问题:空指针的原因

你遇到的NullPointerException是因为getVoiceInteractor()返回了null!这里要注意:VoiceInteractor只有在你的Activity是通过语音交互系统启动的时候才会存在,如果是直接点击桌面图标打开Activity,这个对象就是null,自然调用submitRequest就会崩溃。

另外,你的代码里还有个小问题:在Activity中调用getActivity()是错误的(这是Fragment里的方法),应该换成MainActivity.this或者直接this,否则也会导致后续崩溃。

具体修复步骤

  1. 添加非空判断:在使用VoiceInteractor之前先检查是否为null,避免崩溃:
@RequiresApi(api = Build.VERSION_CODES.M)
private void startVoiceTrigger() {
    VoiceInteractor voiceInteractor = getVoiceInteractor();
    // 先判断VoiceInteractor是否存在
    if (voiceInteractor == null) {
        Toast.makeText(this, "请通过语音指令启动应用来使用此功能", Toast.LENGTH_LONG).show();
        return;
    }

    // 原来的代码继续
    VoiceInteractor.PickOptionRequest.Option option1 = new VoiceInteractor.PickOptionRequest.Option("cheese", 1);
    option1.addSynonym("ready");
    option1.addSynonym("go");
    option1.addSynonym("take it");
    option1.addSynonym("ok");
    VoiceInteractor.Prompt prompt = new VoiceInteractor.Prompt("Say Cheese");
    
    voiceInteractor.submitRequest(new VoiceInteractor.PickOptionRequest(prompt, new VoiceInteractor.PickOptionRequest.Option[]{option1}, null) {
        @Override
        public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
            if (finished && selections.length == 1) {
                Message message = Message.obtain();
                message.obj = result;
                Toast.makeText(MainActivity.this, "Navigate To next screen", Toast.LENGTH_SHORT).show();
            } else {
                // 替换getActivity()为MainActivity.this
                MainActivity.this.finish();
            }
        }
        @Override
        public void onCancel() {
            Toast.makeText(MainActivity.this, "Didn't work", Toast.LENGTH_SHORT).show();
            // 同样替换getActivity()
            MainActivity.this.finish();
        }
    });
}
  1. 正确启动方式:要测试VoiceInteractor功能,你不能直接点击图标打开App,而是需要通过语音指令触发,比如对着手机说“Ok Google,启动IvyVoiceBot”或者对应你Manifest里注册的action指令(比如“Ok Google,拍照”对应STILL_IMAGE_CAMERA的action),这样启动的Activity才会持有有效的VoiceInteractor对象。

  2. 关于唤醒词的补充:如果你想实现自定义的唤醒词(比如自己的“Ok Ivy”),VoiceInteractor是做不到的,它只是用于语音启动后的交互环节。自定义唤醒词需要借助Google Assistant的App Actions,或者自己实现持续音频监听(但后者会有耗电和系统权限限制的问题,不推荐)。


内容的提问来源于stack exchange,提问作者Anish Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:42:46