Trigger Speech Recognition in Android Service - java

I have been trying to find a way to implement the SpeechRecognizer API in a Service (runs in background) so that when a condition is met, it will open the speech recognizer without having to be within the application. My question is whether this is even possible natively? And if so, how would it be done?

Here is my code snippet. You can use the recognition listener like this in a service.
I'm not sure how you are scheduling your services, I have left that to you. But you can do something like this. (I have not added code for restarting service / starting it in a timer etc.)
public class MyService extends Service {
protected static SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
Context c;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//if condition is met then do this
SpeechRecognitionListener h = new SpeechRecognitionListener();
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(h);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
Log.d("avail", " " + mSpeechRecognizer.isRecognitionAvailable(this));
if (mSpeechRecognizer.isRecognitionAvailable(this))
Log.d("created", "onBeginingOfSpeech");
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
c= getApplicationContext();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
class SpeechRecognitionListener implements RecognitionListener {
#Override
public void onReadyForSpeech(Bundle bundle) {
Log.d("onReady", "service");
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float v) {
}
#Override
public void onBufferReceived(byte[] bytes) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int i) {
Log.d("ERROR","ERROR");
}
#Override
public void onResults(Bundle resultsBundle) {
Log.d("Results", "onResults");
}
#Override
public void onPartialResults(Bundle bundle) {
}
#Override
public void onEvent(int i, Bundle bundle) {
}
}
}

Related

Is there a way to use Android's Speech Recognition API to output true/false, even when the phone is off?

I'm trying to detect speech for a feature in a machine learning algorithm, but I'm having a hard time running the Speech Recognition API in the background and while the phone is off. I've tried to put the SpeechRecognizer in a service, however, the service gets killed and reports this error:
E/ActivityThread: Service com.test.speechrecognition.services.SpeechDetectionService has leaked ServiceConnection android.speech.SpeechRecognizer$Connection#914d0fc that was originally bound here
android.app.ServiceConnectionLeaked: Service com.test.speechrecognition.services.SpeechDetectionService has leaked ServiceConnection android.speech.SpeechRecognizer$Connection#914d0fc that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.(LoadedApk.java:1835)
at android.app.LoadedApk.getServiceDispatcherCommon(LoadedApk.java:1707)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:1686)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1819)
at android.app.ContextImpl.bindService(ContextImpl.java:1749)
at android.content.ContextWrapper.bindService(ContextWrapper.java:756)
at android.speech.SpeechRecognizer.startListening(SpeechRecognizer.java:286)
at com.test.speechrecognition.services.SpeechDetectionService$1.run(SpeechDetectionService.java:56)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7664)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I'm needing the application to track if it detected speech every minute ever ten minutes or so.
Here's the MainActivity.java and SpeechDetectionService.java code:
Main Activity:
public class MainActivity extends AppCompatActivity {
// Create speechRecognizer object
private SpeechRecognizer speechRecognizer;
public static final Integer RecordAudioRequestCode = 1;
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Check if permissions have been granted
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
checkPermission();
}
}
#Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart:start SpeechDetectionService");
startService(new Intent(this, SpeechDetectionService.class));
}
// Permission check function
private void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO},RecordAudioRequestCode);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == RecordAudioRequestCode && grantResults.length > 0) {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
}
}
SpeechDetectionService:
public class SpeechDetectionService extends Service {
private static final String TAG = SpeechDetectionService.class.getSimpleName();
private SpeechRecognizer speechRecognizer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind()");
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate()");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.d(TAG, "onStartCommand");
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
final Intent speechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
final Handler handler = new Handler();
final int delay = 10000;
handler.postDelayed(new Runnable() {
public void run() {
speechRecognizer.startListening(speechRecognizerIntent);
handler.postDelayed(this, delay);
}
}, delay);
speechRecognizer.setRecognitionListener(new RecognitionListener() {
#Override
public void onReadyForSpeech(Bundle params) {
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float rmsdB) {
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int error) {
}
#Override
public void onResults(Bundle results) {
}
#Override
public void onPartialResults(Bundle partialResults) {
}
#Override
public void onEvent(int eventType, Bundle params) {
}
});
return START_STICKY;
}

Getting error while setting speechRecognition.startListenenig() and pass the intent

I get error when I set SPR.startlistenening() method I want to use continuously speech recognition and perform tasks based on results.
I am making an app that countinuously uses speech recognition and do specific task on results:
#Override
protected void onStart() {
super.onStart();
setSPR();
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,1);
SPR.startListening(intent);
}
private void setSPR() {
if (SpeechRecognizer.isRecognitionAvailable(this)){
SpeechRecognizer.createSpeechRecognizer(this);
SPR.setRecognitionListener(new RecognitionListener() {
#Override
public void onReadyForSpeech(Bundle params) {
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float rmsdB) {
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int error) {
}
#Override
public void onResults(Bundle bundle) {
ArrayList<String> results = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
setRecognitionResults(results.get(0));
}
#Override
public void onPartialResults(Bundle partialResults) {
}
#Override
public void onEvent(int eventType, Bundle params) { }
});
}
}
Error >>>
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.speech.SpeechRecognizer.startListening(android.content.Intent)'
on a null object reference at
com.teamdev.talkingtorch.MainActivity.onStart(MainActivity.java:74) at
android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1341)
at android.app.Activity.performStart(Activity.java:7278) at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2937)

