基于deepseek的Android智能问答助手

06-01 1081阅读

1、项目背景

        在数字化时代的浪潮中,信息的快速获取与精准处理成为人们日常工作和生活的迫切需求。人工智能技术的蓬勃发展,尤其是大语言模型的出现,彻底改变了人类与信息交互的方式。大语言模型凭借其强大的自然语言理解和生成能力,能够快速、准确地理解用户的问题,并从海量知识储备中提取有效信息,生成高质量的回答,为用户提供高效、智能的问答服务。​

        与此同时,移动互联网的普及使得智能手机成为人们获取信息的主要终端。安卓系统以其开源性、广泛的设备兼容性和庞大的用户基数,占据了全球移动操作系统市场的重要份额。然而,目前安卓应用市场中,虽然存在着各式各样的问答类应用,但大多功能较为单一,缺乏基于前沿大模型技术的深度整合,难以满足用户日益多样化和复杂化的问答需求。​

        本项目旨在开发一款安卓平台上基于大模型 API 的问答助手,将大模型强大的智能问答能力与安卓系统的便捷性、灵活性相结合。通过该应用,用户能够在移动端随时随地获取快速、准确、个性化的问题解答,无论是学习、工作中的专业知识查询,还是日常生活中的各类疑问求解,都能得到高效响应。项目的开展不仅有助于提升用户在移动端的信息获取体验,也将推动大模型技术在移动应用领域的深度应用与创新发展,为安卓生态系统注入新的活力。

2、实现思路

        在核心架构层面,采用经典的 MVC 模式,将数据模型、视图和控制器分离,通过 Activity 高效处理 UI 逻辑,确保界面交互流畅;运用 SQLite 数据库实现用户数据、会话记录和聊天消息的持久化存储,保障信息安全与可追溯性;设计抽象基类实现多 AI 模型支持,为接入更多先进 AI 模型奠定基础,满足用户多样化的交互需求。​

        功能模块上,构建了完善的用户认证系统,涵盖登录与注册功能,有效保障用户账号安全与隐私;支持 DeepSeek V3/R1 和 Qwen 3 等三种 AI 模型,用户可按需切换,获取不同风格与侧重的回答;会话管理功能支持创建新会话、查看历史会话,方便用户管理聊天记录,延续对话思路;消息持久化机制自动将聊天记录保存至本地数据库,避免信息丢失。​

        技术实现上,借助 AsyncTask 实现异步 API 调用,确保网络通信高效且不阻塞主线程,提升应用响应速度;通过专门设计的数据库管理类管理 SQLite 数据库,优化数据存储与读取操作;在 UI 交互方面,由特定 Activity 组件集中处理用户输入,并实时展示聊天内容,打造便捷直观的交互体验。​

        应用的数据流设计科学合理,从用户输入问题开始,经模型选择、API 调用获取答案,再到响应处理、数据存储,最后完成 UI 更新,形成闭环流程。同时,项目采用模块化设计,各功能组件高度解耦,新增 AI 模型只需继承抽象基类并实现对应方法,数据库表结构也充分考虑多用户多会话场景,极大提升了项目的扩展性与维护性,为后续功能迭代与优化提供有力支撑 。

3、技术工具

- Android SDK: 34 (Android 14)

- Gradle: 8.6

- Android Gradle Plugin: 8.2.2

- Java: 1.8

4、核心实现过程

4.1、聊天页面

        页面代码过长,此处不予展示。

基于deepseek的Android智能问答助手

4.2、 聊天代码后端逻辑

