How to query for the default SpeechRecognizer - java

How to find out the ComponentName of the default system speech recognizer, i.e. the one that is returned when createSpeechRecognizer(Context context) is called? (Actually, I only need to find out which input languages it supports, so if there is an answer only to that, then I'd appreciate it as well.)
The framework solves this by
String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.VOICE_RECOGNITION_SERVICE);
(See the source code of SpeechRecognizer.)
However, this solution does not seem to be available to a third party app.

However, this solution does not seem to be available to a third party app.
I assume you came to such conclusion because Settings.Secure.VOICE_RECOGNITION_SERVICE is not a public API. However, Settings.Secure.getString() requires name of the row to lookup in secure table for the second argument. So, you can simply provide the actual the name of the row you are looking for: "voice_recognition_service".
That's, you can use the same code from SpeechRecognizer with slight change:
String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(),
"voice_recognition_service");
Hope this helps.

UPDATE (I misread the original question)
SpeechRecognizer isn't the thing doing the speech processing, the Intent you pass to SpeechRecognizer, however, is (via startListening(Intent intent)). That intent uses RecognizerIntent.ACTION_RECOGNIZE_SPEECH and, AFAIK, can be detected in the old-fashioned way.
To detect defaults, try resolving the Intent that you want the find the default for but with the PackageManager.MATCH_DEFAULT_ONLY set.
Untested code:
String detectDefaultSpeechRecognizer(Context context) {
final Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
// 1: Try to find the default speech intent
final ResolveInfo defaultResolution = context.getPackageManager().resolveService(speechIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (defaultResolution != null) {
final ActivityInfo activity = defaultResolution.activityInfo;
if (!activity.name.equals("com.android.internal.app.ResolverActivity")) {
//ResolverActivity was launched so there is no default speech recognizer
return "";
}
}
// 2: Try to find anything that we can launch speech recognition with. Pick up the first one that can.
final List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentServices(speechIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (!resolveInfoList.isEmpty()) {
speechIntent.setClassName(resolveInfoList.get(0).activityInfo.packageName, resolveInfoList.get(0).activityInfo.name);
return resolveInfoList.get(0).activityInfo.packageName;
}
return "";
}
OLD ANSWER
Check out GAST, it has a way to check if a language is supported in a speech recognizer.
https://github.com/gast-lib/gast-lib/blob/master/library/src/root/gast/speech/SpeechRecognizingActivity.java#L70
You could also try to manually check the <recognition-service> metadata tag.
http://developer.android.com/reference/android/speech/RecognitionService.html#SERVICE_META_DATA

If you only want to find out which input languages the default system speech recognizer supports (createSpeechRecognizer (Context context)), there is a more straightforward way to do it.
All you need to do is using a RecognizerIntent.getVoiceDetailsIntent intent that will check the default system speech recognizer languages:
Intent intent = RecognizerIntent.getVoiceDetailsIntent(getApplicationContext());
if (intent != null) {
ctx.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
#Override
public void onReceive(Context context, final Intent intent) {
Log.d(TAG,
"Receiving Supported Speech Recognition Languages broadcast "
+ intent);
final Bundle extra = getResultExtras(false);
if ((getResultCode() == Activity.RESULT_OK)
&& (extra != null)
&& (mHandler != null)
&& ((extra
.containsKey(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES)) || (extra
.containsKey(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE)))) {
List<String> supportedLanguages = extra
.getStringArrayList(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);
String prefLang = extra
.getString(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE);
}
}
},
null, Activity.RESULT_OK, null, null);
}

Related

Trying to send a picture with text to Instagram stories but com.instagram.share.ADD_TO_STORY does nothing

