How to seperate CMU pocketsphinx android demo into activities - android

I am currently working on CMU pocketpshinx for Android and wish to separate the menu window from the other windows into activities. I am fairly new to coding and am having difficulties with it. I think my code is right, I just don't know where to place it. Any help would be great !
Here is my new activity code (I am unsure where to place it in the PocketSphinxActivity Java file):
Intent i = new Intent("edu.cmu.pocketsphinx.demo.BloodPressure");
startActivity(i)
Intent j = new Intent("edu.cmu.pocketsphinx.demo.HeartRate");
startActivity(j)
Intent k = new Intent("edu.cmu.pocketsphinx.demo.PatientInfo");
startActivity(k)

You have to place the codes in onPartialResult() method. For different actions to be performed for different voice commands, you can use if-else or switch as per your need in the code.
I am assuming that your provided code for starting different new activities are ok and the BloodPressure class will run for listening the command "blood pressure", the HeartRate class will run for listening the command "heart rate" and the PatientInfo class will run for listening the command "patient info". I also assume that you have made correct configurations in your grammar files and recognition system to recognize the parts "blood pressure", "heart rate" and "patient info".
Then your code may go like this using if-else:
public void onPartialResult(Hypothesis arg0) {
if(arg0 == null){ return; }
String command = arg0.getHypstr();
if(command.equals("blood pressure")) {
recognizer.stop();
Intent i = new Intent("edu.cmu.pocketsphinx.demo.BloodPressure");
startActivity(i);
}
else if(command.equals("heart rate")) {
recognizer.stop();
Intent j = new Intent("edu.cmu.pocketsphinx.demo.HeartRate");
startActivity(j);
}
else if(command.equals("patient info")) {
recognizer.stop();
Intent k = new Intent("edu.cmu.pocketsphinx.demo.PatientInfo");
startActivity(k);
}
}
Hope this helps

Related

Google Android speech capture timeout

Just a quick question about the Google speech capture inbuilt on most Android devices (not the cloud service) - see the attached image. Is there any way, either programatically or via the settings, to control how long it waits until it asks you to try again? The 'complete silence' fields in the RecognizerIntent don't seem to make any difference. On certain devices it times out very quickly and the user doesn't have enough time to start speaking.
This is the code in my test app:
public void StartSpeechToText(ISpeechResultCallback callback)
{
string rec = global::Android.Content.PM.PackageManager.FeatureMicrophone;
if (rec == "android.hardware.microphone")
{
MainActivity activity = MainActivity.CurrentActivity;
activity.Callback = callback;
var voiceIntent = new Intent(RecognizerIntent.ActionRecognizeSpeech);
//var voiceIntent = new Intent(RecognizerIntent.ActionVoiceSearchHandsFree);
voiceIntent.PutExtra(RecognizerIntent.ExtraLanguageModel, RecognizerIntent.LanguageModelFreeForm);
voiceIntent.PutExtra(RecognizerIntent.ExtraPrompt, "Speak now");
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputCompleteSilenceLengthMillis, 1500);
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputPossiblyCompleteSilenceLengthMillis, 1500);
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputMinimumLengthMillis, 15000);
voiceIntent.PutExtra(RecognizerIntent.ExtraMaxResults, 1);
voiceIntent.PutExtra(RecognizerIntent.ExtraLanguage, Java.Util.Locale.Default);
activity.StartActivityForResult(voiceIntent, VOICE);
}
}

Android Wear passing data from Activity back to watchface service

