百度文心一言(ERNIE bot)API接入Android应用

百度文心一言(ERNIE bot)API接入Android应用实践 - 拾一贰叁 - 博客园 (cnblogs.com)

Preface:

现在生成式AI越来越强大了,想在android上实现一个对话助手的功能,大概摸索了一下接入百度文心一言API的方法。

与AI助手交换信息的方式可以这么理解:

我向文心一言发送一个message:你好啊:

[{"role": "user","content": "你好啊"}
]

文心一言回答我:你好,很高兴与你交流。请问你有什么具体的问题或需要帮助吗?我会尽力回答你的问题或与你对话:

{"id":"as-n24a5sytuz","object":"chat.completion","created":1711203238,"result":"你好,请问有什么我可以帮助你的吗?如果你有任何问题或需要帮助,请随时告诉我,我会尽力回答和提供帮助。","is_truncated":false,"need_clear_history":false,"finish_reason":"normal","usage":{"prompt_tokens":1,"completion_tokens":28,"total_tokens":29}
}

接着我继续发送message:今天是几号呢?......

[{"role": "user","content": "你好啊"},{"role": "assistant","content": "你好,很高兴与你交流。请问你有什么具体的问题或需要帮助吗?我会尽力回答你的问题或与你对话。"},{"role": "user","content": "今天是几号呢"}
]

每一次发送message,都要带上之前的对话,这样才能实现连续对话的功能。

 具体实现

在Android应用的AndroidManifest.xml文件中添加网络访问权限:

<uses-permission android:name="android.permission.INTERNET" />

在build.gradle中添加必要的依赖:

implementation 'com.squareup.okhttp3:okhttp:4.9.3'

 接下来注册开发者账户、往里边充钱啥的,完成这些之后,在百度智能云控制台 (baidu.com)创建一个新应用,

如上图所示,我们主要需要API Key和Secret Key这俩东西

创建一个新的类以处理文心一言的API信息:WenXin.java,在Activity里需要实现文心一言的对话功能只需调用这个类就好了。

package com.example.wearespeakers;import android.view.View;
import com.google.gson.Gson;
import okhttp3.*;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;import java.io.*;/**主要用于实现对接文心一言API的功能*/
public class WenXin{public static final String APP_ID = "56****59";//这个似乎还用不到public static final String API_KEY = "oQtU**********wePzF";//填你自己应用的apikeypublic static final String SECRET_KEY = "LxfNE*************W2UW0eX";//填你自己应用的secretkeypublic JSONArray Dialogue_Content;//用来储存对话内容,当然初始是空的WenXin(){//构造函数,先初始化Dialogue_Content一下,此时里边是空的啥也没有//不过也可以预先添加对话,以实现一些希望的业务功能Dialogue_Content=new JSONArray();}static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();public String GetAnswer(String user_msg) throws IOException, JSONException {JSONObject jsonObject = new JSONObject();jsonObject.put("role", "user");jsonObject.put("content", user_msg);// 将JSONObject添加到JSONArray中//这里就是把用户说的话添加进对话内容里,然后发给文心一言Dialogue_Content.put(jsonObject);MediaType mediaType = MediaType.parse("application/json");//这是一行参考代码,只能进行一次对话,要想多次对话就必须动态添加历史对话的内容//RequestBody body = RequestBody.create(mediaType,  "{\"messages\":[{\"role\":\"user\",\"content\":\"你好啊\"}],\"disable_search\":false,\"enable_citation\":false}");RequestBody body = RequestBody.create(mediaType,  "{\"messages\":" +Dialogue_Content.toString() +",\"disable_search\":false,\"enable_citation\":false}");Request request = new Request.Builder().url("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=" +getAccessToken()).method("POST", body).addHeader("Content-Type", "application/json").build();Response response = HTTP_CLIENT.newCall(request).execute();//解析出文心一言的回答JSONObject json_feedback = new JSONObject(response.body().string());//这里在开发的时候遇到了一个问题,注意response在上一行被取出里边的内容之后就自动关闭了,不能多次传参。String re=json_feedback.getString("result");//接下来把文心一言的回答加入到Dialogue_Content中JSONObject jsontmp=new JSONObject();jsontmp.put("assistant",re);Dialogue_Content.put(jsontmp);return re;}/*** 从用户的AK,SK生成鉴权签名(Access Token)** @return 鉴权签名(Access Token)* @throws IOException IO异常*/public String getAccessToken() throws IOException, JSONException {MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY+ "&client_secret=" + SECRET_KEY);Request request = new Request.Builder().url("https://aip.baidubce.com/oauth/2.0/token").method("POST", body).addHeader("Content-Type", "application/x-www-form-urlencoded").build();Response response = HTTP_CLIENT.newCall(request).execute();return new JSONObject(response.body().string()).getString("access_token");}
}

在Activity中是这样写的(Activity里的RecyclerView对话界面参考Android RecyclerView的使用(以实现一个简单的动态聊天界面为例),下边大多数都是无关的代码,主要就那几行):