I have read a lot of information on various sites, but not a single method works. There are also a lot of old solutions on the sites that don't work either. Here is my code:
Uri stickerAssetUri = Uri.parse("https://firebasestorage.googleapis.com/v0/b/schooly-47238.appspot.com/o/miners%2Ffimw.png?alt=media&token=9798e9ea-15a0-4ef2-869b-63ce4dc95b78");
String sourceApplication = "com.egormoroz.schooly";
Intent intent = new Intent("com.instagram.share.ADD_TO_STORY");
intent.putExtra("source_application", sourceApplication);
intent.setType("image/зтп");
intent.putExtra("interactive_asset_uri", stickerAssetUri);
intent.putExtra("top_background_color", "#33FF33");
intent.putExtra("bottom_background_color", "#FF00FF");
Activity activity = getActivity();
activity.grantUriPermission(
"com.instagram.android", stickerAssetUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (activity.getPackageManager().resolveActivity(intent, 0) != null) {
activity.startActivityForResult(intent, 0);
}
When this part of the code is triggered, nothing happens to the application. It remains on the same screen.
Based on official documentation from https://developers.facebook.com/docs/instagram/sharing-to-stories/.
You can change this
intent.setType("image/зтп");
to
intent.setType("image/*");
or
intent.setType(MEDIA_TYPE_JPEG);
I think sourceApplication should be your Facebook App ID, not your package name.

How to learn what is the "key" in Android Studio Bundle?

I'm using a library which is not up to date. (https://github.com/notsukamto/GFIPhotoPicker)
It has a onActivityResult function to get activity result. It returns an intent with this function
if (selection != null) {
intent.putExtra(EXTRA_SELECTION, new LinkedList<>(selection));
}
public static List<Uri> getSelection(Intent data) {
return data.getParcelableArrayListExtra(EXTRA_SELECTION);}
So my question is what is the key for this Parcelable and how I get that intent correctly?
(I tried "EXTRA_SELECTION" which is not working)
Bundle[
{com.github.potatodealer.gfiphotopicker.activity.extra.SELECTION=
[file:///storage/emulated/0/DCIM/Camera/IMG_20190114_072919.jpg,
file:///storage/emulated/0/DCIM/Camera/IMG_20190114_072904.jpg,
file:///storage/emulated/0/DCIM/Camera/IMG_20190114_072848.jpg],
com.github.potatodealer.gfiphotopicker.activity.extra.FACEBOOK_SELECTION=[],
com.github.potatodealer.gfiphotopicker.activity.extra.INSTAGRAM_SELECTION=[]
}
]
If you access this directory in the github link you provided, there will be a EXTRA_SELECTION constant in each of those activities.
For example, if we click on the FacebookPreviewActivity.java, we see:
private static final String EXTRA_SELECTION = FacebookPreviewActivity.class.getPackage().getName() + ".extra.SELECTION";

is there away to find out if an apk is installed and if so open app

hi guys some of my previous questions have been marked down so please be nice.
what i want to know is if there is a bit of code i can use that tell the user of my app that an apk is installed. then to open it within my app.
i have a listview, inside the list view is an list of available apps for download. i have worked out how to find out if the apk is there install instead of download. but i cant seam to figure out the installed bit.
ive tried this
public static boolean isPackageInstalled(Context context, String packageName) {
final PackageManager packageManager = context.getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
if (intent == null) {
return false;
}
List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
then using
ispackageinstalled();
but this asks for Context, and string
so i tried add this to constructor
Context shb;
private Static String Showbox = "com.tk.Showbox";
then tried
ispackageinstalled(shb,Showbox);
and the app just crashes lol im obviously writing something wrong. also i would like for the selection to turn red if it installed if possible. but getting the app to open would be a great help cheers guys
You need to pass in an actual Context to the method. Your Activity subclass that is hosting the ListView is a Context. Pass the Activity into your ispackageinstalled() method.
found this worked the way i wanted
private boolean isCallable(Intent intent) {
if (intent == null) {
return false;
}
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
then making an Intent with the package details like this
Intent AllcastOpen = getPackageManager().getLaunchIntentForPackage("com.koushikdutta.cast");
then an if statement
if (isCallable(AllcastOpen) == true) {
AllcastInstalled.equals(true);
startActivity(AllcastOpen);
the allcastInstalled is a seperate method that changes the color of the selection if its installed/downloaded depending

Android code for grammar based speech recognition

I am developing an Android App which requires speech to text conversion. Currently I have used Google voice search for this purpose but using google requires internet connection and moreover it gives highly inaccurate results for eg. when I say '1' it prints "when"..
Therefore, I want to define my own grammar such that when I give a voice command it searches the grammar defined by me to find the best possible match instead of searching the internet. Using grammar for speech recognition can be done easily for windows 8 phone but I want to know how I can make this work for Android phones.
Kindly take a look at below codes!..
**Using Intent:::**
Intent intent = new Intent(
RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
try {
startActivityForResult(intent, RESULT_SPEECH);
txtText.setText("");
} catch (ActivityNotFoundException a) {
Toast t = Toast.makeText(getApplicationContext(),
"Opps! Your device doesn't support Speech to Text",
Toast.LENGTH_SHORT);
t.show();
}
Without Using Intent::
Step 1: Implement RecognitionListener in your class.
Step 2. Add the Below codes:
private SpeechRecognizer speech = null;
private Intent speechIntent=null;
/**
* Speech Result is used to Store the Voice Commands
*/
private ArrayList<String> speechResult;
inside onCreate() --- >
speech = SpeechRecognizer.createSpeechRecognizer(this);
speech.setRecognitionListener(this);
Trigger this after your button Click:
if (SpeechRecognizer.isRecognitionAvailable(this)) {
if(speechIntent==null ){
speechIntent=new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
speechIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
speechIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,12);
speech.startListening(speechIntent);
}else{
if(speech!=null){
speech.startListening(speechIntent);
}
}
}
Replace the onResults link this:
public void onResults(Bundle results) {
speechResult = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if(speechResult!=null){
if(speechResult.size()>0 ){
String command=speechResult.get(0).toString();
}
}
}

Android DownloadManager get filename

In my app you can download some files. I used the Android DownloadManager class for downloading. After the download is completed, it should show me a message that the file was downloaded. The problem is, there could be 2,3 or 4 downloads at the same time. My BroadcastReceiver code looks like this:
receiver_complete = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE) ){
Toast.makeText(MainActivity.this, MainActivity.this.getString(R.string.download_finished, "Here should be the name", Toast.LENGTH_SHORT).show();
}
}
};
How can I get the current filename of the finished download?
Thank you very much.
I think you want to put something like this inside your if block. Replace YOUR_DM with your DownloadManager instance.
Bundle extras = intent.getExtras();
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID));
Cursor c = YOUR_DM.query(q);
if (c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
if (status == DownloadManager.STATUS_SUCCESSFUL) {
// process download
title = c.getString(c.getColumnIndex(DownloadManager.COLUMN_TITLE));
// get other required data by changing the constant passed to getColumnIndex
}
}
Ian Shannon was totally right with his answer, but I sugest some improvement:
Remember to close that Cursor after using it, avoiding "Cursor Leaking". This Cursor consumes a lot of resources and must be released as soon as possible.
If you put some title for the download, such as:
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setTitle("Some title");
The value given by the DownloadManager.COLUMN_TITLE will be "Some title" instead of the file name. So I would recommend this instead:
String filePath = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
title = filePath.substring( filePath.lastIndexOf('/')+1, filePath.length() );
The COLUMN_LOCAL_FILENAME returns the entire path (/storage/sdcard0/Android/data/.../filename.ext), but with this code, we will only get the file name.
Final code:
Bundle extras = intent.getExtras();
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID));
Cursor c = YOUR_DM.query(q);
if (c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
if (status == DownloadManager.STATUS_SUCCESSFUL) {
String filePath = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
filename = filePath.substring( filePath.lastIndexOf('/')+1, filePath.length() );
}
}
c.close();
Edit: Replace YOUR_DM with your DownloadManager instance.
I think what you are looking for is the DownloadManager.COLUMN_TITLE
Here is a link to the Android Documents: http://developer.android.com/reference/android/app/DownloadManager.html#COLUMN_TITLE
And here is a tutorial that will explain more than just getting the title. It is for downloading an image from a URL and then displaying it in an application. Mighty useful I think, overall speaking.
http://wptrafficanalyzer.in/blog/downloading-an-image-from-an-http-url-using-downloadmanager-and-displaying-in-imageview-by-dynamically-registered-broadcastreceiver/
There's a simpler way to retrieve the downloaded file URI, and that is with getUriForDownloadedFile:
download_receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle b = intent.getExtras();
DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
long file_id = b.getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
Uri uri = dm.getUriForDownloadedFile(downloaded_file_id);
}
}
I found this method here in a full description of how to use a BroadcastReceiver for handling DOWNLOAD_COMPLETE events.
u try this code to get the file name
DownloadManager.COLUMN_LOCAL_FILENAME
i am not sure about it

Categories

Resources