Unity Android SDK(aar)小记

参考自:

https://blog.csdn.net/yang8456211/article/details/51356193

https://blog.csdn.net/li5852258/article/details/78978252

https://github.com/Super0410/Unity_XunFeiSDK

unity sdk两种接入方式:

1.继承自UnityPlayerActivity 这时AndroidMainifest需要创建一个Main Activity覆盖Unity自带的Androidmainfest中的Main Activity。否则使用unity自动合并AndroidMainifest会产生两个

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

因为有两个android.intent.category.LAUNCHER安装之后会产生两个图标

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.df">
    <application

        android:allowBackup="true"

        android:label="@string/app_name"

        android:supportsRtl="true">

        <activity android:label="@string/app_name" android:name=".MainActivity" android:screenOrientation="sensorLandscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>

    </application>

    <!--连接网络权限,用于执行云端语音能力 -->

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

    <!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->

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

    <!--读取网络信息状态 -->

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

    <!--获取当前wifi状态 -->

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

    <!--允许程序改变网络连接状态 -->

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

    <!--读取手机信息权限 -->

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

    <!--读取联系人权限,上传联系人需要用到此权限 -->

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

    <!--外存储写权限,构建语法需要用到此权限 -->

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

    <!--外存储读权限,构建语法需要用到此权限 -->

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

    <!--摄相头权限,拍照需要用到 -->

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

</manifest>

package com.test.df;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SpeechRecognizer;

import com.iflytek.cloud.SynthesizerListener;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

public class MainActivity extends UnityPlayerActivity{

    public SpeechRecognizer speechRecognizer;
    public SpeechSynthesizer speechSynthesizer;
    private String ttsSpeakerName = "yefang";
    private String ttsSpeakerPitch = "50";

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);

        //注意这里的appid为
        SpeechUtility.createUtility(getApplicationContext(),"appid=58880d30");

        initRecognizer();
    }

    private void initRecognizer(){
        speechRecognizer = SpeechRecognizer.createRecognizer(getApplicationContext(),mInitListener);
        speechSynthesizer = SpeechSynthesizer.createSynthesizer(getApplicationContext(),mInitSpeaking);
    }

    public InitListener mInitListener = new InitListener() {
        @Override
        public void onInit(int i) {
            UnityPlayer.UnitySendMessage("FlyTalk", "OnInit", "init Listener success!");
        }
    };

    public InitListener mInitSpeaking = new InitListener() {
        @Override
        public void onInit(int i) {
            UnityPlayer.UnitySendMessage("FlyTTS", "OnInit", "init Speaking success!");
        }
    };

    //TTS是Text To Speech的缩写,即“从文本到语音”
    public void setTTSSpeaker(String targetName) {
        ttsSpeakerName = targetName;
    }

    public void setTTSPitch(String targetPitch) {
        ttsSpeakerPitch = targetPitch;
    }

    public void doTTS(String ttsStr){
        //设置发音人
        speechSynthesizer.setParameter(SpeechConstant.VOICE_NAME,ttsSpeakerName);
        //设置音调
        speechSynthesizer.setParameter(SpeechConstant.PITCH,ttsSpeakerPitch);
        //设置音量
        speechSynthesizer.setParameter(SpeechConstant.VOLUME,"50");
        int code = speechSynthesizer.startSpeaking(ttsStr, mTTSListener);
        //UnityPlayer.UnitySendMessage("FlyTTS", "IsSpeaking", ttsStr+String.valueOf(code));
    }

    private SynthesizerListener mTTSListener = new SynthesizerListener() {
        @Override
        public void onSpeakBegin() {
            UnityPlayer.UnitySendMessage("FlyTTS", "SpeakingBegin", "SpeakingStart");
        }

        @Override
        public void onBufferProgress(int i, int i1, int i2, String s) {

        }

        @Override
        public void onSpeakPaused() {

        }

        @Override
        public void onSpeakResumed() {

        }

        @Override
        public void onSpeakProgress(int i, int i1, int i2) {

        }

        @Override
        public void onCompleted(SpeechError speechError) {
            UnityPlayer.UnitySendMessage("FlyTTS", "SpeakingEnd", speechError.toString());
        }

        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {

        }
    };

    //开始听写
    public void startSpeechListener(){

        UnityPlayer.UnitySendMessage("FlyTalk", "Result", "");

        speechRecognizer.setParameter(SpeechConstant.DOMAIN, "iat");
        speechRecognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        speechRecognizer.setParameter(SpeechConstant.ACCENT, "mandarin");
        speechRecognizer.startListening(mRecognizerListener);
    }

    public RecognizerListener mRecognizerListener = new RecognizerListener(){

        @Override
        public void onBeginOfSpeech() {
            // TODO Auto-generated method stub
            UnityPlayer.UnitySendMessage("FlyTalk", "OnSpeechStart", "SpeechBegin");
        }

        @Override
        public void onEndOfSpeech() {
            // TODO Auto-generated method stub
            UnityPlayer.UnitySendMessage("FlyTalk", "OnSpeechEnd","SpeechEnd");
        }

        @Override
        public void onError(SpeechError arg0) {
            // TODO Auto-generated method stub
            UnityPlayer.UnitySendMessage("FlyTalk", "OnSpeechError", arg0.getErrorDescription());
        }

        @Override
        public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
            // TODO Auto-generated method stub
            //UnityPlayer.UnitySendMessage("FlyTalk", "Result", "onEvent");
        }

        @Override
        public void onResult(RecognizerResult recognizerResult, boolean isLast) {
            printResult(recognizerResult);
        }

        @Override
        public void onVolumeChanged(int arg0, byte[] arg1) {
            //UnityPlayer.UnitySendMessage("FlyTalk", "Result", "onVolumeChanged");
            // TODO Auto-generated method stub
        }
    };

    //解析
    private void printResult(RecognizerResult results) {
        String json = results.getResultString();

        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            JSONArray words = joResult.getJSONArray("ws");
            for (int i = 0; i < words.length(); i++) {
                // 转写结果词,默认使用第一个结果
                JSONArray items = words.getJSONObject(i).getJSONArray("cw");
                JSONObject obj = items.getJSONObject(0);
                ret.append(obj.getString("w"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //将解析结果“"result:" + ret.toString()”发送至“Manager”这个GameObject,中的“Result”函数
        //UnityPlayer.UnitySendMessage("FlyTalk", "Result", ret.toString());
        UnityPlayer.UnitySendMessage("FlyTalk", "OnSpeechResult", ret.toString());
    }

    public void ShowToast(final String mStr2Show){

        //UnityPlayer.UnitySendMessage("FlyTalk", "OnResult", "toast");

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),mStr2Show,Toast.LENGTH_LONG).show();
            }
        });
    }
}

