How can i use TextToSpeech functionality without having any interface ? - android

How can i use TextToSpeech functionality without having any interface ? I am developing a app for visually Impaired persons , i just need to generate a voice alert, and the text (alert will be hard coded). Can anyone help me with this ? I am getting error on this TextToSpeech.OnInitListener ..... Is interface is necessory for this ?

Try this one:
public class YourActivity extends Activity {
private TextToSpeech tts;
public static void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_your);
tts = new TextToSpeech(YourActivity.this, InitListener);
}
private TextToSpeech.OnInitListener InitListener = new TextToSpeech.OnInitListener() {
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int res = tts.setLanguage("en", "US", "");
if (res >= TextToSpeech.LANG_AVAILABLE) {
String text = "Input text what you want to say.";
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
}
}
}
}
This app doesn't need UI, and will make voice just once when app is executed.

Related

Android: How to implement Asynctask correctly for this below class?

Below is a login activity which connects with the server to perform login operation, so for this to do in Background thread how to use Asynctask's methods correctly?
I am new to android and not used Asynctask before, but I have seen tutorials still couldn't do it myself
//public class LoginActivity extends AppCompatActivity extends Asynctask shows some error
Edit: error is here
//public class LoginActivity extends AsyncTask extends
AppCompatActivity{ ( { expected)
public class LoginActivity extends AppCompatActivity{
private TextView tvLFS, tvOr;
private Button btnLog;
private EditText etUn, etPw;
private static final String TAG = "LoginActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//remove action bar
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
//change font of the heading
tvLFS = (TextView) findViewById(R.id.tvHeadingLFS);
Typeface typeface =
Typeface.createFromAsset(getAssets(),
"fonts/futuramediumitalicbt.ttf");
tvLFS.setTypeface(typeface);
init();
}
private void init() {
tvLFS = (TextView) findViewById(R.id.tvHeadingLFS);
tvOr = (TextView) findViewById(R.id.tvOR_LOGIN_USING);
btnLog = (Button) findViewById(R.id.btnLogin);
etUn = (EditText) findViewById(R.id.etUName);
etPw = (EditText) findViewById(R.id.etPass);
/* SharedPreferences pref = getSharedPreferences("ActivityPREF",
Context.MODE_PRIVATE);
SharedPreferences.Editor edt = pref.edit();
edt.putBoolean("activity_executed", true);
edt.commit();*/
btnLog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
final String usname = etUn.getText().toString();
final String uspass = etPw.getText().toString();
final LoginRequest loginRequest = new LoginRequest();
loginRequest.setClientType("mobile");
loginRequest.setMsService("login");
loginRequest.setMsServiceType("user-management");
List<LoginRequest.MsDataLogin> msDataLogList = new
ArrayList<>();
LoginRequest.MsDataLogin msData =
loginRequest.getMsDAtaLoginInstance();
msData.setUserName(usname);
msData.setUserPass(uspass);
msDataLogList.add(msData);
loginRequest.setMsData(msDataLogList);
RestClient.getApiInterface().postData(loginRequest).enqueue(new
ResponseResolver<LoginResponse>(LoginActivity.this) {
#Override
public void success(LoginResponse loginResponse) {
if (loginResponse.getErrorCode().equals("0"))
{
Toast.makeText(LoginActivity.this,
"Logged-in successfully!!", Toast.LENGTH_SHORT).show();
Intent in = new
Intent(getApplicationContext(), MainActivity.class);
startActivity(in);
finish();
} else
if(loginResponse.getErrorCode().equals("1")){
Toast.makeText(LoginActivity.this, "No
account found!! Please register", Toast.LENGTH_LONG).show();
}
}
#Override
public void failure(APIError error) {
Log.d(TAG, "failure: error--
"+error.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
Based on you edit, you're trying to extend two classes? Well, (I think) that's not possible in Java ...
Back to your question about AsyncTask. AsynTask are made to make task outside de Main Thread/UI Thread, for some scenarios (Ex.: the basic, not lock the UI while doing some work), for that reason you can't interact with the UI in a AsyncTask or even mix both things (is possible in some cases, but not recommended).
So you need to extends AsyncTask in other class than your view/activity (another Class.java or nested/internal class), example below:
public class MyAsyncTask extends AsyncTask<ParameterType, ProgressType, ReturnType> {
//Example to demonstrate UI interation
private IView view;
public MyAsyncTask(IView view) {
this.view = view;
}
#Override
protected ReturnType doInBackground(ParameterType... params) {
// do and update the work
return new ReturnType(); // work is done, return the result
}
// Override this method if you need to do something after the AsyncTask has finished (based on the return). Here you can interact with the UI too.
#Override
protected void onPostExecute(ReturnType o) {
// Example of UI interaction
view.updateUI(o);
}
}
If you don't need Parameters, Returns or update the progress of your AsyncTask, you can use the 'Void' type in place ParameterType, ProgressType or ReturnType.
Then you can create a intance of MyAsyncTask in other classes (Ex.: your activity) an call ‘execute()’ method to start the AsyncTask.
public class Foobar extends AppCompatActivity implements IView {
... code ...
MyAsyncTask fooTask = new MyAsyncTask(this); // Foobar class needs to implement IView interface
fooTask.execute(parameters); // execute AsyncTask with 'parameters'
... code ...
}
Based on your code you're trying to make a Network call. So you need need migrate your network call to inside 'doInBackground' method, and call the next activity (or show the error) in the 'onPostExecute'.
I not very familiar with your implementation (RestClient, ResponseResolver), but I think you can use Retrofit/Jackson libraries for a more solid solution. They are not very difficult to understand and makes Network calls easier.
In the references below there are other alternatives that you can use instead of a AsyncTask.
Here is some references:
https://developer.android.com/reference/android/os/AsyncTask.html
https://developer.android.com/guide/components/processes-and-threads.html
Good coding.

TextToSpeech in non-activity class/View Adapter class, speak failed: not bound to TTS engine

I've developed a module for my app using RecyclerView in Tabbed-Fragments.
Scenario
There are multiple dynamically loaded images shown in each fragment using RecyclerView. When user taps on any image, system speaks out some information about it using TextToSpeech.
Current code
I'm using an adapter class for RecyclerView that successfully loads images to views. Here's the code:
import android.speech.tts.TextToSpeech;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private ArrayList<CreateList> galleryList;
private Context context;
TextToSpeech tts;
public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
this.context = context;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
.....
}
#Override
public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int i) {
.....
.....
viewHolder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
.....
.....
tts=new TextToSpeech(context, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
// TODO Auto-generated method stub
if(status !=TextToSpeech.ERROR){
tts.setLanguage(Locale.UK);
}
}
});
tts.setPitch(pitch);
tts.setSpeechRate(speechRate);
tts.speak(StringToSpeak, TextToSpeech.QUEUE_FLUSH, null);
}
#Override
public int getItemCount() {
return galleryList.size();
}
.....
.....
}
As you can see I've added a OnClickListener on viewHolder, which initializes TTS object with onInitListener and speaks information. But whenever i click on any image/view/item in Fragment it doesn't speaks out anything. There's no crash, no exception in LogCat, all i get is following message with other messages:
I/TextToSpeech: Sucessfully bound to com.google.android.tts
W/TextToSpeech: speak failed: not bound to TTS engine
I tried debugging the application and found out that while initializing TTS object it returns engine=Null at this line:
tts=new TextToSpeech(context, new TextToSpeech.OnInitListener() {
....});
In other classes that extend Activity, code and TTS is working prefectly but in my Adapter/Non-Activity class it doesn't initiate TTS because it is unable to bind to TTS engine. I've tried to implement interface implements TextToSpeech.OnInitListener in my adapter class with following function:
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.UK);
}
}
But no results :( I've also tried to create an abstract class extending Activity, that implements TTS in its OnCreate() and includes a custom function SpeakMessage() which i tried calling in my Adapter Class but failed. It's been several hours i'm trying to figure out the problem and it's solution, deeply studied every TTS related question on StackOverFlow and other sites but couldn't find any solution for my problem. Please help me with identifying the problem and its proper solution. Thanks alot in advance. One more thing, in same action listener for Views, Playing recorded audio message using MediaPlayer works perfect. The only problem is with speaking string messages using TTS.
I have implemented Text to speech successfully
Below is my Code
I have implemented two method one for <20 api and one is for >21api
#SuppressWarnings("deprecation")
private void ttsUnder20(String text) {
HashMap<String, String> map = new HashMap<>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void ttsGreater21(String text) {
String utteranceId = this.hashCode() + "";
Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");
tts.speak(text, TextToSpeech.QUEUE_FLUSH, params, utteranceId);
}
Here is method which calling this methods.
private void playNextChunk(String text) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ttsGreater21(text);
} else {
ttsUnder20(text);
}}
Call playChunk method from onInit method
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
playNextChunk(String text)
}
}
One more suggestion text to speech is able to speak 4000 character at a time if you have string with >4000 character you need to play it in chunks. for that you need to implement this listener tts.setOnUtteranceProgressListener
Try this code i have added code in your adapter.
public class MyAdapter extends
RecyclerView.Adapter<MyAdapter.ViewHolder>{
private ArrayList<CreateList> galleryList;
private Context context;
TextToSpeech tts;
public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
this.context = context;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
.....
}
#Override
public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int i) {
.....
.....
viewHolder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
.....
.....
tts=new TextToSpeech(context, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
// TODO Auto-generated method stub
// edit from original answer: I put double equal on this line
if(status == TextToSpeech.SUCCESS){
tts.setLanguage(Locale.UK);
playNextChunk(StringToSpeak);
}
}
});
}
private void playNextChunk(String text) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ttsGreater21(text);
} else {
ttsUnder20(text);
}}
#SuppressWarnings("deprecation")
private void ttsUnder20(String text) {
HashMap<String, String> map = new HashMap<>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void ttsGreater21(String text) {
String utteranceId = this.hashCode() + "";
Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");
tts.speak(text, TextToSpeech.QUEUE_FLUSH, params, utteranceId);
}
#Override
public int getItemCount() {
return galleryList.size();
}
.....
.....
}

