我最近开始进行android编程,我试图查看设备上可以使用哪些语言进行语音转换并将其显示在微调器中,但是我遇到了一个非常奇怪的问题。
这是代码的相关部分:
package com.example.dshawn.ttsapp;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import java.util.*;
public class MainActivity extends AppCompatActivity implements
AdapterView.OnItemSelectedListener {
private TextToSpeech mTTS;
Locale[] locales = Locale.getAvailableLocales();
List<Locale> localeList = new ArrayList<Locale>();
List<String> country= new ArrayList<String>();
List<String> asdf= new ArrayList<String>();
int sum=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int i) {
if (i==TextToSpeech.SUCCESS){
for (Locale locale : locales) {
int res = mTTS.isLanguageAvailable(locale);
if (res == TextToSpeech.LANG_COUNTRY_AVAILABLE) {
sum++;
localeList.add(locale);
country.add(locale.getDisplayName());
}
}
asdf.add(Integer.toString(sum));
}
}
});
//Getting the instance of Spinner and applying OnItemSelectedListener on it
Spinner spin = (Spinner) findViewById(R.id.spinner);
spin.setOnItemSelectedListener(this);
//Creating the ArrayAdapter instance having the country list
ArrayAdapter<String> aa = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,country);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Setting the ArrayAdapter data on the Spinner
spin.setAdapter(aa);
}
//Performing action onItemSelected and onNothing selected
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
Toast.makeText(getApplicationContext(),country.get(position) , Toast.LENGTH_LONG).show();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
此TTS初始化后,我尝试打印sum,结果显示为0。我尝试通过执行String = country.get(1)之类的操作来访问localeList和country中的元素。并且会在编译器中给出错误,指出我尝试访问的索引不存在,并且列表中有0个元素。因此,此时似乎设备上可能没有可用的语言,但是奇怪的是,当我通过ArrayAdapter将国家ArrayList放入微调器下拉菜单时,设备上的实际可用国家确实显示在微调器中菜单,但它坏了,这是我的意思的gif图像:
微调器永远不会进入我的onItemSelected侦听器,并且单击该项目后它不会显示在微调器中。我进入了设备的设置,显示的确实是该设备上TTS的可用语言环境。当我删除似乎从未访问过的代码的“ if(res == TextToSpeech.LANG_COUNTRY_AVAILABLE)”部分时,微调框下拉菜单中将没有任何内容。因此,它显然以某种方式抢占了可用的语言环境,但是当我尝试访问arraylist时,它的行为就像是空的,但是以某种方式,它使用了“空” arraylist并将正确的国家/地区放入了微调框,但可能是因为微调框已损坏ArrayList损坏了,因为我尝试使用手动填充的arraylist进行相同的操作,并且元素正常显示,并且我可以正常选择它。
这里可能是什么问题?我已经尝试了所有我能想到的,我只知道问题出在TTS初始化部分。
基本上,我无法访问在TTS的“ onInit”方法中设置或添加的任何项目,这也会导致旋转器损坏。
答案 0 :(得分:1)
我认为问题在于,您是在填充列表之前(使用国家/地区列表)创建适配器的(因为TTS尚未初始化)。
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private TextToSpeech mTTS;
Locale[] locales = Locale.getAvailableLocales();
List<Locale> localeList = new ArrayList<Locale>();
List<String> country = new ArrayList<String>();
// * - Move these two variables out here
ArrayAdapter<String> aa;
Spinner spin;
int sum = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("XXX", "onCreate() was called");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int i) {
if (i == TextToSpeech.SUCCESS) {
// * - delay important tasks until TTS is initialized
startWhenTTSIsInitialized();
}
}
});
//Getting the instance of Spinner and applying OnItemSelectedListener on it
spin = (Spinner) findViewById(R.id.spinner);
}
private void startWhenTTSIsInitialized() {
Log.i("XXX", "startWhenTTSIsInitialized() was called");
for (Locale locale : locales) {
int res = mTTS.isLanguageAvailable(locale);
if (res == TextToSpeech.LANG_COUNTRY_AVAILABLE) {
sum++;
localeList.add(locale);
// * - 'country' is used to populate the adapter, so
// this line must come first
country.add(locale.getDisplayName());
}
}
//Creating the ArrayAdapter instance having the country list
// * - now it's safe to set the adapter because the country list has been populated
aa = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, country);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Setting the ArrayAdapter data on the Spinner
spin.setAdapter(aa);
spin.setOnItemSelectedListener(this);
}
//Performing action onItemSelected and onNothing selected
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
Log.i("XXX", "onItemSelected() was called");
Toast.makeText(getApplicationContext(), country.get(position), Toast.LENGTH_LONG).show();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
答案 1 :(得分:0)
您在哪里打电话给String=country.get(1);
?因为这是一个回调,所以您将不知道何时调用它。如果将代码放在onInit
语句块之后的if
内,您会看到该值吗?