使用时将android studio导出的.arr文件拷贝Assets\Plugins\Android下面,将Unity本身生成的不是android studio生成的AndroidMainfest.xml也拷贝到这个目录下面。android打包时后自动合并这个xml和.arr里面的xml成新的xml使用(这时需要修改将android studioandroid studio生成的Activity替换Unity导出的Activity,否则会出现两个图标)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.youxigu.df" xmlns:tools="http://schemas.android.com/tools" android:versionName="1.0" android:versionCode="1" android:installLocation="preferExternal">
  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
  <application android:theme="@style/UnityThemeSelector" android:icon="@drawable/app_icon" android:label="@string/app_name" android:isGame="true" android:banner="@drawable/app_banner">
    <activity android:label="@string/app_name" android:screenOrientation="sensorLandscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" android:name="com.test.df.MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    </activity>
  </application>
  <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="26" />
  <uses-feature android:glEsVersion="0x00020000" />
  <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
</manifest>

这种方式适合只有一个主Activity 然后这个Activity里面整合其他的sdk接口


2.第二种方式

1)实现SDK时一定要存在一个中间件Activity继承UnityPlayerActivity吗?

网上几乎所有教程都是这样教的,新建一个MyActivity,然后继承UnityPlayerActivity,在MyActivity里面写接口,然而根本没有讲清楚为什么要这样做。。

2)让我们抛弃MyActivity吧

对于1)的问题,答案是NO,简单说一下我的理解,只有当需要在Activity的生命周期中执行一些操作时,我们才需要一个中间Activity去完成这些与生命周期相关的操作,而其他情况下,一个Class足以。

package com.test.df;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SpeechRecognizer;

import com.iflytek.cloud.SynthesizerListener;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

public class MainActivity{

    public SpeechRecognizer speechRecognizer;
    public SpeechSynthesizer speechSynthesizer;
    private String ttsSpeakerName = "yefang";
    private String ttsSpeakerPitch = "50";

    private Activity mActivity;

    public static MainActivity mInstance = null;

    public static MainActivity getInstance()
    {
        if (mInstance == null)
        {
            mInstance = new MainActivity();
        }
        return  mInstance;
    }

    private Context getApplicationContext()
    {
        return mActivity.getApplicationContext();
    }

    protected void onCreate(Context context) {
        mActivity = (Activity)context;

        //注意这里的appid为
        SpeechUtility.createUtility(getApplicationContext(),"appid=58880d30");

        initRecognizer();
    }

    private void initRecognizer(){
        speechRecognizer = SpeechRecognizer.createRecognizer(getApplicationContext(),mInitListener);
        speechSynthesizer = SpeechSynthesizer.createSynthesizer(getApplicationContext(),mInitSpeaking);
    }

    public InitListener mInitListener = new InitListener() {
        @Override
        public void onInit(int i) {
            UnityPlayer.UnitySendMessage("FlyTalk", "OnInit", "init Listener success!");
        }
    };

    public InitListener mInitSpeaking = new InitListener() {
        @Override
        public void onInit(int i) {
            UnityPlayer.UnitySendMessage("FlyTTS", "OnInit", "init Speaking success!");
        }
    };

    //TTS是Text To Speech的缩写,即“从文本到语音”
    public void setTTSSpeaker(String targetName) {
        ttsSpeakerName = targetName;
    }

    public void setTTSPitch(String targetPitch) {
        ttsSpeakerPitch = targetPitch;
    }