package com.example.wearespeakers;
import android.app.Activity;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static java.security.AccessController.getContext;//此activity主要用来实现聊天界面
public class ChatActivity extends Activity {private EditText et_chat;private Button btn_send,btn_chat_return;private ChatlistAdapter chatAdapter;private List<Chatlist> mDatas;private RecyclerView rc_chatlist;final int MESSAGE_UPDATE_VIEW = 1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_chat);init();//聊天信息mDatas = new ArrayList<Chatlist>();Chatlist C1;C1=new Chatlist("ABC:","Hello,world!");mDatas.add(C1);Chatlist C2;C2=new Chatlist("DEF:","This is a new app.");mDatas.add(C2);//可以通过数据库插入数据chatAdapter=new ChatlistAdapter(this,mDatas);LinearLayoutManager layoutManager = new LinearLayoutManager(this );rc_chatlist.setLayoutManager(layoutManager);//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能rc_chatlist.setHasFixedSize(true);//创建并设置Adapterrc_chatlist.setAdapter(chatAdapter);//点击btn_send发送聊天信息btn_send.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//用户的提问String user_ask=et_chat.getText().toString();//获取输入框里的信息Chatlist C3;C3=new Chatlist("User:",user_ask);mDatas.add(C3);chatAdapter.ResetChatlistAdapter(mDatas);rc_chatlist.setAdapter(chatAdapter);//文心一言的回答(以下才是用到WenXin.java的地方)new Thread(new Runnable(){@Overridepublic void run() {//请求详情Chatlist C4;try {WenXin wx=new WenXin();C4=new Chatlist("WenXin:",wx.GetAnswer(user_ask));} catch (IOException | JSONException e) {throw new RuntimeException(e);} finally {}mDatas.add(C4);chatAdapter.ResetChatlistAdapter(mDatas);Message msg = new Message();msg.what = MESSAGE_UPDATE_VIEW;ChatActivity.this.gHandler.sendMessage(msg);}}).start();/*为什么要弄new Thread...这样呢?因为像这种网络请求往往有延迟,需要新开一个进程去处理,与下面的gHandler相对应当app收到来自文心一言的回答后,就去通知gHandler更新界面,把回答的段落显示出来*/}});//点击返回,返回mainActivitybtn_chat_return.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent=new Intent(ChatActivity.this,MainActivity.class);startActivity(intent);ChatActivity.this.finish();}});}private void init(){//执行一些初始化操作btn_send=findViewById(R.id.btn_send);et_chat=findViewById(R.id.et_chat);btn_chat_return=findViewById(R.id.btn_chat_return);rc_chatlist=(RecyclerView) findViewById(R.id.rc_chatlist);}public Handler gHandler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {if (msg.what == MESSAGE_UPDATE_VIEW) {rc_chatlist.setAdapter(chatAdapter);//更新对话界面}}};}

其实只需要关注new Thread和gHandler部分的代码即可。

效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/284612.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库索引

目录 索引的概念 索引的作用 索引的副作用 创建索引的原则 适合建索引的场景 索引的创建方式 查看索引 索引的分类 1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引 删除索引 索引的概念 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和…

【Codesys】DINT类型环形计数处理,计数到2的64次方

最近有遇到编码器计数的计数处理&#xff0c;抓取编码器锁存的数值只能在DINT类型范围内&#xff0c;是从-2147483648到2147483647数值&#xff0c;但是现场会有正向多圈的情况。此时需要记录这个数的位置值。就需要记录多圈计数下&#xff0c;圈数的处理。 PROGRAM FB_DintCir…

python闭包详解(实例)

“闭包”这个词语相信大多数学过编程的同学并不陌生&#xff0c;但是有时候理解起来还是有一定难度。 先看定义&#xff1a;闭包是由函数和与其相关的引用环境组合而成的实体。比如参考资源中就有这样的的定义&#xff1a;在实现深约束时&#xff0c;需要创建一个能显式表示引…

外包干了4年,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入杭州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

抖音视频批量下载软件可导出视频分享链接|手机网页视频提取|视频爬虫采集工具

解锁抖音视频无水印批量下载新姿势&#xff01; 在快节奏的生活中&#xff0c;抖音作为时下最热门的短视频平台之一&#xff0c;吸引着广大用户的目光。而如何高效地获取喜欢的视频内容成为了许多人关注的焦点。Q:290615413现在&#xff0c;我们推出的抖音视频批量下载软件&…

c语言——通讯录(文件版)

大家好我是小锋&#xff0c;今天我们来实现一个通讯录 准备工作 为了让我们的代码具有条理我们要建立三个文件一个文件用来放头文件一个文件用来放函数的实现&#xff0c;一个文件用来实现通讯录的基本逻辑。 然后我们其他的.c文件要使用头文件时我们要用# include<tongxu…

【Linux】进程管理

目录 一、进程创建 二、进程等待 1. 阻塞等待 2. 非阻塞等待 3. status位图 三、进程替换 1. exec* 系列函数 2. 高级语言程序替换 一、进程创建 进程是操作系统进程资源分配的最小单位&#xff0c;每一个进程都有自己独立的PID&#xff0c;以及进程控制块PCB。 父进…

