Is Android speech recognition service busy? - android

I use Android speech recognition service from my application.
It turns out that when two clients attempt to send requests at the same time (say, the user started one voice search from an app, then switched to another application while the search is still active, and launched another search), the service stops working.
Is there a way to determine that there's a voice recognition session in progress, so that I can refuse to start another one?

You should probably be trapping ERROR_RECOGNIZER_BUSY in the onError handler:
#Override
public void onError(int error) {
switch (error) {
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
// do something reasonable
…
}
}
You're most likely (only?) going to receive that on a request to start listening; unfortunately, I'm not aware of any way to test this condition without trying (e.g. I don't think you can pre-detect another process's listener being active to remove a microphone button)
(On stopping listening, you'd only get this error if you were trying to kill another process's listener somehow.)

I was getting this error (ERROR_RECOGNIZER_BUSY) and found out that the package was missing in my intent set up. So I just added this line and it works now:
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
...
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName());

Related

SessionManager.endCurrentSession(false) stops casting

I am using SessionManager to manage a Cast session to a Chromecast device. In my Activity onPause() I have the following code:
val sessionManager = castContext.sessionManager
sessionManager.removeSessionManagerListener(castSessionManagerListener, CastSession::class.java)
sessionManager.endCurrentSession(false)
I found out that the receiver applications stops. I checked the documentation and it says:
public void endCurrentSession (boolean stopCasting)
Ends the current session.
stopCasting Should the receiver application be stopped when ending the current Session.
Even though I use false it still stops the receiver application. Why? I want the receiver application to keep streaming even if my application is in background or closed completely. For example, the YouTube app works that way.

Call Android Activity

I have an application that performs a phone call, but when I send dial directly, the application is in the background and displays the screen of the android default phone call, it must not happen, because when the phone call is made, I need to trigger commands that are in my application. If anyone knows of a possible solution. Thank you.
Below is the my method used to perform a phone call.
private void call() {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:123456789"));
startActivity(callIntent);
} catch (ActivityNotFoundException activityException) {
Log.e("Dialing", "Call failed", e);
}
}
Hope I got your question right. If you are trying to create an app to replace default phone call handling app, then I guess you should know that it's not a cake walk.
Firstly let me make it clear that you simply can't create a phone app to replace default app.
If you really want to do it then you need to get the Android source code, recompile it by adding your phone app and flash it on a rooted device.
Shortly, you cannot do "stealth" calls without dialer showing up.

Android : Launch Skype to be in background

I hope this is just a temporary problem and Skype allows an autostart feature.
I need to launch Skype so that it can receive Skype calls and video calls, and then launch my app. I work with the elderly s simplicity is at a premium. My app runs continuously.
The following code seems to achieve this goal in a BOOT BroadcastReceiver.
PackageManager pmi = context.getPackageManager();
String packageName ="com.skype.raider";
context.startActivity(pmi.getLaunchIntentForPackage(packageName));
Log.d("ANDRO_ASYNC",String.format("should launch Skype"));
Intent intent1 = new Intent(context,MyApp.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle bundle = new Bundle();
bundle.putInt("FromBoot",1);
intent1.putExtras(bundle);
try{ // hoping to schedule the start to after Skype has finished
Thread.sleep(20000);
}catch(InterruptedException ex){
Log.d("ANDRO_ASYNC",String.format("error in delay loop"));
}
context.startActivity(intent1);
This launches Skype and waits 20s to get sorted out before launching my app. My app ends up on the screen (desired effect).
However, it has a tiny problem for most people, but a big one for me. After the first Skype call the Blue welcome screen of Skype stays up, and the user has to press back button. Effectively this makes ending a Skype call different depending on whether it is the first or subsequent calls.
Questions.
Can I close Skype from my app?
Can I detect that Skype is finished teh call from my app?

AudioRecorder blocks microphone

I'm working on an app which allows user to take voice notes. For this I'm using the AudioRecorder to constantly obtain audio data from microphone and process it into Mp3.
It all worked great until recently I found out that if I receive/make a call while my app is running in background the other party can't hear me. Clicking on mute/unmute button on dialer screen doesn't do anything - the microphone seems to be disabled until I stop my app.
Now the question is how can I handle this situation? Is my only option is to release AudioRecorder once a voice call is started? I'm perfectly ok if AudioRecorder would just skip the audio data from microphone during the call, but the situation when user can communicate because of the app is unacceptable.
Thanks,
Only 1 app can use the mic at any given time. You might want to use PhoneStateListener so that you can release the recorder when the phone rings or is off the hook.
You can intercept incoming calls using PHONE_STATE action as part of a BroadcastReceiver. Then, in your onReceive function of your receiver, you would check states of the phone:
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
//Phone is ringing
}else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK){
//Call received
}else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
//Call Dropped or rejected
}
}
Do not forget to add the neccessary permissions in your manifest.
Likewise, you can intercept outgoing calls as well. Here is a nice tutorial explaining how to do both.
The rest is about stopping and resuming recorder depending on what you intercept.

Reboot after install

Is it possible to force a reboot of the device after my apk is installed?
I want to force this because I want to ensure that my service is started.
Most probably the answer is no, your are not allowed to do such things from your app. This is the sole privilege of the user holding the phone (and of maybe the core system services).
You can however ensure you service is started when the user starts you main activity, which would be a very normal thing to do right after the user have installed your application.
For additional information see the question How to start android service on installation, which is in fact what you should be trying to do.
It's not possible in any way to get your application to do anything as soon as it's installed, before the user first launches it from the home screen. There's no broadcast action you can listen for explicitly. However, you can listen for something generic that gets called a lot, such as:
android.intent.action.USER_PRESENT,
android.intent.action.SCREEN_OFF, or
android.intent.action.SCREEN_ON
In any case you should NOT reboot the device. Your users will hunt you down and kill you with stones. Joke aside, Google might actually pull your app from the Market for this. Just listen for one of the actions mentioned above, check if the app has just been installed (using a one-time boolean preference, for example) and start the service.
Note: if you do end up listening for one of the above actions, please disable your receiver the first time it receives an intent. You can do this like so (in your receiver):
public class FirstTimeReceiver extends BroadcastReceiver {
public void onReceive (Context context, Intent intent) {
// start your service (which does stuff asynchronously, of course, and then:
final ComponentName mySelf = new ComponentName(context, FirstTimeReceiver.class);
context.getPackageManager().setComponentEnabledSetting(mySelf, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
}
However, you should only do this if somehow this service is absolutely critical for the user (there are few proper scenarios for this), and not for you / your app. As bjarkef mentioned, you should only start it after the user starts your app from the home screen (better yet, ask for permission from the user to run the service).

Categories

Resources