public class ChatActivity extends AppCompatActivity {
    // 定义UI组件
    private Spinner modelSpinner; // 模型选择下拉框
    private ListView chatListView; // 聊天内容列表视图
    private EditText messageEditText; // 输入消息的编辑框
    private ImageButton sendButton; // 发送消息按钮
    private TextView introTextView; // 欢迎信息文本视图
    private Button newSessionButton; // 创建新会话按钮
    private Button historyButton; // 查看历史会话按钮
    // 定义数据结构
    private List chatMessages; // 存储聊天消息的列表
    private ArrayAdapter adapter; // 用于聊天列表视图的适配器
    private BaseModel currentModel; // 当前选择的模型
    private UserDatabaseHelper dbHelper; // 数据库辅助工具类
    private String username; // 用户名
    private int userId; // 用户ID
    private long currentSessionId; // 当前会话ID
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat); // 设置布局文件
        // 初始化UI组件
        modelSpinner = findViewById(R.id.modelSpinner);
        chatListView = findViewById(R.id.chatListView);
        messageEditText = findViewById(R.id.messageEditText);
        sendButton = findViewById(R.id.sendButton);
        introTextView = findViewById(R.id.introTextView);
        newSessionButton = findViewById(R.id.newSessionButton);
        historyButton = findViewById(R.id.historyButton);
        // 初始化聊天消息列表和适配器
        chatMessages = new ArrayList();
        adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, chatMessages);
        chatListView.setAdapter(adapter);
        // 初始化数据库辅助工具和获取用户信息
        dbHelper = new UserDatabaseHelper(this);
        username = getIntent().getStringExtra("USERNAME");
        userId = dbHelper.getUserId(username);
        // 设置UI组件
        setupModelSpinner(); // 设置模型选择下拉框
        setupSendButton(); // 设置发送消息按钮
        setupNewSessionButton(); // 设置创建新会话按钮
        setupHistoryButton(); // 设置查看历史会话按钮
        startNewSession(); // 开始新会话
    }
    private void setupModelSpinner() {
        String[] models = {"DeepSeek V3", "DeepSeek R1", "Qwen 3"}; // 模型列表
        ArrayAdapter spinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, models);
        modelSpinner.setAdapter(spinnerAdapter); // 设置适配器
        // 监听模型选择变化
        modelSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id) {
                switch (position) {
                    case 0:
                        currentModel = new DeepSeekV3Model(); // 选择DeepSeek V3模型
                        break;
                    case 1:
                        currentModel = new DeepSeekR1Model(); // 选择DeepSeek R1模型
                        break;
                    case 2:
                        currentModel = new Qwen3Model(); // 选择Qwen 3模型
                        break;
                }
            }
            @Override
            public void onNothingSelected(AdapterView parent) {
                // 当没有选择任何项时,不做任何操作
            }
        });
        currentModel = new DeepSeekV3Model(); // 默认选择DeepSeek V3模型
    }
    private void setupSendButton() {
        sendButton.setOnClickListener(v -> { // 设置发送按钮点击事件
            String userInput = messageEditText.getText().toString(); // 获取用户输入的消息
            if (!userInput.isEmpty()) { // 如果用户输入不为空
                chatMessages.add("You: " + userInput); // 将用户消息添加到聊天列表
                adapter.notifyDataSetChanged(); // 更新UI显示
                messageEditText.setText(""); // 清空输入框
                // 添加思考中提示
                int thinkingIndex = chatMessages.size();
                chatMessages.add("AI: 思考中...");
                adapter.notifyDataSetChanged();
                // 在新线程中处理AI回复
                new Thread(() -> {
                    String response = currentModel.getResponse(userInput); // 获取AI回复
                    runOnUiThread(() -> { // 切换到主线程更新UI
                        // 替换思考中提示为实际回复
                        chatMessages.set(thinkingIndex, "AI: " + response);
                        adapter.notifyDataSetChanged();
                        // 如果是第一条消息,则创建会话
                        if (currentSessionId == -1) {
                            String sessionName = userInput.length() > 10 ? userInput.substring(0, 10) : userInput; // 使用用户输入的前10个字符作为会话名
                            currentSessionId = dbHelper.addSession(userId, sessionName); // 创建会话并获取会话ID
                        }
                        // 将消息保存到数据库
                        dbHelper.addMessage(currentSessionId, userInput, true); // 保存用户消息
                        dbHelper.addMessage(currentSessionId, response, false); // 保存AI回复
                    });
                }).start();
            }
        });
    }
    private void setupNewSessionButton() {
        newSessionButton.setOnClickListener(v -> { // 设置创建新会话按钮点击事件
            startNewSession(); // 开始新会话
        });
    }
    private void setupHistoryButton() {
        historyButton.setOnClickListener(v -> { // 设置查看历史会话按钮点击事件
            showHistoryDialog(); // 显示历史会话对话框
        });
    }
    private void startNewSession() {
        messageEditText.setText(""); // 清空消息输入框
        chatMessages.clear(); // 清空聊天消息列表
        adapter.notifyDataSetChanged(); // 更新UI显示
        introTextView.setVisibility(View.VISIBLE); // 显示欢迎信息
        currentSessionId = -1; // 初始化为-1表示未创建会话
    }
    private void showHistoryDialog() {
        List sessions = dbHelper.getSessionsForUser(userId); // 获取用户的所有会话
        final String[] sessionArray = sessions.toArray(new String[0]); // 将会话列表转换为数组
        // 创建对话框构建器
        android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
        builder.setTitle("历史会话:"); // 设置对话框标题
        // 设置对话框选项
        builder.setItems(sessionArray, (dialog, which) -> {
            String selectedSessionName = sessionArray[which]; // 获取选中的会话名
            loadSession(selectedSessionName); // 加载选中的会话
        });
        // 设置取消按钮
        builder.setNegativeButton("取消", (dialog, which) -> dialog.dismiss()); // 取消按钮点击事件
        // 设置清空历史按钮
        builder.setNeutralButton("清空历史", (dialog, which) -> {
            dbHelper.clearAllSessions(userId); // 清空所有会话
            Toast.makeText(this, "已清空所有历史会话", Toast.LENGTH_SHORT).show(); // 显示提示信息
        });
        builder.show(); // 显示对话框
    }
    private void loadSession(String sessionName) {
        List messages = dbHelper.getMessagesForSession(getSessionIdByName(sessionName)); // 获取会话中的所有消息
        chatMessages.clear(); // 清空当前聊天消息列表
        chatMessages.addAll(messages); // 将获取的消息添加到聊天消息列表
        adapter.notifyDataSetChanged(); // 更新UI显示
        introTextView.setVisibility(View.GONE); // 隐藏欢迎信息
    }
    private long getSessionIdByName(String sessionName) {
        SQLiteDatabase db = dbHelper.getReadableDatabase(); // 获取可读数据库实例
        String[] columns = {UserDatabaseHelper.COLUMN_SESSION_ID}; // 要查询的列
        String selection = UserDatabaseHelper.COLUMN_SESSION_NAME + "=?"; // 查询条件
        String[] selectionArgs = {sessionName}; // 查询条件参数
        // 执行查询
        Cursor cursor = db.query(UserDatabaseHelper.TABLE_SESSIONS, columns, selection, selectionArgs, null, null, null);
        long sessionId = -1; // 默认会话ID为-1
        if (cursor.moveToFirst()) { // 如果查询结果不为空
            sessionId = cursor.getLong(cursor.getColumnIndexOrThrow(UserDatabaseHelper.COLUMN_SESSION_ID)); // 获取会话ID
        }
        cursor.close(); // 关闭游标
        db.close(); // 关闭数据库
        return sessionId; // 返回会话ID
    }
}

