Query supported languages for SpeechRecognizer using BroadcastReceiver intent - android

I'm having trouble querying for supported languages using the SpeechRecognizer.ACTION_GET_SUPPORTED_LANGUAGES.
private void queryLanguages() {
Intent i = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
sendOrderedBroadcast(i, null);
}
Now, I know it says the BroadcastReceiver is specified in RecognizerIntent.DETAILS_META_DATA, but I'm not sure as to how I can access that.
So basically what I'm asking is how do I create an Intent to retrieve the available languages data?

This is how it is done:
Intent intent = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
context.sendOrderedBroadcast(intent, null, new HintReceiver(),
null, Activity.RESULT_OK, null, null);
private static class HintReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (DBG)
Log.d(TAG, "onReceive(" + intent.toUri(0) + ")");
if (getResultCode() != Activity.RESULT_OK) {
return;
}
// the list of supported languages.
ArrayList<CharSequence> hints = getResultExtras(true)
.getCharSequenceArrayList(
RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);
}
}
Note :
Whether these are actually provided is up to the particular implementation

Related

"Text to Speech" in Android 9.0

I want to use TTS in an Android application. I followed introduction-to-text-to-speech-in. And this is the code of the Activity which creates TTS instance:
public class MainActivity extends Activity implements TextToSpeech.OnInitListener {
private int MY_DATA_CHECK_CODE = 0;
private TextToSpeech myTTS;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
myTTS = new TextToSpeech(this, this);
}
else {
Intent installTTSIntent = new Intent();
installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installTTSIntent);
}
}
}
#Override
public void onInit(int status) {
}
}
As you can see it is straightforward and simple and also works up to Android 8.1-API 27; but in Android 9.0 I get ActivityNotFoundException:
in onCreate method: No Activity found to handle Intent { act=android.speech.tts.engine.CHECK_TTS_DATA }
in onActivityResult method: No Activity found to handle Intent { act=android.speech.tts.engine.INSTALL_TTS_DATA }
Although with attention to documentation about ACTION_CHECK_TTS_DATA and ACTION_INSTALL_TTS_DATA, no one of them is deprecated. How I can solve above errors?
Sounds like it's probably a beta version of Android 9.0 emulator that is janky?
I don't think it's necessary these days to use the CHECK_TTS_DATA intent... as
1) most all devices (commercial phones, at least) have at least one TTS installed,
2) the myTTS object won't initialize unless that is true ( or, at least it will return an onError callback if you attempt a speak() ), and
3) devices can have multiple engines installed and thus will force the user to choose which engine to send the intent (from the example you used) to.
Instead, I would decide what exact engine/s you want to support, check for it/them specifically, and prompt to install it/them.
For example, if you decided to use/support the Google engine:
private boolean isGoogleTTSInstalled() {
Intent ttsIntent = new Intent();
ttsIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
PackageManager pm = this.getPackageManager();
List<ResolveInfo> listOfInstalledTTSInfo = pm.queryIntentActivities(ttsIntent, PackageManager.GET_META_DATA);
for (ResolveInfo r : listOfInstalledTTSInfo) {
String engineName = r.activityInfo.applicationInfo.packageName;
if (engineName.equals("com.google.android.tts")) {
return true;
}
}
return false;
}
private void installGoogleTTS() {
Intent goToMarket = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("market://details?id=com.google.android.tts"));
startActivity(goToMarket);
}
And, if you intend to support a specific language, check for it using myTTS.isLanguageAvailable(Locale loc), and if not:
private void openTTSSettingsToInstallUnsupportedLanguage() {
Intent intent = new Intent();
intent.setAction("com.android.settings.TTS_SETTINGS");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}

Android Source change to pass intent invoker to Broadcast Receiver

