I'm developing an app for android that uses TTS. I've created a splash screen where I check if the TTS engine is installed and in case that is not installed, it goes to Google Play to download it.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
...
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
...
if (requestCode == PersonalTextToSpeech.MY_DATA_CHECK_CODE)
{
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS)
{
mTts = new TextToSpeech(context, this);
} else
{
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
context.startActivity(installIntent);
}
}
}
It was working fine in Samsung devices with 2.2 and 2.3.x OS. It goes to Google Play if needed, but now I've tried with a Samsung Galaxy S3 (with 4.1.1), which has 2 TTS installed by default (Samsung and Google), so I get a dialog asking to select one.
If the user selects Samsung it works perfect, but if the user selects Google, it goes to Settings --> Language and input --> Text-to-speech output --> Google Text-to-speech Engine --> Settings --> Install Voice Data and I get this:
So, I have 3 questions/problems:
Is there any way to force programatically to use Samsung TTS without asking?
My device is from Spain, but if I change the language to English, this one is not available in my Google list of TTS languages, and I can't find a way to add it (see screenshot #2).
If I change the language to spanish, this language is supposed to be installed in my device (see screenshot #2), but for some reason TTS resultCode is LANG_NOT_SUPPORTED (-2).
In fact, right now while I write this, I've just found something weird.
If you select Samsung TTS, it will "work" (resultCode = CHECK_VOICE_DATA_PASS (1)), but the "voice sound" will change depending on how you have your setting (view Screenshot #3):
If you choose Samsung, it will use Samsung TTS or Google TTS according to what you have selected in:
Settings --> Language and input --> Text-to-speech output.
So, even if you select Samsung TTS, you could be using Google TTS, but if you select Google TTS directly (see Screenshot #1) it will fail.
Can someone explain me what I'm doing wrong?
Thanks for your help.
i too stucked in this problem and i solved it by just replacing a code in my onActivityResult.
Instead of checking for TTS Data,i just checked for available voices.
if (availableLanguages.isEmpty()) {
// no language data available, prompt for install
Intent installIntent = new Intent();
installIntent
.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
} else {
// some language data is available, create TTS instance
myTTS = new TextToSpeech(this, this);
}
Related
I am trying to follow this tutorial for my Android wearables app:
https://www.sitepoint.com/using-android-text-to-speech-to-create-a-smart-assistant/
Here is the code for my Activity file:
import android.speech.tts.TextToSpeech;
public class ScoresActivity extends Activity {
private TextToSpeech tts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scores);
// Text to speech setup
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
System.out.println("status: " + status); // Always returns -1
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.US);
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "This Language is not supported");
}
speak("Hello");
} else {
Log.e("TTS", "Initilization Failed!");
}
}
});
}
I always see this error message in the Logs:
Is it even possible to run the Android SDK's text-to-speech library on wearable devices? I tried running this code on a mobile Android app and everything worked fine.
Yes this is possible as they even have docs for this feauture in Adding Voice Capabilities:
Voice actions are an important part of the wearable experience. They let users carry out actions hands-free and quickly. Wear provides two types of voice actions:
System-provided These voice actions are task-based and are built into the Wear platform. You filter for them in the activity that you
want to start when the voice action is spoken. Examples include "Take
a note" or "Set an alarm".
App-provided These voice actions are app-based, and you declare them just like a launcher icon. Users say "Start " to use these voice
actions and an activity that you specify starts.
You can also check this SO post for additional reference.
Depends which device you have. I think it needs to have android wear 2.0 and then possibly a speaker would make it more likely. Im only saying that based on knowing my nixon mission does not have tts installed but the lg urbane 2 does. Very annoying as tts could be used over bluetooth.
Would be good to get a full listed of supported devices.
I have prepared a simple test project for this question at GitHub.
I am trying to create an Android app, which would scan a QR code from a computer screen and then use the data (MAC address and PIN or hash) for easy pairing (bonding) with a Bluetooth device.
Similar to the popular InstaWifi app - but for Classic Bluetooth.
For testing purposes I don't do any barcode scanning yet, but just display a list of devices:
After user touches one of the devices, pairing is tried in MainActivity.java:
private void startBluetoothPairing(BluetoothDevice device) {
Intent pairingIntent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_PIN);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 1234);
//device.setPin(new byte[]{1,2,3,4}); <- DOES NOT CHANGE ANYTHING
//device.setPairingConfirmation(false);
startActivityForResult(pairingIntent, REQUEST_BT_SETTINGS);
}
Unfortunately, the popup still asks for PIN:
Because I have actually specified a PIN in my source code, I was actually expecting another, simpler system dialog to be shown (this one is shown when doing NFC OOB pairing):
From searching for solutions, I know that there is a setPin() method, but it is not applicable here (or is it?) - because I am trying to pair the whole smartphone to the Bluetooth device and not just the app...
My question: How to make Android OS to show the simple Cancel/Pair dialog?
Searching for Bluetooth pairing request string at GitHub has not shown any hints...
UPDATE: On unrealsoul007's suggestion (thanks) I have update the source code in MainActivity.java and now the simple Cancel/Pair dialog is displayed:
private void startBluetoothPairing(BluetoothDevice device) {
Intent pairingIntent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
pairingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(pairingIntent, REQUEST_BT_PAIRING);
}
However I am not sure how to complete the pairing process - because onActivityResult is called with resultCode=0 even before the dialog is closed:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
// this is called before user clicks Cancel or Pair in the dialog
if (requestCode == REQUEST_BT_PAIRING) {
if (resultCode == Activity.RESULT_OK) { // 0 != -1
Log.d("XXX", "Let#s pair!!!!"); // NOT CALLED
}
return;
}
}
You are being prompted for entering the pin because that is what you are requesting in your pairingIntent.
Instead of using
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_PIN);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 1234);
Use
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PASSKEY_CONFIRMATION);
As mentioned here,
The user will be prompted to confirm the passkey displayed on the
screen or an app will confirm the passkey for the user.
I have a working application that I would like to add voice commands. The current application transmits data back and forth over bluetooth on a periodic (timer) basis. The user can press Buttons and NumberPickers to modify the data being sent over bluetooth. There is also data received from the bluetooth link, and displayed in textViews. This application is currently working correctly.
What I would like to do is add voice command capability, so that the user has either the choice of pressing the Buttons/NumberPickers, or can change the values with only voice commands.
I have tested some of the Speech-to-Text examples that can be found on various websites. I have succesfully tested an App that uses RecognizerIntent. Upon a button press, a dialog pops up and you can speak words or phrases, and it correctly displays the result on the screen.
So, I think that I am close, but I'm not really sure how I can combine the Speech-to-Text with my current Bluetooth App. I don't want the user to have to press a button, I just want the App to be constantly listening. Also, I don't want the pop-up Voice Dialog on the screen.
My hardware is a Samsung tablet running Android 4.1.
I am relatively new to Android programming, so any advice (no matter how basic) is appreciated. Thanks.
To prevent the pop-up Voice Dialog on the screen, you can use the ACTION_RECOGNIZE_SPEECH intent:
private static int SR_CODE = 123;
/**
* Initializes the speech recognizer and starts listening to the user input
*/
private void listen() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
//Specify language
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.ENGLISH)
// Specify language model
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
// Specify how many results to receive
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
// Start listening
startActivityForResult(intent, SR_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SR_CODE && resultCode == RESULT_OK) {
if(data!=null) {
//Retrieves the best list SR result
ArrayList<String> nBestList = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
String bestResult = nBestList.get(0);
Toast.makeText(getApplicationContext(), bestResult, Toast.LENGTH_LONG).show;
}else {
//Reports error in recognition error in log
Log.e(LOGTAG, "Recognition was not successful");
}
}
Concerning the other issue, " I don't want the user to have to press a button, I just want the App to be constantly listening":
I'll recommend using CMUSphinx to recognize speech continuously. To achieve continuous speech recognition using google speech recognition api, you might have to resort to a loop in a background service which will take too much resources and drains the device battery.
On the other hand, Pocketsphinx works really great. It's fast enough to spot a key phrase and recognize voice commands behind the lock screen without users touching their device. And it does all this offline.
You can try the demo.
If you really want to use google's api as I've demonstrated above, see this
The issue is that I need to install an apk(non market app) and for this, the user need to activate the unknown source setting, so i send him (if he didn't have it activated) to the settings so he can turn on the option, the issue is that i tested it in different phones and in samsung that option is on applications while in htcs phones is on security. i want send the user to that option but i don't know how to do it
I read about this and no one knows exactly how to do it
this is my code
int canInstallFromOtherSources = Settings.Secure.getInt(ctx2,Settings.Secure.INSTALL_NON_MARKET_APPS);
if(canInstallFromOtherSources == 0)
{
Intent intentSettings = new Intent();
intentSettings.setAction(android.provider.Settings.ACTION_APPLICATION_SETTINGS);
startActivity(intentSettings);
}
You can do it with the following line (changing to the corresponding action):
startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), REQUEST_CODE_ENABLE_LOCATION_PROVIDERS);
Check Android Settings documentation.
I think you should use ACTION_SECURITY_SETTINGS and one of ACTION_APPLICATION_SETTINGS or ACTION_APPLICATION_DEVELOPMENT_SETTINGS.
And here (line 304), you've got a working example of one of my apps: Tureame
I'm making use of Text to Speech - TTS in my Android app.. I've pasted the code below.. TTS is working fine, however the voice/text it speaks is not very clear.. It speaks really quick, so that it is not fully understandable.. I tried setting Locale.US, and used setPitch or setSpeechRate but it is not really convincing. I felt that there is some problem with my phone (Samsung S2).. So tried installing Google Translate TTS app from Google Play store.. In that app the voice was really clear.
My app will be used by Kids.. so want to make sure that the voice is really clear.
I'm breaking my head for the past few days to fix this problem.. Would be great if you could give me some pointers on where I'm doing wrong or how to improve??
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.getDefault());
//tts.setSpeechRate((float) 0.8);
//tts.setPitch(1.0f);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "This Language is not supported");
} else {
speakOut(0);
}
} else {
Intent installIntent = new Intent();
installIntent.setAction(
TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
private void speakOut(int position) {
tts.speak("Some text goes here", TextToSpeech.QUEUE_FLUSH, null);
}
Note: I tried setting value as 0.5f,0.8f etc., in both setPitch and setSpeechRate but still all the voice is not really clear as in GoogleTranslate App.
Your code looks fine.
All tts libraries are shared across the system. Samsung comes with its own tts library. Rest of phones use Pico TTS. The great thing is that your app is independent from the library and you can download as many TTS libs as you want so that when you request the TTS intent the user will be prompt a pop-up to select which of their TTS synth they want for your app.
For me Pico TTS was working fine. Velocity / speech rate was normal, I just put the tone (pitch) a bit up to de-robotize the feeling a bit.
tts.setPitch(1.1f);
Try with Pico TTS and answer back.