我想在Android上使用HERE Maps实现语音指令,我使用了示例代码“LiveSightGuidanceActivity”,并添加了与here语音指令相关的代码 但声音不起作用!我收到了错误
E / MediaPlayer:应该已经设置了字幕控制器
这是样本中的一段代码
// Setup navigation manager
m_navigationManager = NavigationManager.getInstance();
m_navigationManager.setMap(m_map);
m_navigationManager.setMapUpdateMode(MapUpdateMode.NONE); // No need to update map as LiveSight already does so
attachNavigationListeners();
stopNavigationManager();
// Disable navigation sounds
m_audioFlags = m_navigationManager.getEnabledAudioEvents();
m_navigationManager.setEnabledAudioEvents(EnumSet.allOf((NavigationManager.AudioEvent.class))); // it was nonOf
// Disable traffic avoidance mode as we use pedestrian guidance
m_navigationManager.setTrafficAvoidanceMode(TrafficAvoidanceMode.DISABLE);
// Start navigation in Simulation Mode
NavigationManager.Error error = m_navigationManager.simulate(m_liveSightMapRoute.getRoute(), SIMULATION_SPEED);
if (error != NavigationManager.Error.NONE) {
Toast.makeText(getApplicationContext(), "Failed to start navigation. Error: " + error, Toast.LENGTH_LONG).show();
m_navigationManager.setMap(null);
return;
}
m_navigationManager.setNaturalGuidanceMode(EnumSet.of(NavigationManager.NaturalGuidanceMode.JUNCTION));
setupVoice();
这是完整的setupVoice()方法
private void setupVoice() {
// declare the listeners
// add application specific logic in each of the callbacks.
instructListener = new NavigationManager.NewInstructionEventListener() {
@Override
public void onNewInstructionEvent() {
// Interpret and present the Maneuver object as it contains
// turn by turn navigation instructions for the user.
m_navigationManager.getNextManeuver();
}
};
positionListener = new NavigationManager.PositionListener() {
@Override
public void onPositionUpdated(GeoPosition loc) {
// the position we get in this callback can be used
// to reposition the map and change orientation.
loc.getCoordinate();
loc.getHeading();
loc.getSpeed();
// also remaining time and distance can be
// fetched from navigation manager
m_navigationManager.getTimeToArrival(true,
Route.TrafficPenaltyMode.DISABLED);
m_navigationManager.getDestinationDistance();
}
};
// start listening to navigation events
m_navigationManager.addNewInstructionEventListener(
new WeakReference<NavigationManager.NewInstructionEventListener>(instructListener));
// start listening to position events
m_navigationManager.addPositionListener(
new WeakReference<NavigationManager.PositionListener>(positionListener));
// Retrieve the VoiceCatalog and download the latest updates
VoiceCatalog voiceCatalog = VoiceCatalog.getInstance();
if (!voiceCatalog.isLocalCatalogAvailable()) {
Log.d(TAG, "Voice catalog is not available in local storage.");
//Toast.makeText(mActivity.getApplicationContext(), "Voice catalog is not available in local storage.", Toast.LENGTH_LONG).show();
voiceCatalog.downloadCatalog(new VoiceCatalog.OnDownloadDoneListener() {
@Override
public void onDownloadDone(VoiceCatalog.Error error) {
if (error == VoiceCatalog.Error.NONE) {
// catalog download successful
Log.d(TAG, "Download voice catalog successfully.");
//Toast.makeText(mActivity.getApplicationContext(), "Voice catalog download successful.", Toast.LENGTH_LONG).show();
} else {
Log.d(TAG, "Download voice catalog failed.");
//Toast.makeText(mActivity.getApplicationContext(), "Voice catalog download error.", Toast.LENGTH_LONG).show();
}
// Get the list of voice packages from the voice catalog list
List<VoicePackage> voicePackages =
VoiceCatalog.getInstance().getCatalogList();
if (voicePackages.size() == 0) {
Log.d(TAG, "Voice catalog size is 0.");
//Toast.makeText(mActivity.getApplicationContext(), "Voice catalog size is 0.", Toast.LENGTH_LONG).show();
}
long id = -1;
// select
for (VoicePackage voicePackage : voicePackages) {
if (voicePackage.getMarcCode().compareToIgnoreCase("eng") == 0) {
if (voicePackage.isTts()) // TODO: need to figure out why always return false
{
id = voicePackage.getId();
break;
}
}
}
if (!VoiceCatalog.getInstance().isLocalVoiceSkin(id)) {
final long finalId = id;
VoiceCatalog.getInstance().downloadVoice(id, new VoiceCatalog.OnDownloadDoneListener() {
@Override
public void onDownloadDone(VoiceCatalog.Error error) {
if (error == VoiceCatalog.Error.NONE) {
//voice skin download successful
Log.d(TAG, "Download voice skin successfully.");
//Toast.makeText(mActivity.getApplicationContext(), "Voice skin download successful.", Toast.LENGTH_LONG).show();
// set the voice skin for use by navigation manager
if (VoiceCatalog.getInstance().getLocalVoiceSkin(finalId) != null) {
m_navigationManager.setVoiceSkin(VoiceCatalog.getInstance().getLocalVoiceSkin(finalId));
} else {
Log.d(TAG, "Get local voice skin error.");
//Toast.makeText(mActivity.getApplicationContext(), "Navi manager set voice skin error.", Toast.LENGTH_LONG).show();
}
} else {
Log.d(TAG, "Download voice skin failed.");
//Toast.makeText(mActivity.getApplicationContext(), "Voice skin download error.", Toast.LENGTH_LONG).show();
}
}
});
} else {
// set the voice skin for use by navigation manager
if (VoiceCatalog.getInstance().getLocalVoiceSkin(id) != null) {
m_navigationManager.setVoiceSkin(VoiceCatalog.getInstance().getLocalVoiceSkin(id));
} else {
Log.d(TAG, "Get local voice skin error.");
//Toast.makeText(mActivity.getApplicationContext(), "Navi manager set voice skin error.", Toast.LENGTH_LONG).show();
}
}
}
});
}
}
答案 0 :(得分:0)
通常,HERE的MobileSDK使用的是在Android上设置的系统TTS引擎。因此,请确保您的Android设备已安装并设置了TTS引擎(通常是Google TTS,有些OEM没有设置像我的Sony Z5那样的引擎,或者有些还设置了另一个引擎,例如带有sfplus的LG)。 >
一旦Android具有TTS功能,在HERE SDK端的流程应如下所示:
检查HERE SDK的已安装TTS外观:
dlopen
如果您想要的声音已经在本地下载,则直接跳至4。否则继续下一步。
从HERE服务器获取语音目录:
List localInstalledSkins = VoiceCatalog.getInstance().getLocalVoiceSkins();
在侦听器回调中,您可以查询以下可供下载的语言列表:
VoiceCatalog.getInstance().downloadCatalog(VoiceCatalog.OnDownloadDoneListener)
下载要播放的VoiceSkin:
List packages = VoiceCatalog.getInstance().getCatalogList();
在继续下一步之前,请确保侦听器成功返回。
设置下载的语音皮肤以进行导航:
VoiceCatalog.getInstance().downloadVoice(skin_id_from_catalog_you_want_to_use, VoiceCatalog.OnDownloadDoneListener)
开始指导
您可以从HERE服务器获取完整的项目源:http://tcs.ext.here.com/sdk_examples/TtsAndNavigation.zip