百度文心一言(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.mzph.cn/news/766683.shtml

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

相关文章

spring boot dynamic 动态数据数据源配置连接池

前言 我们可以使用 dynamic-datasource 来快速实现多数据源&#xff0c;但是多数据源配置连接池 以及说明文档都是收费的。 这里整理的连接池的配置以及配置说明 连接池配置 &#xff08;druid或者 hikari 选择一个即可&#xff09; 特此说明 如果配置配到了 spring.datasour…

RabbitMQ如何实现延迟消息?

RabbitMQ如何实现延迟消息&#xff1f; RabbitMQ中是可以实现延迟消息的&#xff0c;一般有两种方式&#xff0c;分别是通过死信队列以及通过延迟消息插件来实现。 死信队列 当RabbitMQ中的一条正常的消息&#xff0c;因为过了存活时间&#xff08;TTL过期&#xff09;、队列长…

(使用C语言详解)求一个集合的全部子集(leetcode编程笔记)

原题链接&#xff1a;子集 (Subsets) - 力扣 (LeetCode) 原码于文章末尾会给出。 本文通过位运算&#xff0c;实现题目要求&#xff0c;之后可能更新其他方法&#xff0c;敬请关注...... 题目&#xff1a; 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该…

C++类的6个默认成员函数(构造)

C类和对象基础-CSDN博客https://blog.csdn.net/lh11223326/article/details/136834917?spm1001.2014.3001.5501 目录 1.构造函数 概念 特性 2.析构函数 概念 特性 3.拷贝构造函数 概念 特征 4.赋值运算符重载&#xff08;构造实现&#xff09; 运算符重载 赋值运算…

Kafka快速入门及使用

入门 官网 简介 Kafka是一个分布式的流媒体平台应用&#xff1a; 消息系统日志收集用户行为追踪流式处理 特点 高吞吐量消息持久化高可靠性高扩展性 常用术语 Broker&#xff1a;集群中的服务器Zookeeper&#xff1a;服务管理Topic&#xff1a;主题&#xff0c;Kafka发…

Linux/openEuler系统部署spring boot+vue前后端分离项目(nginx均衡代理)

Linux/openEuler系统部署spring bootvue前后端分离项目&#xff08;nginx均衡代理&#xff09; 1、系统环境准备&#xff0c;安装openjdk和nginx还有MySQL&#xff0c;咱们本文先连接主机mysql进行登录&#xff08;linux上的mysql服务可以先不安装&#xff09; 可以看我前面的…

springboot精品源码

springboot精品源码 所有项目都包括&#xff1a;源码数据库文件开题LW说明文档运行视频 请看主页资料联系。 项目类型包括: 1 SpringBoot学生心理咨询评估系统 2 基于SpringBoot的网上订餐系统 3 大学生租房平台的设计与实现 4 SpringBoot房屋租赁系统 5 基于SpringBoot的课…

SpringCloud之网关组件Gateway学习

SpringCloud之网关组件Gateway学习 GateWay简介 Spring Cloud Gateway是Spring Cloud的⼀个全新项目&#xff0c;目标是取代Netflix Zuul&#xff0c;它基于Spring5.0SpringBoot2.0WebFlux&#xff08;基于高性能的Reactor模式响应式通信框架Netty&#xff0c;异步⾮阻塞模型…

STM32---DHT11温湿度传感器与BH1750FVI光照传感器(HAL库、含源码)

写在前面&#xff1a;本节我们学习使用两个常见的传感器模块&#xff0c;分别为DHT11温湿度传感器以及BH1750FVI光照传感器,这两种传感器在对于环境监测中具有十分重要的作用&#xff0c;因为其使用简单方便&#xff0c;所以经常被用于STM32的项目之中。今天将使用分享给大家&a…

QGIS编译(跨平台编译)057:FastCGI编译(Windows、Linux、MacOS环境下编译)

文章目录 1、FastCGI介绍2、FastCGI下载3、Windows下编译4、linux下编译5、MacOS下编译1、FastCGI介绍 FCGI 是 FastCGI 的缩写,是一种用于改善 CGI(Common Gateway Interface)性能的协议。在传统的 CGI 中,每次请求都需要启动一个新的进程来处理,这导致了较高的资源消耗和…

【测试思考】设计测试用例时,你在想什么

突然想写这篇文章是因为&#xff0c;前两天看到一篇文章【像用户一样测试】 然后想起事儿 .. 想到在2020年上海爆发疫情后&#xff0c;开始频繁使用买菜软件&#xff0c;在一个深夜从某团紧急挑选加购商品&#xff0c;看到提醒自己账户还有一张满减优惠券&#xff0c;挺高兴的…

claude3国内怎么用

你是否苦恼没有渠道接触最牛的AI——Claude3&#xff0c;这个已经被媒体刷屏的彻底吊打了ChatGPT-4的地表最强AI。 最近&#xff0c;一个国内的claude3镜像站出现了&#xff0c;国内的小伙伴也可以体验了。 无论你用它写文案、做PPT、写代码、调bug、还是画图&#xff0c;都不…

【Linux】调试器-gdb的安装与使用

1. 背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须在源代码生成二进制程序的时候, 加上 -g 选项 GDB的安装 在开始之前&#xff0c;确保已经安装了GDB。如果没有安…

Android 观察者模式

在Android中&#xff0c;观察者模式&#xff08;Observer Pattern&#xff09;是一种常用的设计模式&#xff0c;用于在对象之间建立一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。在Android开发中&#xff0…

HTML5和CSS3笔记

一&#xff1a;网页结构(html)&#xff1a; 1.1&#xff1a;页面结构&#xff1a; 1.2&#xff1a;标签类型&#xff1a; 1.2.1&#xff1a;块标签&#xff1a; 1.2.2&#xff1a;行内标签&#xff1a; 1.2.3&#xff1a;行内块标签&#xff1a; 1.2.4&#xff1a;块标签与行…

独孤思维:流量暴涨,却惨遭违规

最近独孤操作虚拟资料短视频&#xff0c;有个很深的感悟。 每天发10条短视频&#xff0c;积累到20天左右&#xff0c;播放量和粉丝数开始暴涨。 虽然很多牛比的比我数据好&#xff0c;但是对于刚做短视频的独孤来说&#xff0c;我已经满足了。 但是又发了10来天&#xff0c;…

如何用VSCode和Clangd与Clang-Format插件高效阅读Linux内核源码及写驱动

一、如何高效阅读Linux源码&#xff1a;基于clangd uboot/busybox等都可以用这种方式&#xff0c;理论上说所有基于Make和Cmake的源码工程都可以用这套方案 阅读Linux源码最大问题在于调用链太复杂&#xff0c;一个函数或变量引用太多&#xff0c;source insight和cscope等基于…

Pink老师Echarts教学笔记

可视化面板介绍 ​ 应对现在数据可视化的趋势&#xff0c;越来越多企业需要在很多场景(营销数据&#xff0c;生产数据&#xff0c;用户数据)下使用&#xff0c;可视化图表来展示体现数据&#xff0c;让数据更加直观&#xff0c;数据特点更加突出。 01-使用技术 完成该项目需…

阿里云服务器(Ubuntu22)上的MySQL8数据库下载,安装和远程连接

最近阿里云centos主机到期了改为使用Ubuntu操作系统&#xff0c;在上面安装mysql并远程连接出现了一系列问题并解决。 之前在centos系统上下载mysql8的教程如下&#xff1a; 阿里云服务器&#xff08;centos7&#xff09;上的MySQL8数据库下载&#xff0c;安装和远程连接 主机操…

rollup打包起手式

使用Rollup打包JavaScript rollup是一款小巧的javascript模块打包工具&#xff0c;更适合于库应用的构建工具;可以将小块代码编译成大块复杂的代码&#xff0c;基于ES6 modules,它可以让你的 bundle 最小化&#xff0c;有效减少文件请求大小,vue在开发的时候用的是webpack,但是…