4.3、模型调用API示例代码

public class DeepSeekV3Model extends BaseModel {
    // API 密钥,用于身份验证,请替换为你的密钥
    private static final String API_KEY = "your_key";
    // API 的 URL 地址,请替换为你的url
    private static final String API_URL = "your_url";
    // 连接超时时间(单位:毫秒)
    private static final int CONNECT_TIMEOUT = 150000;
    // 读取超时时间(单位:毫秒)
    private static final int READ_TIMEOUT = 150000;
    /**
     * 重写 BaseModel 类的 getResponse 方法,通过异步任务与 AI 模型进行交互。
     * @param input 用户输入的内容
     * @return AI 模型返回的响应内容
     */
    @SuppressLint("StaticFieldLeak")
    @Override
    public String getResponse(String input) {
        final String[] result = {null}; // 存储 AI 模型返回的结果
        new AsyncTask() {
            /**
             * 在后台线程中执行 HTTP 请求。
             * @param params 用户输入的内容
             * @return AI 模型返回的响应内容
             */
            @Override
            protected String doInBackground(String... params) {
                try {
                    URL url = new URL(API_URL); // 创建 URL 对象
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 打开 HTTP 连接
                    connection.setRequestMethod("POST"); // 设置请求方法为 POST
                    connection.setRequestProperty("Content-Type", "application/json"); // 设置请求内容类型为 JSON
                    connection.setRequestProperty("Authorization", "Bearer " + API_KEY); // 设置请求头中的授权信息
                    connection.setConnectTimeout(CONNECT_TIMEOUT); // 设置连接超时时间
                    connection.setReadTimeout(READ_TIMEOUT); // 设置读取超时时间
                    connection.setDoOutput(true); // 允许输出
                    // 构建请求体
                    String requestBody = String.format("{\"model\":\"deepseek-ai/DeepSeek-V3\",\"messages\":[{\"role\":\"user\",\"content\":\"%s\"}]}", params[0]);
                    OutputStream os = connection.getOutputStream(); // 获取输出流
                    os.write(requestBody.getBytes()); // 写入请求体
                    os.flush(); // 刷新输出流
                    os.close(); // 关闭输出流
                    int responseCode = connection.getResponseCode(); // 获取响应码
                    if (responseCode == HttpURLConnection.HTTP_OK) { // 如果响应码为 200
                        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); // 读取响应内容
                        String inputLine;
                        StringBuilder response = new StringBuilder(); // 构建响应字符串
                        while ((inputLine = in.readLine()) != null) {
                            response.append(inputLine); // 逐行读取并拼接响应内容
                        }
                        in.close(); // 关闭输入流
                        try {
                            JSONObject jsonResponse = new JSONObject(response.toString()); // 将响应内容解析为 JSON 对象
                            JSONArray choices = jsonResponse.getJSONArray("choices"); // 获取 choices 数组
                            if (choices.length() > 0) { // 如果 choices 数组不为空
                                JSONObject firstChoice = choices.getJSONObject(0); // 获取第一个 choice 对象
                                JSONObject message = firstChoice.getJSONObject("message"); // 获取 message 对象
                                return message.getString("content"); // 返回 message 中的 content 字段
                            }
                            return "No response content found"; // 如果 choices 数组为空,返回提示信息
                        } catch (Exception e) {
                            e.printStackTrace(); // 打印异常信息
                            return "Error parsing response: " + e.getMessage(); // 返回错误信息
                        }
                    } else {
                        return "Error: " + responseCode; // 返回错误响应码
                    }
                } catch (Exception e) {
                    e.printStackTrace(); // 打印异常信息
                    return "Error: " + e.getMessage(); // 返回错误信息
                }
            }
            /**
             * 在主线程中执行,将后台线程的执行结果赋值给 result。
             * @param response 后台线程返回的响应内容
             */
            @Override
            protected void onPostExecute(String response) {
                result[0] = response; // 将响应结果赋值给 result
            }
        }.execute(input); // 执行异步任务
        // 等待后台线程完成并返回结果
        while(result[0] == null) {
            try {
                Thread.sleep(100); // 每 100 毫秒检查一次结果是否已返回
            } catch (InterruptedException e) {
                e.printStackTrace(); // 打印异常信息
            }
        }
        return result[0]; // 返回最终结果
    }
}

5、整体功能展示

        下图分别是登录/注册界面、聊天界面、历史会话界面。

基于deepseek的Android智能问答助手基于deepseek的Android智能问答助手基于deepseek的Android智能问答助手

!!!若需要源码或定制化开发可后台联系我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码