I am trying to modify the Android source so that a BroadcastReceiver can know who invoked the action.
android.app.activity:
#Override
public void startActivity(Intent intent) {
intent.putExtra("packageName", this.getPackageName());
startActivity(intent, null);
}
I wrote a testing app that has the CALL_PHONE permission. As a debugging step, I also tried to see if I could just pass something in the Intent from the calling app:
Calling App (App #1):
Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:8005551212"));
dialIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialIntent.putExtra("StubTest", "it worked!");
startActivity(dialIntent);
But in my BroadcastReceiver that intent does not have the intent value from the Activity source file change I made, nor the intent value I added from the invoking activity.
Separate App which has a Broadcast Receiver (App #2):
public class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Set<String> k = bundle.keySet();
if (k!=null && k.size() > 0) {
Iterator<String> i = k.iterator();
while (i.hasNext()) {
String key = i.next();
try {
System.out.println("KEY: " + key + "=" + bundle.getString(key));
} catch (Exception e) {
logIt("skipping KEY: " + key);
}
}
}
System.out.println(bundle.getString("packageName"));
System.out.println(bundle.getString("StubTest"));
However, "packageName" and "StubTest" are both null all the time.

Not receiving an Intent back from Zxing barcode scanner

I know some others have had this problem but I've followed the solutions and it still isn't working for me.
I've created a new application, it has 1 activity which has 1 button (scan button) and 2 textviews (which are just going to output the formatname and contents that Zxing returns at the moment).
I have followed the ScanningViaIntent tutorial but it doesn't seem to be hitting onActivityResult
Below is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final IntentIntegrator integrator = new IntentIntegrator(this);
Button btnScan = (Button) findViewById(R.id.button1);
btnScan.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
integrator.initiateScan();
}
});
}
public void OnActivityResult(int requestCode, int resultCode, Intent intent)
{
Log.i("result", "hit line");
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
TextView tv1 = (TextView) findViewById(R.id.textView1);
TextView tv2 = (TextView) findViewById(R.id.textView2);
if(scanResult != null)
{
System.out.println("format: " + scanResult.getFormatName());
System.out.println("contents: " + scanResult.getContents());
tv1.setText(scanResult.getFormatName());
tv2.setText(scanResult.getContents());
}
else
{
tv1.setText("ERROR");
}
}
TextView1 never says "Error" so it doesn't seem that scanResult is null and my Log.i() line is never hit so I'm thinking that onActivityResult isn't even being hit.
Could it be to do with making IntentIntegrator final for the OnClick() method? When I created IntentIntegrator inside OnClick(), I used getParent() to pass the Activity to the constructor but this force closed my app with a NullReferenceException inside IntentItegrator.
Am I using the library correctly?
Thanks for your time,
Poncho
You are not actually overriding the method onActivityResult() because you have implemented OnActivityResult(). Your method is not being called as a result. Everything else looks about right.
This is the kind of thing you catch if you use #Override annotations -- good habit, since it would have caught this.
Where are you calling startActivityForResult(..)? You may want to use something like this :
Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// check which types of codes to scan for
if (desiredBarcodeFormats != null) {
// set the desired barcode types
StringBuilder joinedByComma = new StringBuilder();
for (String format : desiredBarcodeFormats) {
if (joinedByComma.length() > 0) {
joinedByComma.append(',');
}
joinedByComma.append(format);
}
intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
}
String targetAppPackage = findTargetAppPackage(intentScan);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intentScan.setPackage(targetAppPackage);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intentScan);
startActivityForResult(intentScan, REQUEST_CODE);
findTargetAppPackage :
private String findTargetAppPackage(Intent intent) {
PackageManager pm = activity.getPackageManager();
List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (availableApps != null) {
for (ResolveInfo availableApp : availableApps) {
String packageName = availableApp.activityInfo.packageName;
if (targetApplications.contains(packageName)) {
return packageName;
}
}
}
return null;
}
To see a more complete example go here.
You need to get the latest classes from the repository
https://github.com/zxing/zxing/tree/master/android-integration/src/main/java/com/google/zxing/integration/android
See the javadoc of the class to see how to use it. First add code to invoke the Intent:
IntentIntegrator integrator = new IntentIntegrator(yourActivity);
integrator.initiateScan();
Second, add this to your Activity to handle the result:
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanResult != null) {
// handle scan result
}
// else continue with any other code you need in the method
}
More info here https://github.com/zxing/zxing/wiki/Scanning-Via-Intent

display contact list with checkboxes?