【SAP-ABAP】CO01保存时错误DBSQL_DUPLICATE_KEY_ERROR

找到该表的主键OBJNR&#xff0c;事务代码SM56中查看当前缓冲到该key的号码段&#xff0c;事务代码SNRO修改对象名称OBJNR编号范围状态。 事务代码SM13查看数据更新记录

数据可视化-ECharts Html项目实战(5)

在之前的文章中&#xff0c;我们学习了如何设置滚动图例&#xff0c;工具箱设置和插入图片。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢 数据可视化-ECharts…

nodejs社区垃圾分类管理平台的设计与实现python-flask-django-php

近些年来&#xff0c;随着科技的飞速发展&#xff0c;互联网的普及逐渐延伸到各行各业中&#xff0c;给人们生活带来了十分的便利&#xff0c;社区垃圾分类管理平台利用计算机网络实现信息化管理&#xff0c;使整个社区垃圾分类管理的发展和服务水平有显著提升。 语言&#xf…

qt 实现 轮播图效果,且还有 手动 上一页和下一页 已解决

QT中有 轮播图的需求&#xff0c;按照正常html版本 。只需要配置数组就能搞定&#xff0c;但是c qt版本 应该用什么了。 第一想到的是采用定时器。 // 定时器初始化{m_pTime new QTimer(this);m_pTime->start(4 * 1000);//启动定时器并设置播放时间间隔m_pAutoFlag true;/…

vs2019新建Qt工程中双击 .ui 文件无法打开

vs2019 中创建的 Qt 工程&#xff0c;在使用的过程中&#xff0c;经常会有&#xff1a;双击 .ui 文件&#xff0c;闪退的情况&#xff0c;也即 .ui 文件无法打开&#xff01; 针对该问题的详细解决步骤如下&#xff1a; 1、右击该 .ui 文件&#xff0c;选择“打开方式” 2、…

②零基础MySQL数据库-MySQL约束

作用 表在设计的时候加入约束的目的就是为了保证表中的记录完整性和有效性&#xff0c;比如用户表有些列的值&#xff08;手机号&#xff09;不能为空&#xff0c;有些列的值&#xff08;身份证号&#xff09;不能重复 分类 主键约束(primary key) PK 自增长约束(auto_increme…

是德科技keysight DSOX3024T示波器

181/2461/8938产品概述&#xff1a; DSOX3024T 示波器 要特性与技术指标 使用电容触摸屏进行简洁的触控操作&#xff1a; •提高调试效率 •触控设计可以简化文档记录 •使用起来就像您喜欢的智能手机或平板电脑一样简单 使用 MegaZoom IV 技术揭示偶发异常&#xff1a; •超快…

rpc详解rpc框架

文章目录 概述rpc的优点组件工作流程&RPC的底层原理RPC的底层原理 RPC框架rpc框架优点RPC 的实现基础RPC的应用场景RPC使用了哪些关键技术rpc 调用异常一般怎么处理rpc和http的区别为什么RPC要比HTTP更快一些Dubbo和openfeign 区别远程调用RPC框架传输协议传输速度 概述 在…

135. 分发糖果(力扣LeetCode)

文章目录 135. 分发糖果题目描述贪心算法代码如下 总结 135. 分发糖果 题目描述 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩…

my2sql —— go语言版binlog解析及闪回工具

之前学习过python语言版binlog解析及闪回工具 MySQL闪回工具简介 及 binlog2sql工具用法 最近听同事介绍有了新的go语言版的my2sql。优点是不需要安装一大堆依赖包&#xff0c;直接可以安装使用&#xff0c;并且解析更高效&#xff0c;试用一下。 一、 下载安装 1. 软件下载 …

【原理图PCB专题】Cadence 17.4 配置Capture.ini让CIS数据库界面查看PCB封装

在CIS数据库中,如果进行了正确配置是可以查看原理图符号库与PCB封装库的。如下所示: 看到封装库的意义在于一个原理图封装是可以对应多个PCB封装的,如同一个原理图座子,对应了侧插或是竖插,那在没有PCB封装的时候,我们只能通过去看详细资料来判断。如果有PCB封装显示,只…

设计模式-访问者(Visitor)模式详解和应用

文章目录 前言访问者模式介绍结构包含的角色应用场景代码示例访问者模式的扩展访问者模式优缺点总结 前言 最近在做一个根据数学表达式生成java执行代码的功能&#xff0c;其中用到了访问者模式。使我对访问者模式有了更深入的理解。故写下此篇文章分享出来&#xff0c;不足之…

IPV6协议之RIPNG

目录 前言&#xff1a; 一、RIPNG与RIP的区别 二、如何配置RIPNG 如何解决RIPNG环路问题呢&#xff1f; 控制RIPNG的选路 1、修改RIPNG默认优先级 2.配置接口附加开销值从而干涉RIPNG的选路 RIPNG拓展配置 1.RIPNG的认证 配置RIPNG进程下的IPsec认证&#xff1a; 配…