I have an Android Wear watch face created, an interactive one. On the face I have a grid area where I listen for an onTapCpmmand:
else if (x >= x6 & x <= x9 & y >= (y5 - (gridYUnit / 2)) & y <= (y8 - (gridYUnit / 2))) {
activityLaunched = new Intent(MyWatchFace.this, ActivityLaunched.class);
activityLaunched .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activityLaunched );
}
The mew activity then takes over. Within this activity, I have three options, basically ImageButtons, with respective onClickHandlers:
optionOne.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
confirmationIntent = new Intent(ActivityLaunched.this, ConfirmationActivity.class);
confirmationIntent .putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,
ConfirmationActivity.SEARCH_SERVICE);
confirmationIntent .putExtra(ConfirmationActivity.EXTRA_MESSAGE,
getString(R.string.option_one));
currentOption = "1";
broadcastIntent(currentOption);
startActivity(confirmationIntent );
ActivityLaunched.this.finish();
}
});
With broadcastIntent handling the broadcast:
public void broadcastIntent(String currentOption){
Intent optionUpdated = new Intent();
optionUpdated .setAction("com.example.packagename....");
optionUpdated .putExtra("Option", currentOption);
sendBroadcast(optionUpdated );
}
The users selects an options, the activity closes and the flow of control passes to my broadcastReceiver.
Now, I had set up a broadcastReceiver to make a simple toast when an option has been selected. However, I am unable to do any more with this data, other than show a toast.
Within my broadcastReceiver:
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Option Updated." + intent.getStringExtra("Option"), Toast.LENGTH_LONG).show();
currentOption = intent.getStringExtra("Option");
sendOption .setAction("com.example.packagename....");
sendOption tion.putExtra("Option", currentOption );
context.sendBroadcast(sendOption );
Log.d(TAG, "THIS WORKS : " + currentOption );
}
In my WatchFaceService, I have registered the receiver along with the batteryinforeceivers, and any other system ones, as normal. I am receiving the messages within my broadcastReceiver
Back again to my WatchFaceService, it's where I'm getting issues, I'm not receiving any updates:
optionUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle results = getResultExtras(true);
String option = results.getString("Option");
Log.d(TAG, " NOTHING SHOWING HERE " + currentOption + option );
}
};
I have tried using setters and getters, which required a second launch of the activity to get the real value.
Any ideas as to what I am doing wrong?
I've tried following some other answers and ideas here, as well as other external sources. But as it's Android Wear I'm working with, as volatile as the OS is, anything I tried, that was suggested that worked for Android, appears to be ineffective for Android Wear.
Thanks, Emmett
Your watch face service is not guaranteed to be running when there another activity on top of it. It might be preserved, but equally likely it might be torn down. You could try to register your receiver in WatchFaceService.onCreate() and WatchFaceService.onDestroy(), but that's not a way that is guaranteed to work.
Instead, inside the Activity save the information into SharedPreferences and then read the information within you watch face. When your watch face is created, read the value from the prefs (you can also have a listener for the preferences, to update on their change when they change while the watch face is already launched).
I've actually managed to solve it.
I created a second broadcastreceiver, passed this back to the watchface, and then overrode the register / unregister methods to handle the transmission.
Initially, when I had registered the second receiver, it was spamming the log files and crashing the watch. The reason I had to override was to handle the passing of a filter, which cannot be done from within a watchfacecanvas.engine for some strange reason.
Anyway, it's working fine now, but thanks for help

Method similar to tts.getEngines().size() in API 8

I have a code to check the TTS engine availability in the device. As the statement tts.getEngines().size() < 1 will be executed only from the API 14. I need to know if there is any way(methods) to check the same functionality even from the API 8.
Thanks in Advance
Code:
private void checkTTSAvailability() {
tts = new TextToSpeech(this, this);
ttsPresent=true;
**if (tts.getEngines().size() < 1) {**
PackageManager pm = getPackageManager();
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
ResolveInfo resolveInfo = pm.resolveActivity(installIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfo == null) {
Log.i("DragDrop", "No voice support on your phone");
Dialog d = new Dialog(this);
d.setTitle("Alert ");
TextView tv = new TextView(this);
tv.setText("No voice support on your phone");
d.setContentView(tv);
d.show();
ttsPresent=false;
// Not able to find the activity which should be started for
// this intent
} else {
Dialog d = new Dialog(this);
d.setTitle("Alert ");
TextView tv = new TextView(this);
tv.setText("Installing");
d.setContentView(tv);
d.show();
Log.i("DragDrop", "Installing");
startActivity(installIntent);
}
}
}
AFAIK, there is no way to list TTS engines or otherwise know they are installed, below API 14. Maybe you could review a list of all installed packages and recognize known TTS engine names there, but it's far from ideal.
The correct way of doing this would be to implement TextToSpeech.OnInitListener() callback in your activity, to know when the default system TTS engine was initialized, and if the initialization was a success or failure. Then, from within this callback on SUCCESS return, first set the language you need on the TTS object, then send an Intent to TTS to check for installed data (ACTION_CHECK_TTS_DATA) for that language, and again when the activity result comes, call ACTION_INSTALL_TTS_DATA if needed.
For a code example, see my other post, link below. It compares async operations in Android Java and C# for Android (with Xamarin for Android), but the Java code sample given there has the correctly functioning OnInitListener() callback.
How to implement Android callbacks in C# using async/await with Xamarin or Dot42?
Greg

Android not acknowledging TTS Engine

