使用安卓sdk 24 编译官方导航Demo,运行时APP崩溃,异常信息如下:
UnsatisfiedLinkError: dlopen failed ... text relocations
和高德技术人员交流后,发现是语音模块的问题,高德地图使用了科大讯飞语音模块,下面就讲述一下,使用sdk 24编译&&执行官方Demo的办法。
- 下载科大讯飞SDK
将so文件&&Msc.jar放入高德官方Demo
这里需要注意一下:
下载的sdk中对应很多abi的so文件,在实际开发中应该将这些abi文件夹都复制到jniLibs文件夹下;
将原来官方Demo中jniLibs下armeabi文件夹下面的so文件,除libmsc.so文件外,向其他的abi文件夹中都复制一份(注意,对于兼容性没有做测试)。TTSController.java文件
其内容如下:
package com.pansoft.oilgas.gaodenavigation;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.autonavi.tbt.TrafficFacilityInfo;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
/**
* 语音播报组件
*/
public class TTSController implements SynthesizerListener, AMapNaviListener {
public static final String TAG = TTSController.class.getSimpleName();
public static TTSController ttsManager;
boolean isfinish = true;
private Context mContext;
// 合成对象.
private SpeechSynthesizer mSpeechSynthesizer;
@Override
public void onEvent(int i, int i1, int i2, Bundle bundle) {
}
TTSController(Context context) {
mContext = context;
}
public static TTSController getInstance(Context context) {
if (ttsManager == null) {
ttsManager = new TTSController(context);
}
return ttsManager;
}
public void init() {
// 初始化合成对象.
mSpeechSynthesizer = SpeechSynthesizer.createSynthesizer(mContext, null);
initSpeechSynthesizer();
}
/**
* 使用SpeechSynthesizer合成语音,不弹出合成Dialog.
*
* @param
*/
public void playText(String playText) {
// if (!isfinish) {
// return;
// }
if (null == mSpeechSynthesizer) {
APPUtil.appendLog(mContext, "mSpeechSynthesizer is null");
// 创建合成对象.
mSpeechSynthesizer = SpeechSynthesizer.createSynthesizer(mContext, null);
initSpeechSynthesizer();
}
// 进行语音合成.
mSpeechSynthesizer.startSpeaking(playText, this);
}
public void stopSpeaking() {
if (mSpeechSynthesizer != null)
mSpeechSynthesizer.stopSpeaking();
}
public void startSpeaking() {
isfinish = true;
}
private void initSpeechSynthesizer() {
// 设置发音人
mSpeechSynthesizer.setParameter(SpeechConstant.VOICE_NAME,
mContext.getString(R.string.preference_default_tts_role));
// 设置语速
mSpeechSynthesizer.setParameter(SpeechConstant.SPEED,
"" + mContext.getString(R.string.preference_key_tts_speed));
// 设置音量
mSpeechSynthesizer.setParameter(SpeechConstant.VOLUME,
"" + mContext.getString(R.string.preference_key_tts_volume));
// 设置语调
mSpeechSynthesizer.setParameter(SpeechConstant.PITCH,
"" + mContext.getString(R.string.preference_key_tts_pitch));
}
@Override
public void onBufferProgress(int arg0, int arg1, int arg2, String arg3) {
Log.d(TAG, "onBufferProgress");
}
@Override
public void onCompleted(SpeechError arg0) {
APPUtil.appendLog(mContext, "error info :" + arg0.getErrorDescription());
Log.e(TAG, arg0.getErrorDescription());
Log.d(TAG, "onCompleted");
isfinish = true;
}
@Override
public void onSpeakBegin() {
APPUtil.appendLog(mContext, "onSpeakBegin");
Log.d(TAG, "onSpeakBegin");
isfinish = false;
}
@Override
public void onSpeakPaused() {
APPUtil.appendLog(mContext, "onSpeakPaused");
Log.d(TAG, "onSpeakPaused");
}
@Override
public void onSpeakProgress(int arg0, int arg1, int arg2) {
APPUtil.appendLog(mContext, "onSpeakProgress :" + arg0);
}
@Override
public void onSpeakResumed() {
APPUtil.appendLog(mContext, "onSpeakResumed ");
}
public void destroy() {
if (mSpeechSynthesizer != null) {
mSpeechSynthesizer.stopSpeaking();
}
}
@Override
public void onArriveDestination() {
// TODO Auto-generated method stub
this.playText("到达目的地");
}
@Override
public void onArrivedWayPoint(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onCalculateRouteFailure(int arg0) {
this.playText("路径计算失败,请检查网络或输入参数");
}
@Override
public void onCalculateRouteSuccess() {
String calculateResult = "路径计算就绪";
this.playText(calculateResult);
}
@Override
public void onEndEmulatorNavi() {
this.playText("导航结束");
}
@Override
public void onGetNavigationText(int arg0, String arg1) {
// TODO Auto-generated method stub
this.playText(arg1);
}
@Override
public void onInitNaviFailure() {
// TODO Auto-generated method stub
}
@Override
public void onInitNaviSuccess() {
// TODO Auto-generated method stub
}
@Override
public void onLocationChange(AMapNaviLocation arg0) {
// TODO Auto-generated method stub
}
@Override
public void onReCalculateRouteForTrafficJam() {
// TODO Auto-generated method stub
this.playText("前方路线拥堵,路线重新规划");
}
@Override
public void onReCalculateRouteForYaw() {
this.playText("您已偏航");
}
@Override
public void onStartNavi(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onTrafficStatusUpdate() {
// TODO Auto-generated method stub
}
@Override
public void onGpsOpenStatus(boolean arg0) {
// TODO Auto-generated method stub
}
@Override
public void onNaviInfoUpdated(AMapNaviInfo arg0) {
// TODO Auto-generated method stub
}
@Override
public void onNaviInfoUpdate(NaviInfo arg0) {
// TODO Auto-generated method stub
}
@Override
public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
}
@Override
public void showCross(AMapNaviCross aMapNaviCross) {
}
@Override
public void hideCross() {
}
@Override
public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {
}
@Override
public void hideLaneInfo() {
}
@Override
public void onCalculateMultipleRoutesSuccess(int[] ints) {
}
@Override
public void notifyParallelRoad(int i) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
}
@Override
public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
}
@Override
public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
}
}
- 在APPlication中添加
@Override
public void onCreate() {
super.onCreate();
// 将“12345678”替换成您申请的 APPID
// 请勿在“ =” 与 appid 之间添加任务空字符或者转义符
SpeechUtility.createUtility(this, SpeechConstant.APPID + "=577a0332");
}