I am working on an android project and I would like to create an application that intercept the inbound calls.How to assign a check box at contact list, in order to be able to select multiple contact persons once?
Here is my code:
//main activity
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
add = (Button)findViewById(R.id.add_reminder);
manage = (Button)findViewById(R.id.manage_reminders);
add.setOnClickListener(this);
manage.setOnClickListener(this);
}
public void onClick(View v) {
switch(v.getId())
{
case R.id.manage_reminders:
break;
case R.id.add_reminder:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT);
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if (requestCode == PICK_CONTACT)
{
Cursor cursor = managedQuery(intent.getData(), null, null, null, null);
cursor.moveToNext();
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
Toast.makeText(this, "Contect LIST = "+name, Toast.LENGTH_LONG).show();
}
}//onActivityResult
}
Take a look here: http://www.krvarma.com/2010/08/detecting-incoming-and-outgoing-calls-in-android/
Just make an BroadcastReceiver that listens to:
android.intent.action.PHONE_STATE
If the phone state is 'Ringing', then there is an incoming call.
TelephonyManager.EXTRA_STATE
Like:
public class IncomingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if(null == bundle)
return;
String state = bundle.getString(TelephonyManager.EXTRA_STATE);
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))
{
String phonenumber = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.i("IncomingCallReceiver","Incoming Number: " + phonenumber);
}
}
}
Now the phone number will be printed in logcat.

start installed app from code

Hallo, I writing an app and I want to integrate a sketch-app to draw something and pass the file or path back to my app. At the moment the app can store videos,pictures, sensor data,... and I like to add the ability to store sketches. I found this Code
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity( intent);
But i dont know how to start sketchbook(app from market). And I need also the path to the saved picture.Or is there an other way? Or Open Source ?
greetings...
So sketchbook is not your application?
To start another program, you need to know the intent filters it uses, or the package name. The developer of sketchbook will be able to supply you with this information (if they wish to share it).
Now when it comes to getting data FROM another app, the only way for that app to return anything to you is if the developer made it that way. It is up to the developer to decide what an Activity returns (if anything). So if you are looking to integrate with a specific application, it would be best for you to contact that developer and discuss how the two apps will interface with each other. On the other hand, if you implemented your own sketch app, you could make it integrate however you'd like.
You'd need to detect that the intent can be handled by the system.
public static boolean canHandleIntent(final Context context, final Intent intent) {
if (intent != null) {
final PackageManager pm = context.getPackageManager();
if (pm != null) {
if (pm.queryIntentActivities(intent, 0).size() > 0) {
return true;
}
}
}
return false;
}
If that returns false you should prompt the user to download the app from the market.
Call,
//Market.getViewPackageOnMarket("org.otherapp.sketchapp");
public class Market {
public static final String Application_BaseMarketUri = "market://details?id=";
public static final Intent getViewPackageOnMarket(final String package_name) {
final Intent result = new Intent(Intent.ACTION_VIEW);
result.setData(Uri.parse(Application_BaseMarketUri + package_name));
return result;
}
}
You'll also need to use startActivityForResult, in your launching activity you need to add these things....
public class MyKillerAppActivity extends Activity {
// Declare constant for the activity result.
public static final int ACTIVITYRESULT_GETSKETCH = 1;
// Call the activity ....
public void someMethod() {
startActivityForResult(intent, ACTIVITYRESULT_GETSKETCH);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) {
if(requestCode == ACTIVITYRESULT_GETSKETCH) {
handleGetSketchResult(data);
} /* Handle other results if you need to. */
}
}
}
That's kinda a mouthful but there's more! You'll need to interpret the data that comes back from the app. I don't know the format is for the sketch app you're looking into but here's an example on how to get data from the Gallery. The Gallery app returns you a content provider location to load the image that the user picked. This code locates the file path from the content provider and then opens the file and loads it into a Bitmap object for use.
public static Bitmap onActivityResult_getImage(Context context, Intent data) {
Bitmap result = null;
Uri dataUri = data.getData();
final String filePath = findPictureFilePath(context, dataUri);
if(filePath != null) {
result = BitmapFactory.decodeFile(filePath);
}
return result;
}
private static String findPictureFilePath(Context context, Uri dataUri) {
String filePath = null;
final String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(dataUri, projection, null, null, null);
int data_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if(cursor.moveToFirst()) {
filePath = cursor.getString(data_index);
}
} finally {
if(cursor != null) {
cursor.close();
}
}
return filePath;
}

Categories

Resources