It's possible to make SpeechRecognizer faster?

I'm developing an application which is using the android SpeechRecognizer. I'm using it for something simple. I click in a button, my SpeechRecognizer start listening and I got some results from what I said.
Easy right? Well, My problem is that I need to make SpeechRecognizer fast. I mean, I click in my button, I say "Hello" and SpeechRecognizer takes like 3-4 seconds in return an array with the possible results. My question is:
It's possible to make SpeechRecognizer return results more faster?
Or take less time to close the Listening intent and start to process what it listen?
Maybe another way to do it? which will have a better performance than this?
I was checking the library and I saw this 3 parameters:
EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS:
The amount of time that it should take after we stop hearing speech to consider the input complete.
EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS
The minimum length of an utterance.
EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS
The amount of time that it should take after we stop hearing speech to
consider the input possibly complete.
http://developer.android.com/intl/es/reference/android/speech/RecognizerIntent.html
I have tried all of them but it is not working, or maybe I'm not using them right. Here is my code:
public class MainActivity extends Activity {
private static final String TIME_FORMAT = "%02d:%02d:%02d";
private final String TAG = "MainActivity";
private StartTimerButton mSpeakButton;
private CircleProgressBar mCountdownProgressBar;
private CountDownTimer mCountDownTimer;
private TextView mTimer;
private int mRunSeconds = 0;
private SpeechRecognizer mSpeechRecognizer;
private Intent mSpeechRecognizerIntent;
private boolean mIsListening = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRunSeconds = 0;
mTimer = (TextView) findViewById(R.id.timerText);
mCountdownProgressBar = (CircleProgressBar) findViewById(R.id.progressBar);
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
// mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS,
// 1000);
// mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS,
// 1000);
// mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS,
// 1000);
SpeechRecognitionListener listener = new SpeechRecognitionListener();
mSpeechRecognizer.setRecognitionListener(listener);
mSpeakButton = (StartTimerButton) findViewById(R.id.btnSpeak);
mSpeakButton.setReadyState(false);
mSpeakButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mSpeakButton.isReady()) {
if (!mIsListening)
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
} else
mSpeakButton.setReadyState(true);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
return true;
}
public void onSpeechResults(ArrayList<String> matches) {
for (String match : matches) {
match = match.toLowerCase();
Log.d(TAG, "Got speech: " + match);
if (match.contains("go")) {
//Do Something
mSpeechRecognizer.stopListening();
}
if (match.contains("stop")) {
//Do Something
mSpeechRecognizer.stopListening();
}
}
}
protected class SpeechRecognitionListener implements RecognitionListener
{
#Override
public void onBeginningOfSpeech()
{
//Log.d(TAG, "onBeginingOfSpeech");
}
#Override
public void onBufferReceived(byte[] buffer)
{
}
#Override
public void onEndOfSpeech()
{
//Log.d(TAG, "onEndOfSpeech");
}
#Override
public void onError(int error)
{
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
//Log.d(TAG, "error = " + error);
}
#Override
public void onEvent(int eventType, Bundle params)
{
}
#Override
public void onPartialResults(Bundle partialResults)
{
ArrayList<String> matches = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
for (String match : matches) {
match = match.toLowerCase();
Log.d(TAG, "onPartialResults : " + match);
}
}
#Override
public void onReadyForSpeech(Bundle params)
{
Log.d(TAG, "onReadyForSpeech"); //$NON-NLS-1$
}
#Override
public void onResults(Bundle results)
{
//Log.d(TAG, "onResults"); //$NON-NLS-1$
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
onSpeechResults(matches);
// matches are the return values of speech recognition engine
// Use these values for whatever you wish to do
}
#Override
public void onRmsChanged(float rmsdB)
{
}
}}
Yes, it is possible to reduce the delay before shutdown....
You cannot alter the amount of time that Google considers to be silence at the end of a user speaking. The EXTRA_SPEECH_* parameters used to work, now they appear to sporadically work at best, or not work at all.
What you can do, is use the partial results to detect the words or phrase you want and then manually shut down the recognition service.
Here's an example of how to do this:
public boolean isHelloDetected(#NonNull final Context ctx, #NonNull final Locale loc, #NonNull final Bundle results) {
boolean helloDetected = false;
if (!results.isEmpty()) {
final String hello = ctx.getString(R.string.hello);
final ArrayList<String> partialData = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
/* handles empty string bug */
if (partialData != null && !partialData.isEmpty()) {
partialData.removeAll(Collections.singleton(""));
if (!partialData.isEmpty()) {
final ListIterator<String> itr = partialData.listIterator();
String vd;
while (itr.hasNext()) {
vd = itr.next().toLowerCase(loc).trim();
if (vd.startsWith(hello)) {
helloDetected = true;
break;
}
}
}
}
if (!helloDetected) {
final ArrayList<String> unstableData = results.getStringArrayList("android.speech.extra.UNSTABLE_TEXT");
/* handles empty string bug */
if (unstableData != null && !unstableData.isEmpty()) {
unstableData.removeAll(Collections.singleton(""));
if (!unstableData.isEmpty()) {
final ListIterator<String> itr = unstableData.listIterator();
String vd;
while (itr.hasNext()) {
vd = itr.next().toLowerCase(loc).trim();
if (vd.startsWith(hello)) {
helloDetected = true;
break;
}
}
}
}
}
}
return helloDetected;
}
You would run this method each time you receive from onPartialResults()
If true is returned, you'll need to call stopListening() on the main thread (probably by new Handler(Looper.getMainLooper()).post(...
Be aware though, once you've shut down the recognizer, the subsequent and final results you receive in onResults() may not contain "hello". As that word may have only be classified as unstable.
You'll need to write additional logic to prevent using detectHello() once hello has been detected (otherwise you'll repeatedly call stopListening()) - some simple boolean markers would resolve this.
Finally, the use of Collections.singleton("") to remove empty strings is part of an internal bug report, details to replicate here and the use of a ListIterator may be overkill for just your sample; a simple for loop would suffice.
Good luck.

Where to manipulate views in android app?

I have a MainActivity, which creates MyOwnTextToSpeech object which is responsible for some tts stuff. It also has to manipulate some UI views (e.g. set text in some TextViews). How should I implement this manipulations of UI? Is it good idea to pass reference to MainActivity to MyOwnTextToSpeech (and other objects) and prepare some public methods in MainActivity for manipulating UI or maybe I should create getters for all views (TextView etc.) to have access to them? Or maybe there is a way not to pass reference to MainActivity (I read somewhere that passing reference to Activities is not good because of some memory leaks stuff)?
UPDATE
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyOwnTextToSpeech myTts = new MyOwnTextToSpeech(context);
}
}
And my class responsible for tts.
public class MyOwnTextToSpeech implements TextToSpeech.OnInitListener {
private TextToSpeech tts;
public MyOwnTextToSpeech (Context ctx) {
tts = new TextToSpeech(ctx, this);
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
}
#Override
public void onError(String utteranceId) {
}
#Override
public void onDone(final String utteranceId) {
// here I want some UI update stuff
}
});
int result = tts.setLanguage(new Locale("pl", "PL"));
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "This Language is not supported");
}
} else {
Log.e("TTS", "Initilization Failed!");
}
}

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 = 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

Categories

Resources