I am developing a very simple app in here. It's for my Cerebral Palsy daughter. It's just a big YES and NO buttons, so she can press them when requested.
Well... I am using SVOX Classic TTS Engine.
Everything was running smoothly until my tablet upgraded to ICS. Now, everytime I run the app, it opens the Market asking for me to install TTS. I hit "back" and then, my app speaks. This is VERY annoying.
Here is what Google API says:
*A successful check will be marked by a CHECK_VOICE_DATA_PASS result code, indicating this device is ready to speak, after the creation of our TextToSpeech object. If not, we need to let the user know to install the data that's required for the device to become a multi-lingual talking machine! Downloading and installing the data is accomplished by firing off the ACTION_INSTALL_TTS_DATA intent, which will take the user to Android Market, and will let her/him initiate the download. Installation of the data will happen automatically once the download completes. Here is an example of what your implementation of onActivityResult() would look like:*
Here is my code:
public class yesOunoActivity extends Activity implements OnInitListener{
ImageView yes;
ImageView no;
public TextToSpeech tts;
private int MY_DATA_CHECK_CODE = 0;
#Override
public 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);
tts = new TextToSpeech(this, this);
setContentView(R.layout.yesorno);
yes = (ImageView) findViewById(R.id.yes);
no = (ImageView) findViewById(R.id.no);
yes.setClickable(true);
yes.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent arg1) {
if (arg1.getAction() == android.view.MotionEvent.ACTION_DOWN) {
tts.speak("yes!", TextToSpeech.QUEUE_ADD, null);
}
return true;
}
});
no.setClickable(true);
no.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent arg1) {
if (arg1.getAction() == android.view.MotionEvent.ACTION_DOWN) {
//Intent myIntent = new Intent(v.getContext(), ParametrosActivity.class);
tts.speak("no!", TextToSpeech.QUEUE_ADD, null);
}
return true;
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
tts = new TextToSpeech(this, this);
} else {
// missing data, install it
//ATTENTION: BELOW THIS GIVES ME PROBLEMS SINCE IT OPENS MARKET
//AND I HAVE TO HIT THE BACK BUTTON, THEN, IT SPEAKS!
//BTW TTS ENGINE "IS" INSTALLED!!
Intent installIntent = new Intent();
installIntent
.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
} else if (status == TextToSpeech.ERROR) {
}
}
#Override
public void onDestroy() {
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
System.gc();
}
}
If I remove the area with "ATTENTION" above (since I am SURE I have TTS installed), it works the first time I run the app, if I leave the app and I open it again, it says "speak failed: not bound to tts engine"
It's like it doesn't create the TTS object since the app is still in memory.
So, guys... what do you guys think that I should do??
This is driving me crazy and I really need to communicate to my daughter through the tablet!
Any help is appreciated!!
I had this trouble on my application as well: TTS works in 2.3, but when I tried 4.0, it had the same symptoms as your problem (which I just found now while searching for a solution). The engine would work if you force-closed the application through Settings and started it again but just "backing out" and going back made the TTS engine in ICS not bind.
I tried setting the TTS object (mTts) to null after running mTts.shutdown(). When I started the application again after backing out, I got a null error on my mTts.speak() line.
At least for ICS, something is not letting go of the TTS engine. My solution (for now) is that I have made my TTS object static:
// in Activity
private static TextToSpeech mTts;
.
.
.
// in onCreate()
mTts = new TextToSpeech(this, this);
.
.
.
// in onDestroy()
if (mTts != null) {
mTts.stop();
mTts.shutdown();
mTts = null;
}
I was already only using one TTS object for the application so I don't think there are too many downsides to this approach.
This is what I have in onActivityResult(...)
#Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
/*
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
mTts = new TextToSpeech(this, this);
} else {
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(
TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
*/
if (mTts==null) {
Intent installIntent = new Intent();
installIntent.setAction(
TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
mTts = new TextToSpeech(this, this);
}
}
Instead of using if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {...}, I check if mTts has already been instantiated. You'll also have to set mTts as static, as was mentioned by jlquant and Rakesh in an earlier post, so you'll have only a single instance of it. For example, private static TextToSpeech mTts.
So, unless you "Force stop" the app or it stops working because of an error, it won't anymore call the startActivity(installIntent);-- the annoying culprit that asks you to install TTS every time.
I fixed this by installing ivona having both Tts engines cured all problems, though I'm finding other issues such as no default tts is installed using the two together makes one work not a great fix but its s fix,
Also I can't find the option to allow my phone to install non market apps ie apk from my SD card
I had the same problem and solved. Maybe it's a timing issue in bounding, not sure, but a simple action before speak helped me.
Anyway I did this:
mTts = new TextToSpeech(this, this);
String engine = mTts.getDefaultEngine();
mTts = new TextToSpeech(this, this,engine);
Log.d("","...something here...");
Then when I hit my speak button, it speaks. You should watch your variable status on OnInit method. Maybe a separate thread can help talking in the app.
By the way, if you are sure TTS is installed, you can remove the block Intent checkIntent = new Intent(); for checking.
I definitely hope this helps you.
in my app I also used checkintent.setAction(...) to check if the necessary tts files are installed (which was working like a charm before upgrading to ICS). In ICS it always returned that the files are missing. So now I just ignore this check: i am creating the object and it initializes fine.
Moreover I was using two instances for two different languages. This also seems to not work anymore.
Now when I set the language for one of the instances, the other instance of the object is set to the same language (behaves like one instance).
gingerbread allowed setting of default tts in voice input& output / default tts
gingerbread only allows 'preferred' tts in language and input / text to speech output.
so tts is preferred instead of default, which just means it is not as clear as to which gets used.
The default with application overrides where stated is a better option I think.