    public void doTTS(String ttsStr){
        //设置发音人
        speechSynthesizer.setParameter(SpeechConstant.VOICE_NAME,ttsSpeakerName);
        //设置音调
        speechSynthesizer.setParameter(SpeechConstant.PITCH,ttsSpeakerPitch);
        //设置音量
        speechSynthesizer.setParameter(SpeechConstant.VOLUME,"50");
        int code = speechSynthesizer.startSpeaking(ttsStr, mTTSListener);
        //UnityPlayer.UnitySendMessage("FlyTTS", "IsSpeaking", ttsStr+String.valueOf(code));
    }

    private SynthesizerListener mTTSListener = new SynthesizerListener() {
        @Override
        public void onSpeakBegin() {
            UnityPlayer.UnitySendMessage("FlyTTS", "SpeakingBegin", "SpeakingStart");
        }

        @Override
        public void onBufferProgress(int i, int i1, int i2, String s) {

        }

        @Override
        public void onSpeakPaused() {

        }

        @Override
        public void onSpeakResumed() {

        }

        @Override
        public void onSpeakProgress(int i, int i1, int i2) {

        }

        @Override
        public void onCompleted(SpeechError speechError) {
            UnityPlayer.UnitySendMessage("FlyTTS", "SpeakingEnd", speechError.toString());
        }

        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {

        }
    };

    //开始听写
    public void startSpeechListener(){

        UnityPlayer.UnitySendMessage("FlyTalk", "Result", "");

        speechRecognizer.setParameter(SpeechConstant.DOMAIN, "iat");
        speechRecognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        speechRecognizer.setParameter(SpeechConstant.ACCENT, "mandarin");
        speechRecognizer.startListening(mRecognizerListener);
    }

    public RecognizerListener mRecognizerListener = new RecognizerListener(){

        @Override
        public void onBeginOfSpeech() {
            // TODO Auto-generated method stub
            UnityPlayer.UnitySendMessage("FlyTalk", "OnSpeechStart", "SpeechBegin");
        }

        @Override
        public void onEndOfSpeech() {
            // TODO Auto-generated method stub
            UnityPlayer.UnitySendMessage("FlyTalk", "OnSpeechEnd","SpeechEnd");
        }

        @Override
        public void onError(SpeechError arg0) {
            // TODO Auto-generated method stub
            UnityPlayer.UnitySendMessage("FlyTalk", "OnSpeechError", arg0.getErrorDescription());
        }

        @Override
        public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
            // TODO Auto-generated method stub
            //UnityPlayer.UnitySendMessage("FlyTalk", "Result", "onEvent");
        }

        @Override
        public void onResult(RecognizerResult recognizerResult, boolean isLast) {
            printResult(recognizerResult);
        }

        @Override
        public void onVolumeChanged(int arg0, byte[] arg1) {
            //UnityPlayer.UnitySendMessage("FlyTalk", "Result", "onVolumeChanged");
            // TODO Auto-generated method stub
        }
    };

    //解析
    private void printResult(RecognizerResult results) {
        String json = results.getResultString();

        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            JSONArray words = joResult.getJSONArray("ws");
            for (int i = 0; i < words.length(); i++) {
                // 转写结果词,默认使用第一个结果
                JSONArray items = words.getJSONObject(i).getJSONArray("cw");
                JSONObject obj = items.getJSONObject(0);
                ret.append(obj.getString("w"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //将解析结果“"result:" + ret.toString()”发送至“Manager”这个GameObject,中的“Result”函数
        //UnityPlayer.UnitySendMessage("FlyTalk", "Result", ret.toString());
        UnityPlayer.UnitySendMessage("FlyTalk", "OnSpeechResult", ret.toString());
    }

    public void ShowToast(final String mStr2Show){

        //UnityPlayer.UnitySendMessage("FlyTalk", "OnResult", "toast");

        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),mStr2Show,Toast.LENGTH_LONG).show();
            }
        });
    }
}

这个没有继承UnityPlayerActivity 使用一个单例和onCreate将Unity中的Activity传入到这里面用来获得当前acticity上下文环境

这时AndroidMainfest.xml就可以不需要Activity了 只需要配置权限打包aar后Unity会自动融合

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.youxigu.df" >

    <!--连接网络权限,用于执行云端语音能力 -->

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

    <!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->

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

    <!--读取网络信息状态 -->

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

    <!--获取当前wifi状态 -->

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

    <!--允许程序改变网络连接状态 -->

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

    <!--读取手机信息权限 -->

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

    <!--读取联系人权限,上传联系人需要用到此权限 -->

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

    <!--外存储写权限,构建语法需要用到此权限 -->

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

    <!--外存储读权限,构建语法需要用到此权限 -->

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

    <!--摄相头权限,拍照需要用到 -->

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

</manifest>

ajc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = ajc.GetStatic<AndroidJavaObject>("currentActivity");
ajc = new AndroidJavaClass("com.test.df.MainActivity");
ajo = ajc.CallStatic<AndroidJavaObject>("getInstance");
Debug.Log("getInstance call" + ajo.GetType().ToString());
ajo.Call("onCreate", jo);

Debug.logger.logEnabled = true;

这个将log打印到adb logcat中 

这样就可以调用了



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值