I'm working on a notification based app, for which I need to listen to incoming notifications. I've been able to listen to incoming call,sms, mail etc. I have no clue how to listen for pings or messages from friends on Whatsapp via code. Can this actually be done but problem is that TTS service continue started.when user send message two time TTS service run two time. plz solve this problem...
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
super.onNotificationPosted(sbn);
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
int state = telephonyManager.getCallState();
if (state != TelephonyManager.CALL_STATE_OFFHOOK) {
String packageName = sbn.getPackageName();
if (sbn.getNotification().tickerText != null) {
if (packageName.contains("whatsapp")) {
whatText = "Whatsapp Notification";
initTTS(sbn.getNotification().tickerText + "");
}
}
}
}
private void initTTS(String s) {
text = whatText + " ";
STD = s + " ";
tts = new TextToSpeech(this, this);
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
}
#Override
public void onDone(String utteranceId) {
stopSelf();
}
#Override
public void onError(String utteranceId) {
}
});
}
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR) {
tts.setLanguage(Locale.US);
SharedPreferences preferences = getSharedPreferences("SET", MODE_PRIVATE);
String Demo = preferences.getString("text", text);
tts.speak(Demo + STD + " ", TextToSpeech.QUEUE_FLUSH, null);
}
}
Related
TextToSpeech is initialized like this in onCreate()
tts = new TextToSpeech(this, this);
onInit coded like this.
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String s) {
Log.v(TAG, "onStart : " + s);
}
#Override
public void onDone(String s) {
tts.setLanguage(Locale.US);
fabSpeak.setEnabled(true);
Log.v(TAG, "Proceed");
}
#Override
public void onError(String s) {
Log.v(TAG, "onError : " + s);
}
});
Log.v(TAG, "Proceed2");
} else {
Log.e(TAG, "Initilization Failed!");
}
}
only Proceed2 printed. Proceed is printed only on when I call
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, "1");
If I synthesizeToFile without call speak like this
int test = tts.synthesizeToFile(text, null, file, "tts");
if (test == TextToSpeech.SUCCESS) {
Log.v(TAG, "Success");
}
This log prints Success, but file is empty. If I synthesize file after called speak then file has data.
But I want to synthesizeToFile without call speak. I don't know what is wrong here.
I need to speak multiple language. I created an array for TextToSpeech.
private TextToSpeech[] mTextSpeechs_;
mTextSpeechs_ = new TextToSpeech[5];
mTextSpeechs_[0] = new TextToSpeech(this, new TextToSpeech.OnInitListener()
{
#Override
public void onInit(int status)
{
mTextSpeechs_[0].setLanguage(Locale.CHINESE);
mTextSpeechs_[0].speak(getString(R.string.string_main_chineseready), TextToSpeech.QUEUE_FLUSH, null,"Display");
}
});
mTextSpeechs_[1] = new TextToSpeech(this, new TextToSpeech.OnInitListener()
{
#Override
public void onInit(int status)
{
mTextSpeechs_[1].setLanguage(Locale.forLanguageTag("yue-HK"));
mTextSpeechs_[1].speak(getString(R.string.string_main_hongkong), TextToSpeech.QUEUE_FLUSH, null,"Display");
}
});
mTextSpeechs_[2] = new TextToSpeech(this, new TextToSpeech.OnInitListener()
{
#Override
public void onInit(int status)
{
mTextSpeechs_[2].setLanguage(Locale.JAPAN);
mTextSpeechs_[2].speak(getString(R.string.string_main_japan), TextToSpeech.QUEUE_FLUSH, null,"Display");
}
});
mTextSpeechs_[3] = new TextToSpeech(this, new TextToSpeech.OnInitListener()
{
#Override
public void onInit(int status)
{
mTextSpeechs_[3].setLanguage(Locale.KOREA);
mTextSpeechs_[3].speak(getString(R.string.string_main_korea), TextToSpeech.QUEUE_FLUSH, null,"Display");
}
});
mTextSpeechs_[4] = new TextToSpeech(this, new TextToSpeech.OnInitListener()
{
#Override
public void onInit(int status)
{
mTextSpeechs_[4].setLanguage(Locale.ENGLISH);
mTextSpeechs_[4].speak(getString(R.string.string_main_english), TextToSpeech.QUEUE_FLUSH, null,"Display");
}
});
....
//type 0 flush
//type 1 add
public void speakMultiLanguage(String text, int type,int langidx)
{
if( type == 0 )
mTextSpeechs_[langidx_].speak(text, TextToSpeech.QUEUE_FLUSH, null,"Display");
else if( type == 1)
mTextSpeechs_[langidx_].speak(text, TextToSpeech.QUEUE_ADD, null,"Display");
}
Now, When I call speakMultiLanguage function to speak specified language, it will delay about 5 seconds to speak. If the last language is same, it will not delay. Does anyone give me a solution to solve the delay?
I wasn't testing your particular case of multiple usage of TTS in array. But for me it looks none productive, especially memory and resources using.
In my case I initialise only one TTS object in onCreate() method of My Activity. And when I need to change languge to another, I'll use tts.setLanguge(Locale).
In my case and with my virtual device this solution working immediately.
initialise:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS){
tts.setLanguage(Locale.ENGLISH);
}else{
Log.e(TAG, "TTS fault");
}
}
});
//....
}
Change:
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void prepareTTS(Locale newLocale){
if (!tts.getVoice().getLocale().getISO3Language().equals(newLocale.getISO3Language())) {
tts.setLanguage(newLocale);
Log.d(TAG, "ChangeTo: " + newLocale.getISO3Language());
}else{
Log.d(TAG, "The same");
}
}
speech:
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void ttsSpeak21(String text){
String utteranceId = this.hashCode() + "";
int result = tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
if (result == TextToSpeech.ERROR){
Log.d(TAG, "Can't say");
}else {
Log.d(TAG, lang + "speaking!");
}
}
free resources:
#Override
protected void onDestroy() {
if (tts != null){
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
Ok i tried everything every single problem in every site and google even i tried every example
why I cant do speech to text in real time with google voice input ?? it works when we click on mic on the keyboard but that don't have keycode to use it in custom button to keyevent it is there any way to do real time speech to text or implement that mic button (keycode)?
private EditText log;
private SpeechRecognizer sr;
private static final String TAG = "spk2txtD2";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button speakButton = (Button) findViewById(R.id.btn);
log = (EditText) findViewById(R.id.txt);
speakButton.setOnClickListener(this);
//get the SpeechRecognizer and set a listener for it.
sr = SpeechRecognizer.createSpeechRecognizer(this);
sr.setRecognitionListener(new listener());
}
#Override
public void finish() {
sr.destroy();
sr = null;
super.finish();
}
/*
* The Recognitionlistener for the SpeechRecognizer.
*/
class listener implements RecognitionListener {
public void onReadyForSpeech(Bundle params) {
Log.d(TAG, "onReadyForSpeech");
}
public void onBeginningOfSpeech(){
Log.d(TAG, "onBeginningOfSpeech");
}
public void onRmsChanged(float rmsdB){
Log.d(TAG, "onRmsChanged" );
}
public void onBufferReceived(byte[] buffer) {
Log.d(TAG, "onBufferReceived");
}
public void onEndOfSpeech() {
Log.d(TAG, "onEndofSpeech");
}
public void onError(int error) {
Log.d(TAG, "error " + error);
logthis("error " + error);
}
public void onResults(Bundle results) {
Log.d(TAG, "onResults " + results);
// Fill the list view with the strings the recognizer thought it could have heard, there should be 5, based on the call
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
//display results.
log.setText(String.valueOf(matches));
logthis("results: "+String.valueOf(matches.size()));
for (int i = 0; i < matches.size(); i++) {
Log.d(TAG, "result " + matches.get(i));
logthis("result " +i+":"+ matches.get(i));
}
}
public void onPartialResults(Bundle partialResults)
{
Log.d(TAG, "onPartialResults");
}
public void onEvent(int eventType, Bundle params)
{
Log.d(TAG, "onEvent " + eventType);
}
}
public void onClick(View v) {
if (v.getId() == R.id.btn) {
//get the recognize intent
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
//Specify the calling package to identify your application
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,getClass().getPackage().getName());
//Given an hint to the recognizer about what the user is going to say
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
//specify the max number of results
// intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,0);
intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS,true);
// intent.putExtra("android.speech.extra.DICTATION_MODE", true);
//User of SpeechRecognizer to "send" the intent.
sr.startListening(intent);
Log.i(TAG,"Intent sent");
}
}
/*
* simple method to add the log TextView.
*/
public void logthis (String newinfo) {
if (newinfo != "") {
log.setText(log.getText() + "\n" + newinfo);
}
}
}
When I check which languages are available Thai (th)is available butit doesn't read the text
#SuppressLint("NewApi")
private void speak() {
if(tts!=null && tts.isSpeaking()){
tts.stop();
}else{
tts = new TextToSpeech(this, this);
tts.setLanguage(Locale.forLanguageTag("th")); //tts.getAvailableLanguages().;
tts.setSpeechRate(0.7f);
}
}
#Override
public void onInit(int status) {
tts.speak("ซึ่งมีระยะทางส่วนใหญ่เป็น ทางหลวงแผ่นดินหมายเลข (สายบางนา - หาดเล็ก) เป็นเส้นทางคมนาคมหลักเส้นหนึ่งของประเทศไทย ", TextToSpeech.QUEUE_FLUSH, null);
}
Edit your code like this:
#SuppressLint("NewApi")
private void speak() {
if(tts!=null && tts.isSpeaking()) {
tts.stop();
}else{
tts = new TextToSpeech(this, this);
}
}
#Override public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int res = tts.setLanguage("th_TH");
//tts.getAvailableLanguages().;
tts.setSpeechRate(0.7f);
if (res >= TextToSpeech.LANG_AVAILABLE) {
tts.speak("ซึ่งมีระยะทางส่วนใหญ่เป็น ทางหลวงแผ่นดินหมายเลข (สายบางนา - หาดเล็ก) เป็นเส้นทางคมนาคมหลักเส้นหนึ่งของประเทศไทย ", TextToSpeech.QUEUE_FLUSH, null);
}
}
Because TextToSpeech instance is created asynchronously, so you can hear synthesis result when you control your tts after onInit() method was done.
I am using the default dictionary that comes with the pocketsphinx demo which is good for my purposes. When a user enters a phrase, the app starts a keyphrase listening but if the word is not found in the dictionary the app crashes. The app crashes onError() within a service. How is the error handling done? is there any way I can catch the error? Overall I would just like the service to call stopSelf() when an error happens so the main activity won't crash as well.
Errors:
ERROR: "kws_search.c", line 165: The word 'phonez' is missing in the dictionary
Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 5389 (1994.wherephone)
Here is my service class:
public class WherePhoneService extends Service implements RecognitionListener {
private static String SettingStorage = "SavedData";
SharedPreferences settingData;
private SpeechRecognizer recognizer;
private String sInput;
private String sOutput;
private int seekVal;
private TextToSpeech reply;
private AsyncTask t;
public WherePhoneService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
makeText(getApplicationContext(), "onHandle start", Toast.LENGTH_SHORT).show();
getValues();
startTTS();
t = new AsyncTask<Void, Void, Exception>() {
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(WherePhoneService.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
#Override
protected void onPostExecute(Exception result) {
if (result != null) {
//((TextView) findViewById(R.id.caption_text)).setText("Failed to init recognizer " + result);
} else {
switchSearch(sInput);
}
}
}.execute();
return Service.START_STICKY;
}
private void setupRecognizer(File assetsDir) throws IOException {
recognizer = defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
// To disable logging of raw audio comment out this call (takes a lot of space on the device)
//.setRawLogDir(assetsDir)
// Threshold to tune for keyphrase to balance between false alarms and misses
.setKeywordThreshold(1e-45f)
// Use context-independent phonetic search, context-dependent is too slow for mobile
.setBoolean("-allphone_ci", true)
.getRecognizer();
recognizer.addListener(this);
// Create keyword-activation search.
recognizer.addKeyphraseSearch(sInput, sInput);
}
private void switchSearch(String searchName) {
recognizer.stop();
// If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
if (searchName.equals(sInput))
recognizer.startListening(searchName);
else
recognizer.startListening(searchName, 10000);
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onEndOfSpeech() {
if (!recognizer.getSearchName().equals(sInput))
switchSearch(sInput);
}
#Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), "Partial", Toast.LENGTH_SHORT).show();
if (text.equals(sInput)) {
setVolume();
// Text to speech
reply.speak(sOutput, TextToSpeech.QUEUE_ADD, null);
switchSearch(sInput);
}
else {
makeText(getApplicationContext(), "Try again", Toast.LENGTH_SHORT).show();
switchSearch(sInput);
}
}
#Override
public void onResult(Hypothesis hypothesis) {
if (hypothesis != null) {
// restart listener and affirm that partial has past
makeText(getApplicationContext(), "end", Toast.LENGTH_SHORT).show();
//recognizer.startListening(sInput);
switchSearch(sInput);
}
}
public void onError(Exception e) {
e.printStackTrace(); // not all Android versions will print the stack trace automatically
Intent intent = new Intent ();
intent.setAction ("com.mydomain.SEND_LOG"); // see step 5.
intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); // required when starting from Application
startActivity (intent);
stopSelf();
}
#Override
public void onTimeout() {
switchSearch(sInput);
}
public void startTTS() {
reply = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR){
reply.setLanguage(Locale.UK);
}
}
});
}
public void getValues() {
settingData = getBaseContext().getSharedPreferences(SettingStorage, 0);
sInput = settingData.getString("inputstring", "Where is my phone").toString().toLowerCase().replaceAll("[^\\w\\s]", "");
sOutput = settingData.getString("outputstring", "").toString().toLowerCase();
seekVal = settingData.getInt("seekval", 0);
}
public void setVolume() {
int seekValConvert = 0;
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int getMaxPhoneVol = audioManager.getStreamMaxVolume(audioManager.STREAM_MUSIC);
seekValConvert = ((seekVal * getMaxPhoneVol)/100);
audioManager.setStreamVolume(audioManager.STREAM_MUSIC, seekValConvert, 0);
}
#Override
public void onDestroy() {
super.onDestroy();
makeText(getApplicationContext(), "destroy", Toast.LENGTH_SHORT).show();
recognizer.cancel();
recognizer.shutdown();
t.cancel(true);
}
}
Crash is a bug in pocketsphinx-android. If you update to latest version from github, it should properly throw RuntimeException on any errors in methods addKeyphrase and setSearch.