How to implement text to speech in non-activity class
I want to implement text to speech in non-activity class, I want when user click on custom ListView to listen the word who is written.
The code is next:
public class BankAdapter extends BaseAdapter {
List<BankItem> items;
LayoutInflater inflater;
//class who implements 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 开发者_如何学Go= 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;
. . . .
}
}
Now the class who implements 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();
}
}
This question is symptomatic when you want to use Android framework outside of a android context..
From my little experience and lecture, Here my own best practice in this question context.
FIRST:
Custom Service, Activity, Broadcastreceiver, ContentProvider are android context and/or are provided with android context. This context is very important to get access to android services.
TTS is not in exception : it needs to be intantiated with a context and a listener to notify when it is ready (not ready at contruction time)
So you may do TextToSpeech actions in non-GUI component like a service for instance.
SECOND:
Avoid to design your code with a mix of App Logic and GUI in same code
THIRD:
if logic need to act on android framework it's a good way to provide context only when needed at runtime (as a parameter for instance) as example : context can be a service or activity instance.
FOURTH:
Avoid as much as possible to keep reference to a context. because android framework,for memory allocation strategy, may destroy /reconstruct context at it's own discretion.
hope that help
精彩评论