Loading multiple AdMob videos

For demonstration purposes, the app has one activity that simply offers this:
You click a button, view a rewarded video, and you are rewarded with whatever.
The Problem
How can I load the videos? From what I have seen you can only call mAd.loadAd() once. There are 3 videos, each with their own AD UNIT ID. Each ad unit can have its own listener, but only one video loads so it doesn't matter...
When trying to load multiple videos
For example:
mAd1.loadAd("AD_UNIT_1", new AdRequest.Builder().build());
mAd2.loadAd("AD_UNIT_2", new AdRequest.Builder().build());
mAd3.loadAd("AD_UNIT_3", new AdRequest.Builder().build());
results in only the last video being loaded and this in log:
W/Ads: Loading already in progress, saving this object for future refreshes.
onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAd1 = MobileAds.getRewardedVideoAdInstance(this);
mAd2 = MobileAds.getRewardedVideoAdInstance(this);
mAd3 = MobileAds.getRewardedVideoAdInstance(this);
listeners...
mAd1.loadAd() etc
}
Thank you for your help
Edit: It's clear I am thinking about this problem wrong. I have 5+ ad zones that each will play a rewarded video and give a different reward (for example, one gives coins, one gives a level up, and so on..). There is no reason to load 5 videos. I should load one in onCreate(), so it's ready when needed, then load it again after the item is rewarded so it's ready for next time.
So the question remains, if there is just the one video, and thus one ad zone, being loaded onCreate() then how can I track what reward to give?
Here's a simple solution...
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAd = MobileAds.getRewardedVideoAdInstance(this);
mAd.setRewardedVideoAdListener(new RewardedVideoAdListener() {
#Override
public void onRewarded(RewardItem rewardItem) {
switch(Constants.currentAd) {
case("REWARD1"):
//do something
Constants.currentAd = "";
break;
case("REWARD2"):
//do something
Constants.currentAd = "";
break;
case("REWARD3"):
//do something
Constants.currentAd = "";
break;
}
}
});
mAd.loadAd("REWARDED_VIDEO_UNIT_ID", new AdRequest.Builder().build());
}
public void showRewardedVideo() {
if (mAd.isLoaded()) {
mAd.show();
}
}
Constants.java
public class Constants {
public static String currentAd = "";
}
Showing the ad after button click
rewardButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Constants.currentAd = "REWARD1";
dismiss();
((MainActivity) getActivity()).showRewardedVideo();
}
});
REWARDED_VIDEO_UNIT_ID is one ad unit for rewarded video in AdMob...remove the rest. No need for other units, you can track whatever you like in the listener.
Other simple soluction...
AbstractRewardVideo.java
public abstract class AbstractRewardVideo {
private RewardedVideoAd mAd;
private String adId = "ca-app-pub...";
private Activity activity;
abstract protected RewardedVideoAdListener getListener();
public void init(Activity activity) {
this.activity = activity;
mAd = MobileAds.getRewardedVideoAdInstance(activity);
setAdId(adId);
loadRewardedVideoAd();
}
public Activity getActivity(){
return this.activity;
}
public void loadRewardedVideoAd() {
mAd.loadAd(adId, new AdRequest.Builder().build());
}
public void showVideo(){
setListener(getListener());
if (mAd.isLoaded()) {
mAd.show();
} else {
Utils.exibirToast("Don't loaded!");
}
}
public void setAdId(#NonNull String id){
this.adId = id;
}
public void setListener(RewardedVideoAdListener listener){
mAd.setRewardedVideoAdListener(listener);
}
}
Reward1.java
public class Reward1 extends AbstractRewardVideo {
public Reward1(Activity activity) {
init(activity);
}
#Override
protected RewardedVideoAdListener getListener() {
return new Listener();
}
private class Listener implements RewardedVideoAdListener {
#Override
public void onRewarded(RewardItem rewardItem) {
//Do something...
}
public void onRewardedVideoAdLoaded() {}
public void onRewardedVideoAdOpened() {}
public void onRewardedVideoStarted() {}
public void onRewardedVideoAdClosed() { loadRewardedVideoAd(); }
public void onRewardedVideoAdLeftApplication() {}
public void onRewardedVideoAdFailedToLoad(int i) {}
}
}
Reward2.java
public class Reward2 extends AbstractRewardVideo {
public Reward2(Activity activity) {
init(activity);
}
#Override
protected RewardedVideoAdListener getListener() {
return new Listener();
}
private class Listener implements RewardedVideoAdListener {
#Override
public void onRewarded(RewardItem rewardItem) {
//Do something...
}
public void onRewardedVideoAdLoaded() {}
public void onRewardedVideoAdOpened() {}
public void onRewardedVideoStarted() {}
public void onRewardedVideoAdClosed() { loadRewardedVideoAd(); }
public void onRewardedVideoAdLeftApplication() {}
public void onRewardedVideoAdFailedToLoad(int i) {}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity{
Reward1 reward1;
Reward2 reward2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
reward1 = new Reward1(this);
reward2 = new Reward1(this);
...
reward1.showVideo();
...
reward2.showVideo();
}
}
MobileAds.initialize ( this, "ca-app-pub-4761500786576152~8215465788" );
RewardedVideoAd mAd = MobileAds.getRewardedVideoAdInstance(this);
mAd.setRewardedVideoAdListener(Video_Ad.this);
}
#Override
public void onRewardedVideoAdLoaded() {
}
#Override
public void onRewardedVideoAdOpened() {
}
#Override
public void onRewardedVideoStarted() {
}
#Override
public void onRewardedVideoAdClosed() {
}
#Override
public void onRewarded(RewardItem rewardItem) {
}
#Override
public void onRewardedVideoAdLeftApplication() {
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
}
#Override
public void onRewardedVideoCompleted() {
}

