基于百度AI--理解与交互技术UNIT,实现聊天机器人

前言:用过苹果和三星的小伙伴们,肯定对其中的语音助手 Siri 和 Bixby一定不陌生,今天我们基于百度AI技术,一起来实现这个功能。

效果图:

百度AI文档说明连接:http://ai.baidu.com/docs#/UNIT-v2-service-API/top

第一步:获取Access_token:

public class AuthService {

    /**
     * 获取权限token
     */
    public static String getAuth() {
        // 官网获取的 API Key 更新为你注册的
        String clientId = "百度ai申请的API Key";
        // 官网获取的 Secret Key 更新为你注册的
        String clientSecret = "百度ai申请的Secret Key";
        return getAuth(clientId, clientSecret);
    }

    /**
     * 获取API访问token
     * 该token有一定的有效期,需要自行管理,当失效时需重新获取.
     *
     * @param ak - 百度云官网获取的 API Key
     * @param sk - 百度云官网获取的 Securet Key
     * @return assess_token 示例:
     * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
     */
    public static String getAuth(String ak, String sk) {
        // 获取token地址
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost
                // 1. grant_type为固定参数
                + "grant_type=client_credentials"
                // 2. 官网获取的 API Key
                + "&client_id=" + ak
                // 3. 官网获取的 Secret Key
                + "&client_secret=" + sk;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.err.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String result = "";
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            /**
             * 返回结果示例
             */
            System.err.println("result:" + result);
            JSONObject jsonObject = new JSONObject(result);
            String access_token = jsonObject.getString("access_token");
            return access_token;
        } catch (Exception e) {
            System.err.printf("获取token失败!");
            e.printStackTrace(System.err);
        }
        return null;
    }

}

第二步:调用请求接口,获取反馈结果:

public class UnitService {
    /**
     * 重要提示代码中所需工具类
     * FileUtil,Base64Util,HttpUtil,GsonUtils请从
     * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
     * https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
     * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
     * https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
     * 下载
     */

    /**
     *
     * @参数一 具体可以参考百度官方说明
     * @参数二 你提出的问题 (不能为空)
     */
    public static String utterance(String session_id, String query) {

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("log_id", "UNITTEST_10000");  //参数说明,具体可以参考百度官方说明
            jsonObject.put("version", "2.0");
            jsonObject.put("service_id", "S15007");
            jsonObject.put("session_id", session_id);
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("query", query);
            jsonObject1.put("user_id", "88888");
            jsonObject.put("request", jsonObject1);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        String string = jsonObject.toString();
        System.out.println("获取到的json: " + string);

        // 请求URL
        String talkUrl = "https://aip.baidubce.com/rpc/2.0/unit/service/chat";
        try {
            // 请求参数
            String accessToken = AuthService.getAuth();
            String result = HttpUtil.post(talkUrl, accessToken, "application/json", string);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getIMEI(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
        String imei = telephonyManager.getDeviceId();

        return imei;
    }
}

通过以上两步,基本实现了功能,下面我们来实现对话聊天框的实现:

原理分析:基于RecycleView 来实现这个功能, 对于提问方和回答方给出两个不同的type来判断

具体实现代码如下:

页面布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/rl_title"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:background="@color/btn_background">

        <TextView
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:text="小沐"
            android:textColor="@color/white"
            android:textSize="18dp"/>

    </RelativeLayout>

    <Button
        android:id="@+id/btn_speech"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_margin="5dp"
        android:text="按住说话"/>


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/btn_speech"
        android:layout_below="@id/rl_title"
        android:orientation="vertical">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_show"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <RelativeLayout
            android:id="@+id/rl_show"
            android:layout_width="180dp"
            android:layout_height="180dp"
            android:layout_centerInParent="true"
            android:background="@color/gray2"
            android:visibility="gone">

            <ImageButton
                android:id="@+id/iv_show"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:background="@mipmap/ease_record_animate_01"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/iv_show"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="20dp"
                android:text="手指松开,录音结束"
                android:textColor="@color/black"
                android:textSize="16sp"/>

        </RelativeLayout>
    </RelativeLayout>
</RelativeLayout>

主要业务代码:

private void initView() {
        mRl_show = (RelativeLayout) findViewById(R.id.rl_show);
        mIv_show = (ImageButton) findViewById(R.id.iv_show);

        mRv_show = (RecyclerView) findViewById(R.id.rv_show);

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRv_show.setLayoutManager(layoutManager);

        adapter = new MsgAdapter(msgList);       //创建MsgAdapter的实例并将数据传入到MsgAdapter的构造函数中
        mRv_show.setAdapter(adapter);

        Button btn_speech = (Button) findViewById(R.id.btn_speech);
        btn_speech.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                switch (action) {
                    case MotionEvent.ACTION_DOWN://按下
                        mIv_show.setBackgroundResource(R.drawable.voice_audio);
                        mBackground = (AnimationDrawable) mIv_show.getBackground();
                        mBackground.start();
                        mRl_show.setVisibility(View.VISIBLE);
                        mSpeechRecognizerTool.startASR(MainActivity.this);
                        break;
                    case MotionEvent.ACTION_UP://抬起
                        mBackground.stop();
                        mRl_show.setVisibility(View.GONE);
                        mSpeechRecognizerTool.stopASR();
                        break;
                    default:
                        return false;
                }
                return true;
            }
        });
    }

语音识别后的处理:

 @Override
    public void onResults(final String result) {
        if (result.isEmpty()) {
            return;
        }
        msgList.add(new MsgBean(result, MsgBean.TYPE_SENT));
        adapter.notifyItemInserted(msgList.size() - 1);
        mRv_show.scrollToPosition(msgList.size() - 1);

        new Thread(new Runnable() {
            @Override
            public void run() {
                String utterance = UnitService.utterance(session_id, result);

                RobotBean robotBean = GsonUtils.fromJson(utterance, RobotBean.class);
                final String say = robotBean.getResult().getResponse_list().get(0).getAction_list().get(0).getSay();
                session_id = robotBean.getResult().getSession_id();

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        msgList.add(new MsgBean(say, MsgBean.TYPE_RECEIVED));
                        adapter.notifyItemInserted(msgList.size() - 1);
                        mRv_show.scrollToPosition(msgList.size() - 1);
                    }
                });
                speek(say);
            }
        }).start();
    }

项目中用到的语音识别和语音合成的实现这里就不贴出来了,具体如何实现可以参考百度AI里面的接口文档说明

资源下载地址:https://download.csdn.net/download/abner_crazy/11019672

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等风起了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值