How to make an Android app that depends on another app?

If I create an app that depends on another app or apps (eg: the Facebook and Twitter apps), yet they are not installed, is there a method of checking for those dependencies and installing them at the same time as my own app?
I did this in my application which requires the zxing scanner app to be installed.
You will want this inside your onclick or ontouch:
try{
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.setPackage("com.google.zxing.client.android");
startActivityForResult(intent, 0);
} catch (Exception e) {
createAlert("Barcode Scanner not installed!", "This application uses " +
"the open source barcode scanner by ZXing Team, you need to install " +
"this before you can use this software!", true);
}
which calls
public void createAlert(String title, String message, Boolean button) {
// http://androidideasblog.blogspot.com/2010/02/how-to-add-messagebox-in-android.html
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle(title);
alertDialog.setMessage(message);
if ((button == true)) {
alertDialog.setButton("Download Now",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent browserIntent = new Intent(
Intent.ACTION_VIEW,
Uri.parse("market://search?q=pname:com.google.zxing.client.android"));
startActivity(browserIntent);
}
});
}
alertDialog.show();
}
Then after sorting out all that code out I realise you asked for it to be installed at the same time as your app. Not sure if i should post this code, but it may be helpful
Short answer: No, you cannot automatically install other applications as dependencies.
Longer answer:
Android Market does not let you declare other applications to install as a dependency. As a system, Market appears to be designed for single application installs -- not Linux distro style mega dependency graphs.
At runtime, you can test for installed apps and punt your user over to the Market if so. See the techniques suggested by #QuickNick (testing if an app is installed) and #TerryProbert (punting to market) if that's what you want.
Your best bet is probably to design your app to gracefully degrade if dependencies are not available, and suggest (or insist) that they head over to market to install them.
Start from this:
Intent mediaIntent = new Intent("com.example.intent.action.NAME");
// add needed categories
List<ResolveInfo> listResolveInfo = getPackageManager().queryIntentServices(mediaIntent, 0);
if (listResolveInfo.size() != 0) {
//normal behavior
} else {
//install what you need
}
I give you example of querying services. If you want to check activities, then you will call queryIntentActivities().
I think following the pattern outlined in this post on the Android Developer Blog will help you.
http://android-developers.blogspot.com/2009/01/can-i-use-this-intent.html
As TerryProbert points out if you know that the Intent is not available prompt the user to install the missing app.
Here's what I use to return the first mission activity that exists:
try {
Class<?> missionClass = Class.forName(mPackageName+".Mission"+mission);
Method missionDescription;
missionDescription = missionClass.getMethod("missionDescription");
mMissionDescription = (String) missionDescription.invoke(null);
if (mMissionDescription.length() > 0) {
nextMission = mission;
break;
}
} catch (Exception e) {
//DEBUG*/Log.v(this.getClass().getName(), "onResume: Mission no "+mission+" not found: "+e.getMessage());
}
Each mission is held in a separate class, derived from a Mission base class. Derived classes are called Mission1, Mission24 etc.
Not all missions are defined.
The base class has an abstract class missionDescription which returns a string describing the mission.
This code is inside a loop so tests mission=1 to 99, trying to call missionDescription. It returns when the Description for the first mission found is returned.

Categories

Resources