Stopping Android services from an extended Application class

I'm having some troubles trying to stop a services which I started previously on the onCreate() of class that is extended of an Android Application class. The GPS is supposed to be running during the execution of the app (that part is working fine) but when the app is closed the service is still running. I tried to use the onTerminate() because onClose() doesn´t exist in Applicaction class and the service keep running.
public class ControlEntrega extends Application {
public GPSBean posicion;
public ServicioGPS servicio;
public void onCreate() {
Log.d(TAG,"onCreate");
super.onCreate();
usuario=null;
cliente=null;
entrega=null;
dal=new DAL(getApplicationContext());
crearDB();
util=new Utilitario();
servicio=new ServicioGPS();
posicion=new GPSBean();
iniciarGPS();
}
#Override
public void onTerminate() {
super.onTerminate();
Log.d(TAG,"onTerminate");
try {
stopService(new Intent(this,ServicioGPS.class));
} catch (Exception e) {
Log.d(TAG,"onTerminate error: "+e.getMessage());
}
}
}
The Service Class:
public class ServicioGPS extends Service implements LocationListener{
String TAG=ServicioGPS.class.getCanonicalName();
LocationManager locationManager=null;
public int tiempoGPS=1;
public int distanciaMetros=10;
Intent notificacion;
ControlEntrega controlador;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"onDestroy");
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
locationManager.removeUpdates(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
controlador= (ControlEntrega)getApplicationContext();
if(controlador!=null){
if(controlador.posicion!=null){
controlador.posicion.imprimir();
}
}
locationManager =(LocationManager)getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria,true);
//LocationManager.GPS_PROVIDER
//LocationManager.NETWORK_PROVIDER
locationManager.requestLocationUpdates(provider,1000 * 60 * tiempoGPS,distanciaMetros,this);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged");
//Seteando los valores del objeto location
if(controlador!=null){
Log.d(TAG, "seteando bean GPS");
controlador.posicion=new GPSBean();
controlador.posicion.latitud=location.getLatitude();
controlador.posicion.longitud=location.getLongitude();
controlador.posicion.altitud=location.getAltitude();
controlador.posicion.precision=location.getAccuracy();
controlador.posicion.proveedor=location.getProvider();
controlador.posicion.tiempo=location.getTime();
controlador.posicion.velocidad=location.getSpeed();
controlador.posicion.imprimir();
}
//Notificación
Intent notificacion = new Intent(getString(R.string.intentGPS));
sendBroadcast(notificacion);
//Se para asi mismo, ya se calendarizo antes
stopSelf();
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
There is a way I could know when the application stops completely? So I can stop the service.
Regards
Alfredo
public class EyeCastApplication extends Application {
static Context context;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
context = getApplicationContext();
}
/***
* start Heart Beat Loop
*/
public static void stopHeartBeatLoop() {
context.stopService(new Intent(context, CmdConnectService.class));
}
enter code here
enter code here
}

Android Background Service didn't stop/terminate

I am using a Service to play background Music. The problem is that the music continues playing when i have finished the activity.
Here is code From Main Activity which starts the service
Intent svc=new Intent(HomeActivity.this, BackgroundSoundService.class);
startService(svc);
BackgroundSoundService.java
public class BackgroundSoundService extends Service {
private static final String TAG = null;
public static MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d("atMedia", "Backround Music playing");
player = MediaPlayer.create(this, R.raw.background);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
Try to stop service from your MainActivity:
Intent svc=new Intent(HomeActivity.this, BackgroundSoundService.class);
stopService(svc);
You have to call selfStop() method inside your service.
or use stopService() API

Categories

Resources