I want to use android's speech to text. following is my MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView txtSpeechInput;
private ImageButton btnSpeak;
private final int REQ_CODE_SPEECH_INPUT = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtSpeechInput = (TextView) findViewById(R.id.txtSpeechInput);
btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
// hide the action bar
//getActionBar().hide();
btnSpeak.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("OnClickListener CALLED:", "");
promptSpeechInput();
}
});
}
private void promptSpeechInput() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
getString(R.string.speech_prompt));
try {
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
} catch (ActivityNotFoundException a) {
Toast.makeText(getApplicationContext(),
getString(R.string.speech_not_supported),
Toast.LENGTH_SHORT).show();
}
Log.i("promptSpeechInput :", "Prompt speech CALLED");
}
/**
* Receiving speech input
* */
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i("OnActivity CALLED1:","one");
switch (requestCode) {
case REQ_CODE_SPEECH_INPUT: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> result = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
txtSpeechInput.setText(result.get(0));
Log.i("OnActivity CALLED2:", result.get(0));
}
break;
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Here is my Log:
02-26 16:23:05.047 13636-13636/com.example.vishal.speechtotext I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy#39ca1da6 time:158833044
02-26 16:23:09.637 13636-13636/com.example.vishal.speechtotext I/Timeline: Timeline: Activity_launch_request time:158837632
02-26 16:23:09.707 13636-13636/com.example.vishal.speechtotext I/promptSpeechInput :: Prompt speech CALLED
02-26 16:23:42.797 13636-13636/com.example.vishal.speechtotext I/OnActivity CALLED1:: one
02-26 16:23:42.837 13636-13636/com.example.vishal.speechtotext I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy#39ca1da6 time:158870837
code just runs, doesn't show any error. i am unable to find what the
error is.
I am testing on Lollipop
Do i need net connection?
any help will be appreciated.
Yes you'll be needing Internet for this. Paste Following permissions inside your manifest file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Right now all the devices are not supporting offline speech input. To enable offline speech input for supported devices follow below steps:
On your device go to Settings -> Language and Input. Click on icon on Google voice input.
Under ALL tab select the language you want to download.
3. Once the language package downloaded, you can see it under INSTALLED tab.
I have downloaded speech input packages on my Nexus 5 and offline speech is working fine.
For further reference checkout the below link:
https://web.archive.org/web/20160218040751/http://www.androidhive.info/2014/07/android-speech-to-text-tutorial/
Related
Google Speech-to-Text API supports Marathi as per their documentation here. However I have not been able to get it working on my Android phone. I have already added 'Marathi' in languages for my Android device (Moto G6, running android 7.1.1). However, I am not yet able to get a simple SMS converted from speech-to-text with this. Marathi typing works fine though.
Do I need to modify any other setting? What else is required? Any pointers for this would be highly appreciated.
Have you configured your intent to detect marathi languages as below?
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,"mr-IN");
You can checkout other languages codes here.
You can use following code for your reference:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.RecordBtn:
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
// Use Off line Recognition Engine only...
intent.putExtra(RecognizerIntent.EXTRA_PREFER_OFFLINE, false);
// Use Marathi Speech Recognition Model...
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "mr-IN");
try {
startActivityForResult(intent, SST_REQUEST_CODE);
} catch (ActivityNotFoundException a) {
Toast.makeText(getApplicationContext(),
getString(R.string.error),
Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case SST_REQUEST_CODE:
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> getResult = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
Original.setText(getResult.get(0));
conversionTable = new ConversionTable();
String Transformed_String = conversionTable.transform(getResult.get(0));
result.setText(Transformed_String);
}
break;
}
}
I'm struggling with my application lately.
I have an activity 'MyActivity' with a textview holding the current date
The use case is simple:
- user clicks a button to start camera intent from MyActivity
- user takes picture
- MyActivity is resumed and the textview still holds the current date
This works fine on most devices. However, on devices with low memory, the activity is destroyed during camera intent and when I get back to MyActivity,
the textview no longer holds the date.
Using debugger and breakpoints, I could see the following:
05-16 12:41:35.364 3614-3614/com.example.test D/TAG: onDestroy: MyActivity#10140ca0
05-16 12:41:35.414 3614-3614/com.example.test D/TAG: onCreate: MyActivity#2e507264
05-16 12:41:35.804 3614-3614/com.example.test D/TAG: setting textview date : "16 05 2018"
05-16 12:41:37.206 3614-3614/com.example.test D/TAG: onDestroy: MyActivity#2e507264
05-16 12:41:37.236 3614-3614/com.example.test D/TAG: onCreate: MyActivity#253f67dc
05-16 12:41:37.706 3614-3614/com.example.test D/TAG: setting textview date : "16 05 2018"
As you can see the textview is being set just as expected, but the screen doesn't show it.
If anyone can guess the solution to this annoying I would be thankful.
Edit
#Override
public void onCreate(Bundle savedInstanceState) {
Log.d("TAG", "onCreate: " + this);
// inflate the layout
loadContent(R.layout.activity_invoice_more_options);
dateView = findViewById(R.id.date_view);
buttonView = findViewById(R.id.button_view);
dateView.setText(Tools.getFormattedDate(Calendar.getInstance().getTime(), "dd MM yyyy"));
// set button click listener
buttonView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent chooseImageIntent = getPickImageIntent(getApplicationContext(), getString(R.string.choose_action));
startActivityForResult(chooseImageIntent, FILE_PICKER_RESULT);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data == null) return;
switch (requestCode) {
case FILE_PICKER_RESULT:
if (resultCode != RESULT_OK) return;
// retrieve file content and name
final String fileName = Tools.getFileName(this, data);
String fileContent = Tools.getFileContent(this, data);
break;
}
}
I have a menu Activity with several options. One of them is to post to a news feed using Glass's speech-to-text. I looked at https://developers.google.com/glass/develop/gdk/input/voice#starting_the_speech_recognition_activity
and have it all implemented, but the onActivityResult method apparently never gets called.
On the Glass device, I'm able to select "New Post" in the menu and the voice capture comes up. I can speak to it and it'll convert my speech to text on the screen. But after I accept it (by tapping or waiting a few seconds), it just exits and takes me back to the home screen. I need to be able to get the speech text String in onActivityResult and call another method (displayPostMenu) to show another menu to process the text but I can't do that if onActivityResult is never called.
I've looked at several similar issues but none of the solutions have worked/were applicable... I don't think I can setResult() on RecognizerIntent.ACTION_RECOGNIZE_SPEECH since it's Google's? Any help would be greatly appreciated!
Some pieces of my code:
private final int SPEECH_REQUEST = 1;
//Code to make this Activity work and the menu open...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.view_feed:
//Stuff
return true;
case R.id.new_post:
Log.i("MainMenu", "Selected new_post");
displaySpeechRecognizer();
Log.i("MainMenu", "Ran displaySpeechRecog under new_post selection");
return true;
case R.id.stop:
Activity parent = getParent();
Log.i("MainMenu", "Closing activity; parent: " + parent + "; " + hashCode());
if (parent != null && parent.getApplication() == getApplication()) {
finish();
} else {
MainMenu.close();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onOptionsMenuClosed(Menu menu) {
// Nothing else to do, closing the Activity.
finish();
}
public void displaySpeechRecognizer() {
Log.i("MainMenu", "Entered displaySpeechRecognizer");
Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
startActivityForResult(speechIntent, SPEECH_REQUEST);
Log.i("MainMenu", "Finished displaySpeechRecognizer. startActivityForResult called.");
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i("MainMenu", "onActivityResult entered from MainMenu");
switch (requestCode) {
case SPEECH_REQUEST:
Log.i("MainMenu", "onActivityResult enters SPEECH_REQUEST case");
if (resultCode == RESULT_OK) {
Log.i("MainMenu", "onActivityResult enters RESULT_OK for voice cap");
List<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
String spokenText = results.get(0);
Log.i("MainMenu", "SpokenText:" + spokenText);
holdText = spokenText;
if (holdText != "") {
displayPostMenu();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
You say this is a "menu activity", so does that mean that it's attached to a live card?
If so, are you overriding onOptionsMenuClosed and calling finish inside it?
If you are, the menu activity will finish and destroy itself before the speech activity returns, so there will be no place for the result to go back to.
One approach to fix this would be to use a flag to indicate whether you should defer the call to finish when the menu is closed, and make that call conditionally inside onOptionsMenuClosed based on that flag. Then, set that flag in your displaySpeechRecognizer method and wait until the end of your onActivityResult processing to call finish instead.
Something like this should work (written without testing, may contain typos):
private boolean shouldFinishOnMenuClose;
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// By default, finish the activity when the menu is closed.
shouldFinishOnMenuClose = true;
// ... the rest of your code
}
private void displaySpeechRecognizer() {
// Clear the flag so that the activity isn't finished when the menu is
// closed because it will close when the speech recognizer appears and
// there won't be an activity to send the result back to.
shouldFinishOnMenuClose = false;
// ... the rest of your code
}
#Override
public void onOptionsMenuClosed(Menu menu) {
super.onOptionsMenuClosed();
if (shouldFinishOnMenuClose) {
finish();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SPEECH_REQUEST) {
if (resultCode == RESULT_OK) {
// process the speech
}
// *Now* it's safe to finish the activity. Note that we do this
// whether the resultCode is OK or something else (so the menu
// activity goes away even if the user swipes down to cancel
// the speech recognizer).
finish();
}
}
I want to ask how I can use speech to text code on my emulator. My codes work on real device but not work on emulator. The error said :
No Activity found to handle Intent { act=android.speech.action.RECOGNIZE_SPEECH (has extras) }
What can I do?
package net.viralpatel.android.speechtotextdemo;
import java.util.ArrayList;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.Menu;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
protected static final int RESULT_SPEECH = 1;
private ImageButton btnSpeak;
private TextView txtText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtText = (TextView) findViewById(R.id.txtText);
btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
btnSpeak.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(
RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
try {
startActivityForResult(intent, RESULT_SPEECH);
txtText.setText("");
} catch (ActivityNotFoundException a) {
Toast t = Toast.makeText(getApplicationContext(),
"Ops! Your device doesn't support Speech to Text",
Toast.LENGTH_SHORT);
t.show();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_SPEECH: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> text = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
txtText.setText(text.get(0));
}
break;
}
}
}
}
You need to install onto your emulator an app that contains an Activity that handles the RECOGNIZE_SPEECH-intent. You might be able to find Google's VoiceSearch.apk on the web.
There are certain things you can't test using an emulator. Speech to text is on of them.
I'm not sure about this, but you can't use this android feature with the emulator.
No matter what, you should handle this exception with a try/ catch an give some feedback to the user.
You can check if there is that Activity in current device running your app doing something like:
PackageManager pm = context.getPackageManager();
List<ResolveInfo> infoList = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
if (infoList.size() == 0) {
/** Show some feedback to user if there is the activity. Something like "Your device is not abl to run this feature..."*/
}else{
/**Your current code goes here.*/
}
Let me know if it helps.
You need to install com.google.android.voicesearch application on target device which has no voice recognition activity like:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch"));
startActivity(browserIntent);
if you try to install Google's Search app - it won't help since it doesn't contain the VR engine inside and thus it will try to do the same - install com.google.android.voicesearch app but it could fail due to a bug in package name (pname:com.google.android.voicesearch instead of just pure package name). However com.google.android.voicesearch installation might be impossible due to "Not available in your country".
You might need a virtual SD Card. You can refer here
I am using following code to open Android Contacts
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnContacts = (Button) findViewById(R.id.btn_contacts);
txtContacts = (TextView) findViewById(R.id.txt_contacts);
btnContacts.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
txtContacts.setText("");
Intent intent = new Intent(Intent.ACTION_PICK, People.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
});
}
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (PICK_CONTACT):
if (resultCode == Activity.RESULT_OK) {
//display picked contact data.
}
}
}
Now I want to put Button at the top of this Contact activity when opened or add my own Menu in this Activity
Can any one guide me? Is this possible or not? If yes then please tell how to achieve this?
I don't believe that is possible as each Activity in Android is working on its own and by starting the Intent, you are basically giving the new Activity the focus (and control).
One way to do something like this would be to build a custom contact list activity that uses the public data providers to access the contacts and simply lists them then. Then you could add as many custom functions as you like or even add Intents for original actions (like viewing a contact's details).