I'm trying to get Android's TTS to run inside a service, but I have no idea why it isn't working, it compiles, doesn't crash, but it just doesn't work.
The Toast notification do work though.
package alarm.test;
import android.app.Service;
import com.google.tts.TextToSpeechBeta;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyAlarmService extends Service {
private TextToSpeechBeta myTts;
private TextToSpeechBeta.OnInitListener ttsInitListener = new TextToSpeechBeta.OnInitListener() {
public void onInit( int arg0, int arg1 ) {
myTts.speak("", 0, null);
}
};
#Override
public void onCreate() {
// TODO Auto-generated method stub
myTts = new TextToSpeechBeta( this,
ttsInitListener );
Toast.makeText(this, "MyAlarmService.onCreate()", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
myTts.speak("something is working", TextToSpeechBeta.QUEUE_FLUSH, null);
Toast.makeText(this, "MyAlarmService.onBind()", Toast.LENGTH_LONG).show();
return null;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "MyAlarmService.onDestroy()", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Toast.makeText(this, "MyAlarmService.onStart()", Toast.LENGTH_LONG).show();
}
#Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(this, "MyAlarmService.onUnbind()", Toast.LENGTH_LONG).show();
return super.onUnbind(intent);
}
}
You can do like below: It's working for me.
You have to create an activity to start this service, like this: this.startService(intent)
public class TTSService extends Service implements TextToSpeech.OnInitListener{
private String str;
private TextToSpeech mTts;
private static final String TAG="TTSService";
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
mTts = new TextToSpeech(this,
this // OnInitListener
);
mTts.setSpeechRate(0.5f);
Log.v(TAG, "oncreate_service");
str ="turn left please ";
super.onCreate();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
if (mTts != null) {
mTts.stop();
mTts.shutdown();
}
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
sayHello(str);
Log.v(TAG, "onstart_service");
super.onStart(intent, startId);
}
#Override
public void onInit(int status) {
Log.v(TAG, "oninit");
if (status == TextToSpeech.SUCCESS) {
int result = mTts.setLanguage(Locale.US);
if (result == TextToSpeech.LANG_MISSING_DATA ||
result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.v(TAG, "Language is not available.");
} else {
sayHello(str);
}
} else {
Log.v(TAG, "Could not initialize TextToSpeech.");
}
}
private void sayHello(String str) {
mTts.speak(str,
TextToSpeech.QUEUE_FLUSH,
null);
}
}
https://developer.android.com/reference/android/speech/tts/TextToSpeechService.html
since API Level 14, android has added a default TextToSpeech Service class that does what you want.
Related
First time to use AIDL. I want to test it.
Below is my code:
MainActivity:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "CalculateClient";
private Button btnCalculate;
private EditText etNum1;
private EditText etNum2;
private TextView tvResult;
private CalculateInterface mService;
private ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
logE("disconnect service");
mService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
logE("connect service");
mService = CalculateInterface.Stub.asInterface(service);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle args = new Bundle();
Intent intent = new Intent("com.example.calculate.CalculateService");
intent.putExtras(args);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
etNum1 = (EditText) findViewById(R.id.editText);
etNum2 = (EditText) findViewById(R.id.editText2);
tvResult = (TextView) findViewById(R.id.textView);
btnCalculate = (Button) findViewById(R.id.button);
btnCalculate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
logE("Start..");
try {
double num1 = Double.parseDouble(etNum1.getText().toString());
double num2 = Double.parseDouble(etNum2.getText().toString());
logE(Double.toString(num1));
logE(Double.toString(num2));
String answer = "Result:" + mService.doCalculate(num1, num2); //this line BUG
tvResult.setTextColor(Color.BLUE);
tvResult.setText(answer);
} catch (RemoteException ignored) {
}
}
});
}
private void logE(String str) {
Log.e(TAG, "--------" + str + "--------");
}
}
MyTestService:
package com.radio.miao.aidltest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyTestService extends Service {
private static final String TAG = "CalculateService";
private final CalculateInterface.Stub mBinder = new CalculateInterface.Stub() {
#Override
public double doCalculate(double a, double b) throws RemoteException {
// TODO Auto-generated method stub
Log.e("Calculate", "remote");
return b + a;
}
};
private static void logE(String str) {
Log.e(TAG, "--------" + str + "--------");
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
logE("onBind()");
return mBinder;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
logE("onCreate()");
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
logE("onStart()");
super.onStart(intent, startId);
}
#Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
logE("onUnbind()");
return super.onUnbind(intent);
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
logE("onDestroy()");
super.onDestroy();
}
}
<service android:name="com.radio.miao.aidltest.MyTestService">
<intent-filter>
<action android:name="com.radio.miao.aidltest.MyTestService" />
</intent-filter>
package com.radio.miao.aidltest;
// Declare any non-default types here with import statements
interface CalculateInterface {
double doCalculate(double a, double b);
}
The error is
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.radio.miao.aidltest.MainActivity$2.onClick(MainActivity.java:79)
The following line creates an intent for an invalid service:
Intent intent = new Intent("com.example.calculate.CalculateService");
The correct should be:
Intent intent = new Intent(this,MyTestService.class);
public class MainActivity extends Activity implements OnClickListener {
Button start,stop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start=(Button) findViewById(R.id.button1);
stop=(Button) findViewById(R.id.button2);
start.setOnClickListener(this);
stop.setOnClickListener(this);
TelecomManager tm=(TelecomManager) getSystemService(TELEPHONY_SERVICE);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i=new Intent(this,MyService.class);
if(v.getId()==R.id.button1) {
startService(i);
} else if(v.getId()==R.id.button2) {
stopService(i);
}
}
}
MyService.java
public class MyService extends Service {
MediaPlayer player;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
player=MediaPlayer.create(this, R.raw.song1);
}
#Override
#Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
player.start();
super.onStart(intent, startId);
}
#Override
public void onDestroy() {
if (!(player == null)) {
if (player.isPlaying()) {
player.stop();
player.release();
player = null;
}
}
In your Service you could register a PhoneStateListener via TelephonyManager.listen(PhoneStateListener, int)
But as the interface is quite big you could also just register a BroadcastReceiver in your Service
IntentFilter phoneStateFilter = new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(phoneStateReceiver, phoneStateFilter);
In your BroadcastReceiver you check the phone state by
String phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
I know there are quite a few posts about this already and I have read pretty much all of them (or so it feels at least). Yet my service refuses to work, at all.
In short: I have a widget that should launch the speecrecognizer service when clicked on. The service should then listen to input and (for now) print it out to logcat.
The service starts correctly (the logs in oncreate and ondestroy are printed) but the actual voice recognition part doesn't work.
I have added the service in the android manifest and added the "android.permission.RECORD_AUDIO" permission.
Part of the issue is that
SpeechRecognizer.isRecognitionAvailable(this)
returns false.
Here's the important bit of code from the service:
#Override
public void onCreate() {
super.onCreate();
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(mListener);
if (SpeechRecognizer.isRecognitionAvailable(this))
Log.d(TAG, "we are go for speech recognition");
else
Log.d(TAG, "red light for speech recognition :c");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "i'm being destroyed :c");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "we made it");
playTtsForMessage("We made it", true);
speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
mSpeechRecognizer.startListening(speechIntent);
Log.d(TAG, "started listening");
return super.onStartCommand(intent, flags, startId);
}
private void broadcastStopIntent() {
Intent intent = new Intent(Intents.ACTION_VOICE_COMMANDS_STOP);
AddApplication.getInstance().sendBroadcast(intent, null);
}
All the log outputs get printed, apart from the ones i've placed inside the listener.
If interested, here's the listener:
private RecognitionListener mListener = new RecognitionListener() {
#Override
public void onReadyForSpeech(Bundle params) {
// TODO Auto-generated method stub
}
#Override
public void onBeginningOfSpeech() {
// TODO Auto-generated method stub
Log.d(TAG, "speech started");
}
#Override
public void onRmsChanged(float rmsdB) {
// TODO Auto-generated method stub
}
#Override
public void onBufferReceived(byte[] buffer) {
// TODO Auto-generated method stub
}
#Override
public void onEndOfSpeech() {
// TODO Auto-generated method stub
Log.d(TAG, "speech ended");
broadcastStopIntent();
}
#Override
public void onError(int error) {
// TODO Auto-generated method stub
}
#Override
public void onResults(Bundle results) {
// TODO Auto-generated method stub
ArrayList<String> spoken = results
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
String msg = "";
for (String s : spoken) {
msg += s + " ";
}
Log.d(TAG, "what i understood from that was: " + msg);
WidgetVoiceCommandProviderIntentService.this.stopSelf();
}
#Override
public void onPartialResults(Bundle partialResults) {
// TODO Auto-generated method stub
}
#Override
public void onEvent(int eventType, Bundle params) {
// TODO Auto-generated method stub
}
};
I tried this guy's workaround: Android Speech Recognition as a service on Android 4.1 & 4.2
Which yielded no results. Any suggestions?
I'm trying to write a simple app that updates the MainActivity with the Lat/Lng values returned by the service. But it always returns the null value. I have added permissions and added TheService.java as service in AndroidManifest.xml file...Kindly tell me where I have gone wrong.
MainActivity.java
public class MainActivity extends Activity {
TextView tv1, tv2;
IntentFilter filter;
receive rec;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 =(TextView)findViewById(R.id.textView1);
tv2 = (TextView)findViewById(R.id.textView2);
filter = new IntentFilter("Updated");
rec = new receive();
Intent gps_int = new Intent(this,TheService.class);
startService(gps_int);
}
#Override
public void onPause()
{
super.onPause();
unregisterReceiver(rec);
}
#Override
public void onResume()
{
super.onResume();
rec = new receive();
registerReceiver(rec, filter);
}
#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;
}
public class receive extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
tv1.setText(intent.getExtras().getString("lat"));
tv2.setText(intent.getExtras().getString("lon"));
Toast.makeText(getApplicationContext(), "Toast Executed", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), "BR Latitude "+intent.getExtras().getString("lat"),Toast.LENGTH_SHORT).show();
}
}}
TheService.java
public class TheService extends Service implements LocationListener {
LocationManager lm;
Location loc;
double lat = 0;
double lon = 0;
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
lm=(LocationManager)getSystemService(LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
onLocationChanged(loc);
return START_STICKY;
}
#Override
public void onCreate()
{
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
updateui(location);
}
private void updateui(Location location) {
// TODO Auto-generated method stub
lat = location.getLatitude();
lon = location.getLongitude();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent gps_intent = new Intent("Updated");
gps_intent.putExtra("lat", lat);
gps_intent.putExtra("lon", lon);
sendBroadcast(gps_intent);
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}}
You should use the Google Play Services for the location, that's easier to handle.
What for do you even need a Service? Having a location listener in your Activity is totally fine.
If you want to stay with the Service, than bind the Activity to it, instead of using a Broadcast.
I have a class that extends the AsyncTask.
When the doing background task done, in post executed i get the static properties of other class to equal the result of doing background, n I WANT TO BROADCAST IT OUT SO THAT the on receiver in other class will be update interface
here the code of the onPostExecuted
protected void onPostExecute(String result) {
Log.d(tag, "post executed "+result);
// do sth here
if (result != null){
result = result.trim();
String temp_result[];
if ( result.contains("|") ){
temp_result = result.split("\\|");
MyGPS.location_info = temp_result[1];//
Log.d(result, "contains | : "+MyGPS.location_info);
}else if (result.equalsIgnoreCase("300 OK")){
Log.d(result, "in 300 OK BUT UNKNOWN : "+ result);
MyGPS.location_info = "Unknown";
}else if (result.equalsIgnoreCase("400 ERROR"))
Log.d(result, "400 ERROR : "+ result);
else Log.d(result, "else : "+ result);
//assemble data bundle to be broadcasted
//myFilteredResponseThread = new Intent(GPS_FILTER);
myFilteredResponseThread.putExtra("location_info_post",
MyGPS.location_info);
// CAN"T USE SEND BROADCAST METHOD ?
//myFilteredResponseThread.
//Log.e(">>GPS_Service<<", "location_info"+MyGPS.location_info);
}
}
after that i can't write sendBroadcast method , it is undefined whY?
If I understood u correctly following is the solution.
class MyService extends Service{
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
class GPSListener implements LocationListener{
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
// you can get context as follow
MyService.this.getBaseContext().sendBroadcast(new Intent("Hi"));
}
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
}
}