我想在非活动类中实现文本到语音,我希望当用户单击自定义ListView来收听写入的单词时。
代码是下一个:
public class BankAdapter extends BaseAdapter {
List<BankItem> items;
LayoutInflater inflater;
//实现TextToSpeech的类
**TextToSpeach ttl1;**
OnClickListener l;
static class BankItemHolder {
TextView wordView;
TextView descriptionView;
}
Activity myMainActivity;
public BankAdapter(Activity mainActivity) {
// TODO Auto-generated constructor stub
super();
this.myMainActivity=mainActivity;
}
public BankAdapter(Context ctx, List<BankItem> items) {
this.items = items;
inflater =(LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
。 。 。 。
public View getView(final int position, View convertView, ViewGroup parent) {
final BankItemHolder bih;
if (convertView == null) {
RelativeLayout rl = (RelativeLayout) inflater.inflate(R.layout.v_bank_item, null);
convertView = rl;
bih = new BankItemHolder();
bih.wordView = (TextView) rl.findViewById(R.id.txtWord);
bih.descriptionView = (TextView) rl.findViewById(R.id.txtDescription);
convertView.setTag(bih);
} else {
bih = (BankItemHolder) convertView.getTag();
}
bih.wordView.setText(items.get(position).getWord());
bih.descriptionView.setText(items.get(position).getDescriprion());
l=new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String w1 = items.get(position).getWord();
int i1 = w1.indexOf(" ");
String w2=w1.substring(0, i1);
**ttl1.speakWords(w2);**
}
};;;
convertView.setOnClickListener(l);
return convertView;
。 。 。
}
}
现在是实现TextToSpeech的班级
public class TextToSpeach extends Activity implements OnInitListener {
private int MY_DATA_CHECK_CODE = 0;
private TextToSpeech tts;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
// Fire off an intent to check if a TTS engine is installed
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
}
public void speakWords(String word) {
tts.speak(word, TextToSpeech.QUEUE_ADD, null);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
tts = new TextToSpeech(this, this);
}
else {
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
}
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
Toast.makeText(TextToSpeach.this, "Text-To-Speech engine is initialized", Toast.LENGTH_LONG).show();
}
else if (status == TextToSpeech.ERROR) {
Toast.makeText(TextToSpeach.this, "Error occurred while initializing Text-To-Speech engine",
Toast.LENGTH_LONG).show();
}
}
/**
* Be kind, once you've finished with the TTS engine, shut it down so other
* applications can use it without us interfering with it :)
*/
@Override
public void onDestroy()
{
// Don't forget to shutdown!
if (tts != null)
{
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
}
答案 0 :(得分:-1)
当你想在Android上下文之外使用Android框架时,这个问题是有症状的。
从我的小经验和讲座, 这是我在这个问题背景下的最佳实践。
自定义服务,活动,Broadcastreceiver,ContentProvider是android上下文和/或提供了android上下文。 这个上下文对于访问android服务非常重要。
TTS不在异常中:它需要使用上下文和侦听器进行实例化,以便在它准备就绪时通知(在构建时未准备好)
因此,您可以在非GUI组件中执行TextToSpeech操作,例如服务。
避免在相同代码中混合使用App Logic和GUI来设计代码
如果逻辑需要对android框架起作用,那么它只是在运行时需要时提供上下文的好方法(例如作为参数) 例如:context可以是服务或活动实例。
尽可能避免继续引用上下文。 因为用于内存分配策略的android框架可以根据自己的判断来破坏/重建上下文。
希望有帮助