old语音识别科大讯飞+deepseek api
教程:(带源码)
https://blog.csdn.net/qq_38436214/article/details/106900471
使用科大讯飞旧版的链接
http://E:\teach\old\Android_iat1146_8ead105c
seepseek
好的,我现在需要帮助一个Android开发的新手,他们已经在应用中实现了语音识别,并将结果显示在界面上。现在他们想集成DeepSeek的API,将语音识别的文字发送给API,获取回答,并按要求显示在界面上。回答需要满足字数、语言风格和多轮对话形式的要求。我需要详细指导他们每一步该怎么做,包括代码和解释。
首先,用户使用的是Android Studio,Groovy DSL和Java。他们已经完成了语音识别部分,所以重点在集成API。我需要考虑以下几个步骤:
-
网络权限和依赖添加:确保AndroidManifest.xml有互联网权限,添加必要的依赖库,比如Retrofit或OkHttp来处理HTTP请求,可能还需要Gson来处理JSON数据。
-
多轮对话的消息管理:用户需要维护一个消息列表,每次发送新问题时,需要包含之前的对话历史。需要指导他们如何维护这个列表,确保每次请求都包含所有消息。
-
构建API请求:根据DeepSeek的API文档,构建正确的请求体,包括模型名称、消息列表、temperature等参数。需要确保用户正确设置API密钥的认证方式,比如在请求头中添加Authorization。
-
异步网络请求处理:在Android中,网络请求必须在后台线程执行,避免主线程阻塞。需要使用AsyncTask、RxJava、Coroutines或者简单的线程处理。考虑到用户是新手,可能AsyncTask或简单的Thread+Handler更合适。
-
处理API响应并更新UI:获取到API的响应后,解析出需要的回答内容,检查字数限制,确保语言风格,然后将回答添加到消息列表,并更新UI显示。
-
错误处理和用户体验:需要考虑网络错误、API返回错误等情况,给用户适当的提示,比如Toast或Snackbar。
现在,逐步分解:
第一步:添加依赖和权限
检查build.gradle中是否有Retrofit和Gson的依赖。用户可能不熟悉如何添加,需要详细说明在哪个模块的build.gradle,以及具体的依赖项。同时,确认AndroidManifest.xml有INTERNET权限。
第二步:创建API服务接口
使用Retrofit创建一个接口,定义POST请求到DeepSeek的API端点。需要包括请求头中的Authorization,以及请求体的结构。可能需要创建一个请求体类,包含model、messages等字段。
第三步:管理多轮对话消息
创建一个消息列表,每次用户说话后,添加用户消息到列表,发送请求,收到响应后添加助手消息到列表。需要指导用户如何维护这个列表,比如使用ArrayList,并在每次请求前确保包含所有历史消息。
第四步:发送请求和处理响应
在语音识别的回调中,获取用户输入,添加到消息列表,然后调用API。使用Retrofit的异步enqueue方法,或者在后台线程执行网络请求。处理响应后,解析数据,截断超过200字的部分,并更新UI。
第五步:UI更新和消息显示
在UI上显示对话历史,可能需要使用RecyclerView或简单的TextView追加。确保在主线程更新UI,比如使用runOnUiThread或Handler。
第六步:错误处理和测试
处理可能的异常,比如网络不可用、API密钥错误等,给出提示。测试不同情况下的应用表现,确保稳定性。
需要注意的潜在问题:
- API密钥的安全:避免硬编码在代码中,建议使用gradle.properties或其他安全方式。
- 消息列表的管理:防止内存泄漏,确保在配置更改时保存状态。
- 响应格式的解析:确保正确解析DeepSeek返回的JSON结构,可能需要创建对应的模型类。
- 字数限制的处理:在收到响应后,检查内容长度,超过200字时进行截断。
- 多线程的正确处理:确保网络请求不在主线程,UI更新在主线程。
需要详细解释每一步的代码,特别是Retrofit的配置、消息列表的管理和异步处理。用户可能对回调函数和线程切换不熟悉,需要简明扼要地说明。
以下是实现该功能的详细步骤及代码解释:
步骤一:添加网络权限和依赖库
- 在AndroidManifest.xml中添加网络权限:
xml
复制
<uses-permission android:name="android.permission.INTERNET" />
- 在app/build.gradle中添加依赖:
groovy
复制
dependencies { // Retrofit网络库 implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // Gson用于JSON解析 implementation 'com.google.code.gson:gson:2.8.9' }
步骤二:创建DeepSeek API请求模型类
在MainActivity.java
同级目录新建ApiRequest.java
:
java
复制
public class ApiRequest { private String model; private List<Message> messages; public ApiRequest(String model, List<Message> messages) { this.model = model; this.messages = messages; } public static class Message { private String role; private String content; public Message(String role, String content) { this.role = role; this.content = content; } } }
步骤三:配置Retrofit网络客户端
在MainActivity.java
中添加以下代码:
java
复制
public class MainActivity extends AppCompatActivity { private static final String BASE_URL = "https://api.deepseek.com"; private static final String API_KEY = "YOUR_API_KEY"; // 替换成你的API密钥 private List<ApiRequest.Message> messages = new ArrayList<>(); // 存储多轮对话历史 private Retrofit retrofit; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化Retrofit OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(chain -> { Request original = chain.request(); Request request = original.newBuilder() .header("Authorization", "Bearer " + API_KEY) .build(); return chain.proceed(request); }) .build(); retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build(); } }
步骤四:实现API调用方法
继续在MainActivity.java
中添加:
java
复制
private void callDeepSeekApi(String userInput) { // 添加用户消息到历史记录 messages.add(new ApiRequest.Message("user", userInput)); // 构建请求体 ApiRequest request = new ApiRequest("deepseek-chat", messages); // 创建API接口实例 DeepSeekApi api = retrofit.create(DeepSeekApi.class); Call<ResponseBody> call = api.getCompletion(request); // 异步请求 call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { try { if (response.isSuccessful() && response.body() != null) { // 解析JSON响应 String jsonResponse = response.body().string(); JSONObject jsonObject = new JSONObject(jsonResponse); String answer = jsonObject.getJSONArray("choices") .getJSONObject(0) .getJSONObject("message") .getString("content"); // 限制字数并添加换行符 answer = formatAnswer(answer); // 添加AI回复到历史记录 messages.add(new ApiRequest.Message("assistant", answer)); // 更新UI runOnUiThread(() -> updateChatDisplay(userInput, answer)); } } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { runOnUiThread(() -> Toast.makeText(MainActivity.this, "网络请求失败", Toast.LENGTH_SHORT).show()); } }); }
步骤五:创建API接口定义
新建DeepSeekApi.java
接口文件:
java
复制
public interface DeepSeekApi { @POST("/v1/chat/completions") Call<ResponseBody> getCompletion(@Body ApiRequest request); }
步骤六:实现回答格式化方法
java
复制
private String formatAnswer(String original) { // 限制200字符 if (original.length() > 200) { original = original.substring(0, 200) + "..."; } // 添加换行符(每50字符换行) StringBuilder formatted = new StringBuilder(); for (int i = 0; i < original.length(); i += 50) { int endIndex = Math.min(i + 50, original.length()); formatted.append(original.substring(i, endIndex)).append("\n"); } return formatted.toString(); }
步骤七:集成到语音识别回调
在你的语音识别成功回调处添加:
java
复制
@Override public void onSpeechResult(String recognizedText) { // 显示用户输入 TextView userText = findViewById(R.id.user_text); userText.setText(recognizedText); // 调用DeepSeek API callDeepSeekApi(recognizedText); }
步骤八:更新聊天显示界面
java
复制
private void updateChatDisplay(String userInput, String aiResponse) { TextView chatHistory = findViewById(R.id.chat_history); String formattedDialog = "[你] " + userInput + "\n" + "[AI助手] " + aiResponse + "\n\n"; chatHistory.append(formattedDialog); // 自动滚动到底部 final int scrollAmount = chatHistory.getLayout().getLineTop(chatHistory.getLineCount()) - chatHistory.getHeight(); if (scrollAmount > 0) { chatHistory.scrollTo(0, scrollAmount); } else { chatHistory.scrollTo(0, 0); } }
注意事项
-
API密钥保护:
- 不要硬编码在代码中,建议使用
BuildConfig
或gradle.properties - 在
app/build.gradle
中添加:groovy
复制
buildTypes.each { it.buildConfigField 'String', 'DEEPSEEK_API_KEY', "\"${your_api_key}\"" }
- 不要硬编码在代码中,建议使用
-
对话历史管理:
- 建议最多保留10轮对话,防止超过API token限制
- 添加清除历史按钮:
java
复制
public void onClearHistoryClick(View view) { messages.clear(); ((TextView)findViewById(R.id.chat_history)).setText(""); }
-
性能优化:
- 使用
RecyclerView
代替TextView
显示长对话 - 添加加载状态提示:
java
复制
private void showLoading() { findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); }
- 使用
最终效果
用户说话 → 显示识别文字 → 发送API请求 → 显示格式化的AI回复 → 自动滚动显示最新消息。每次对话都会携带完整上下文,实现自然的多轮对话体验。
遇到具体实现问题可以进一步询问!建议先从简单的文本交互开始测试,再集成语音功能。
一、代码架构分析
本代码实现了一个 集成语音识别 + AI对话的Android应用,采用 单Activity架构,主要包含以下模块:
模块 | 技术栈 | 功能说明 |
---|---|---|
语音识别模块 | 讯飞语音SDK (SpeechRecognizer) | 实现语音输入和识别 |
网络通信模块 | Retrofit2 + OkHttp3 | 处理与DeepSeek API的通信 |
对话管理模块 | List | 维护多轮对话历史记录 |
UI交互模块 | ViewBinding | 管理界面元素和用户交互 |
权限管理模块 | Android权限系统 | 动态申请录音、存储等敏感权限 |
二、核心功能流程
图片
代码
sequenceDiagram participant User as 用户 participant UI as 界面 participant SpeechSDK as 讯飞SDK participant DeepSeek as DeepSeek API User->>UI: 点击录音按钮 UI->>SpeechSDK: 启动语音识别 SpeechSDK-->>UI: 返回识别文本 UI->>DeepSeek: 发送用户输入 DeepSeek-->>UI: 返回AI回复 UI->>UI: 更新对话记录
DeepSeek API讯飞SDK界面用户DeepSeek API讯飞SDK界面用户点击录音按钮启动语音识别返回识别文本发送用户输入返回AI回复更新对话记录
三、逐行代码解析
1. 类定义与初始化部分
java
复制
public class MainActivity extends AppCompatActivity { // 使用ViewBinding替代findViewById private ActivityMainBinding binding; // 讯飞语音核心对象 private SpeechRecognizer mIat; private RecognizerDialog mIatDialog; // 存储多轮对话历史(关键数据结构) private List<ApiRequest.Message> messages = new ArrayList<>(); // Retrofit网络通信实例 private Retrofit retrofit; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); // 按钮点击事件绑定(Lambda表达式简化代码) binding.btnStart.setOnClickListener(v -> { // 异常处理:检查语音识别器是否初始化成功 if( null == mIat ){ showMsg("创建对象失败..."); return; } // 清空历史识别结果 mIatResults.clear(); // 配置语音识别参数 setParam(); // 显示语音识别对话框 mIatDialog.show(); }); // 初始化权限系统 initPermission(); // 创建讯飞语音识别器(工厂方法模式) mIat = SpeechRecognizer.createRecognizer(this, mInitListener); // 初始化带UI的语音对话框 mIatDialog = new RecognizerDialog(this, mInitListener); // 初始化Retrofit网络框架(重点配置) OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(chain -> { // 添加Authorization请求头(API密钥验证) Request request = chain.request().newBuilder() .header("Authorization", "Bearer " + API_KEY) .build(); return chain.proceed(request); }).build(); retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) // API基础地址 .client(client) // 注入自定义Client .addConverterFactory(GsonConverterFactory.create()) // JSON转换 .build(); } }
2. 语音识别模块
java
复制
// 初始化监听器(使用Lambda简化) private final InitListener mInitListener = code -> { Log.d(TAG, "初始化状态码: " + code); if (code != ErrorCode.SUCCESS) { showMsg("初始化失败,错误码:" + code); } }; // 语音识别结果监听器 private final RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() { @Override public void onResult(RecognizerResult results, boolean isLast) { // 解析JSON格式的识别结果 printResult(results); } @Override public void onError(SpeechError error) { // 显示友好错误提示 showMsg(error.getPlainDescription(true)); } }; // 参数配置方法(关键配置项) public void setParam() { // 清空旧参数 mIat.setParameter(SpeechConstant.PARAMS, null); // 设置云端识别引擎 mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); // 中文识别配置 mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); mIat.setParameter(SpeechConstant.ACCENT, "mandarin"); // 音频保存路径(需存储权限) mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav"); }
3. AI对话处理模块
java
复制
// 核心API调用方法 private void callDeepSeekApi(String userInput) { // 构建对话历史记录(遵循DeepSeek API格式) messages.add(new ApiRequest.Message("user", userInput)); ApiRequest request = new ApiRequest("deepseek-chat", messages); // 创建Retrofit接口实例 DeepSeekApi api = retrofit.create(DeepSeekApi.class); Call<ResponseBody> call = api.createChatCompletion(request); // 异步网络请求 call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { try { if (response.isSuccessful() && response.body() != null) { // 解析JSON响应(注意:此处建议使用Gson自动解析) String jsonResponse = response.body().string(); JSONObject jsonObject = new JSONObject(jsonResponse); String answer = jsonObject.getJSONArray("choices") .getJSONObject(0) .getJSONObject("message") .getString("content"); // 格式化回复内容 answer = formatAnswer(answer); // 维护对话历史(注意:需控制最大长度) messages.add(new ApiRequest.Message("assistant", answer)); // UI更新(必须切回主线程) runOnUiThread(() -> updateChatDisplay(userInput, answer)); } } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { // 网络错误处理 runOnUiThread(() -> Toast.makeText(MainActivity.this, "网络请求失败", Toast.LENGTH_SHORT).show()); } }); } // 文本格式化工具方法 private String formatAnswer(String original) { // 长度限制(防止过长文本影响显示) if (original.length() > 200) { original = original.substring(0, 200) + "..."; } // 自动换行处理(每50字符换行) StringBuilder formatted = new StringBuilder(); for (int i = 0; i < original.length(); i += 50) { int endIndex = Math.min(i + 50, original.length()); formatted.append(original, i, endIndex).append("\n"); } return formatted.toString(); }
4. UI更新模块
java
复制
// 语音识别结果处理方法 public void onSpeechResult(String recognizedText) { // 显示用户输入(建议改用ViewBinding) TextView userText = findViewById(R.id.user_text); userText.setText(recognizedText); // 触发AI对话流程 callDeepSeekApi(recognizedText); } // 对话记录更新方法 private void updateChatDisplay(String userInput, String aiResponse) { TextView chatHistory = findViewById(R.id.chat_history); // 构建格式化对话记录 String formattedDialog = "[你] " + userInput + "\n" + "[AI助手] " + aiResponse + "\n\n"; // 追加新对话(建议改用StringBuilder优化性能) chatHistory.append(formattedDialog); // 自动滚动到底部(提升用户体验) final int scrollAmount = chatHistory.getLayout().getLineTop(chatHistory.getLineCount()) - chatHistory.getHeight(); if (scrollAmount > 0) { chatHistory.scrollTo(0, scrollAmount); } }
四、程序完整简述
这是一个集成讯飞语音识别和DeepSeek大模型的智能对话应用,主要实现以下功能:
-
语音交互流程:
- 用户点击按钮启动语音识别
- 讯飞SDK进行实时语音转文字
- 识别结果通过DeepSeek API获取智能回复
- 对话记录实时更新显示
-
关键技术点:
- 使用
LinkedHashMap
存储语音分段识别结果 - 通过
Retrofit Interceptor
自动添加API密钥 - 采用
runOnUiThread
保证线程安全 - 实现多轮对话历史管理
- 使用
-
优化建议:
- 增加对话历史最大长度限制(防止内存溢出)
- 使用
Gson
替代手动JSON解析 - 将网络请求移至
ViewModel
中 - 添加加载状态提示(如ProgressBar)
-
扩展方向:
- 支持语音合成输出
- 添加本地对话记录存储
- 实现上下文敏感对话
- 支持多语言识别
该代码完整实现了从语音输入到智能输出的完整链路,可作为语音交互类应用的开发模板。