打通“科大讯飞插件asr”到“辅助点击功能”的流程
参考前一篇:AccessibilityService可见即可说方案对比-CSDN博客
基于前面创建AccessibilityVoiceCtrlService类,需要把asr VoiceRecognitionService获取的热词传递给AccessibilityVoiceCtrlService。
现在的设计是main activity创建时启动了asr的语音服务VoiceRecognitionService和辅助服务AccessibilityVoiceCtrlService,前者会监控语音输入,转换为热词,后者会监控界面,实时获取所有view节点的文本。前者将获取的热词,传递给后者,触发模拟点击操作。
抽象场景为一个service与另一个service通讯。
安卓系统中会有多个进程,每个进程都是相互独立的,无法共享内存。想要共享进程间的数据,就需要进程通信,AIDL即为IPC机制(跨进程通信)的一种。
注意点:
-
AccessibilityService本身不是一个服务端,而是一个客户端,用于监听和响应用户界面的事件。 -
AccessibilityService作为一个系统服务,其接口onBind不能重载,所以只能作客户端。 -
VoiceRecognitionService监听语音输入,将语音转化为字符串。属于自定义的service,可以作服务端。
-
一般用法是客户端给服务端发消息,而这里需要AIDL服务端VoiceRecognitionService主动给客户端AccessibilityVoiceCtrlService发消息,可以用AIDL Callback来实现。
AIDL接口配置步骤:
1、确保 AIDL 文件放在 src/main/aidl/<your_package_name> 目录下,与接口声明的包名一致。
2、检查 AIDL 文件的 import 语句,确保导入路径正确。



3、在 build.gradle 文件中确保有以下配置:
android {
...
sourceSets {
main {
aidl.srcDirs = ['src/main/aidl']
}
}
...
}
4、java文件中,import <your_package_name>.<aidl接口名>;
5、客户端
import com.example.helloworld.AvcAidlInterface;
import com.example.helloworld.AvcAidlCallbackInterface;
import com.example.helloworld.VoiceRecognitionService;
public class AccessibilityVoiceCtrlService extends AccessibilityService {
private AvcAidlInterface myAidlInterface;
private final ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myAidlInterface = AvcAidlInterface.Stub.asInterface(service);
try {
myAidlInterface.registerCallback(callback, "connect to AIDL server!!!");
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
myAidlInterface = null;
}
};
private final AvcAidlCallbackInterface.Stub callback = new AvcAidlCallbackInterface.Stub() {
@Override
public boolean hitHotWord(String hotWord) {
// 处理接收到的消息
return handlePerformActionByHotWord(hotWord);
}
};
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "---AccessibilityVoiceCtrlService onCreate");
Intent intent = new Intent(this, VoiceRecognitionService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(serviceConnection);
}
。。。。。。
6、服务端
public class VoiceRecognitionService extends Service {
private static final String TAG = VoiceRecognitionService.class.getSimpleName();
private AvcAidlCallbackInterface avcCallback = null;
private final AvcAidlInterface.Stub binder = new AvcAidlInterface.Stub() {
@Override
public void registerCallback(AvcAidlCallbackInterface callback, String desc) throws RemoteException {
Log.d(TAG, "---AIDL method called!" + desc);
avcCallback = callback;
}
};
@Override
public IBinder onBind(Intent intent) {
return binder;
}
。。。。。。
业务调用点举例:
if (avcCallback != null) {
if (avcCallback.hitHotWord(keyword)) {
Log.d(TAG, "---hit word, direct return");
break;
}
}
测试能看到handlePerformActionByHotWord里日志,表示调用流程是通畅的,后面就是调整业务了。
更多推荐


所有评论(0)