Android get available input languages - android

I'm trying to get the available input devices on Android, in order to do that I'm using the InputMethodManager and using the API of getEnabledInputMethodList() as follows:
InputMethodManager inputMgr = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
List<InputMethodInfo> inputMethodList = inputMgr.getEnabledInputMethodList();
for (InputMethodInfo method : inputMethodList) {
List<InputMethodSubtype> subMethods = inputMgr.getEnabledInputMethodSubtypeList(method, true);
for (InputMethodSubtype submethod : subMethods) {
if (submethod.getMode().equals("keyboard")) { //Ignore voice input method
String localeString = submethod.getLocale();
Locale locale = new Locale(localeString);
String currentLanguage = locale.getLanguage();
//do something...
}
}
}
However, although I've got many more input languages available on my LG G3 and MEIZU M2, this API returns only 1 input language - English.
It seems that this API works as expected only on Google Nexus phones.
Has anyone tried to do the same and succeeded?
P.S
I've already read the solution on this thread but it doesn't help much:
how to get user keyboard language

There is no way to do this. A keyboard doesn't report to Android the list of languages it supports.
In fact, most keyboards keep the input language separate from the phone's locale, in order to switch without resetting the UI of the entire phone. So the OS has no idea what languages a keyboard can write in or is currently writing in.

Related

Questions about localization of Android applications

I am developing an Android application that can set up two languages.
And I would like to divide the default language and the setting language by distinguishing between the language set on the phone and the language set inside the app.
However, if you implement a language change function, the default language settings that can be known through googling will be returned within the app.
During the search process, I learned that individual languages for each app can be set from Android 13.
Is there any way to check Android's default language and app setting language in Android 12 or lower versions?
Below are the functions I used. I'd appreciate it if you could answer me.
'''
Log.e("contry","resources.configuration.locales.get(0) = ${resources.configuration.locales.get(0)}")
Log.e("contry","resources.configuration.locales.get(0).language = ${resources.configuration.locales.get(0).language}")
Log.e("contry","Locale.getDefault().language = ${Locale.getDefault().language}")
Log.e("contry","getSystemLanguage = ${getSystemLanguage(this)}")
Log.e("contry","LocaleList.getDefault = ${LocaleList.getDefault()}")
fun getSystemLanguage(context: Context): String {
val systemLocale: Locale
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
systemLocale = context.getResources().getConfiguration().getLocales().get(0)
} else {
systemLocale = context.getResources().getConfiguration().locale
}
return systemLocale.language // ko
}
'''

Android speech recognizer vs OK GOOGLE

In my application I'm using SpeechRecognizer, in order to detect what the user said.
My device's language is set to English and it works perfect when I say something in English, but when I say something in other languages, for example - Hebrew, it doesn't work all the time as it works for English, until I set the device's language to Hebrew and then it works OK.
I'm trying to avoid from setting the device's language and want it to automatically detect the user language.
I've noticed that "OK Google" works and detect the correct words in Hebrew even when the device's language is set to English.
For the meantime, what I tried to do is when the user enter for the first time
to my application, I'm asking him to enter his country.
Then when I have his country -> I'm getting the country code and then I create a Locale using the country code.
This locale is then sent as the language to the speech recognizer.
But it didn't help..
// example of how to get the locale using the country code
Locale myLocale = null;
String toSearch = "IL";
toSearch = toSearch.trim().toLowerCase();
for (Locale locale : Locale.getAvailableLocales())
{
if(locale.getCountry().trim().toLowerCase().contains(toSearch))
{
myLocale = locale;
break;
}
}
// example of how I'm sending the locale
Intent recIntent= new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recIntent.putExtra(RecognizerIntent.ExtraLanguage,myLocale);

Detect if voice typing is enabled

I need to display an alert to the user if they haven't enabled Google voice typing from their settings(Language and input -> Google voice typing). Is there someway to detect that setting status?
So i found my answer. There is no official way of detecting wether voice typing is enabled or not. I have managed to get a list of enabled input methods ( keyboard, voice, etc).
String enabledMethods = Settings.Secure.getString(getActivity().getContentResolver(),Settings.Secure.ENABLED_INPUT_METHODS);
There we can see if Google voice typing is enabled or not and we can alert the user to turn it on, however this applies for the default keyboard. Some users use custom keyboards that have their own implementation of speech to text and it doesn't relly on the users settings for Google voice typing. So it will be a false positive for them.
Given that you know the package name of the IME, you can do something like this:
boolean isImeEnabled(String packageName) {
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
for (InputMethodInfo imi : imm.getEnabledInputMethodList()) {
if (imi.getPackageName().equals(packageName)) {
return true;
}
}
return false;
}

android: can TTS speak cantonese?

I am learning to write an app that is intended to perform TTS on given strings, and have tried an example modified from web:
Coding as follows:
// setup TTS part 1
mTts = new TextToSpeech(Lesson2_dialog_revision_simple.this, this); // TextToSpeech.OnInitListener
speakBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
StringTokenizer loveTokens = new StringTokenizer("他們 one two是 three ",",.");
int i = 0;
loveArray = new String[loveTokens.countTokens()];
while(loveTokens.hasMoreTokens())
{
loveArray[i++] = loveTokens.nextToken();
}
speakText();
}
});
}
// setup TTS part 2
#Override
public void onUtteranceCompleted(String utteranceId)
{
Log.v(TAG, "Get completed message for the utteranceId " + utteranceId);
lastUtterance = Integer.parseInt(utteranceId);
}
// setup TTS part 3
#Override
public void onInit(int status)
{
if(status == TextToSpeech.SUCCESS)
{
int result = mTts.setLanguage(Locale.CHINESE); // <====== set speech location
if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)
{
Toast.makeText(Lesson2_dialog_revision_simple.this, "Language is not supported", Toast.LENGTH_LONG).show();
speakBtn.setEnabled(false);
}
else
{
speakBtn.setEnabled(true);
mTts.setOnUtteranceCompletedListener(this);
}
}
}
// setup TTS part 4
private void speakText()
{
lastUtterance++;
if(lastUtterance >= loveArray.length)
{
lastUtterance = 0;
}
Log.v(TAG, "the begin utterance is " + lastUtterance);
for(int i = lastUtterance; i < loveArray.length; i++)
{
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.valueOf(i));
mTts.speak(loveArray[i], TextToSpeech.QUEUE_ADD, params);
}
}
Questions:
Everything is ok if the int result = mTts.setLanguage(Locale.US); in part 3 above is set as US and to read out "one two three" in English perfectly. (in the above example, it will skip all the chinese words and just read out one two three)
However, if I change the string to read out Chinese by setting language as setLanguage(Locale.CHINESE), it immediately toasts out that "Language is not supported".
I would like to ask
the current TTS still does not support Chinese? I would even more prefer Cantonese rather than Chinese.
The phone is ABLE to recognize Cantonese when I inputting messages via speech (Cantonese). Is it actually there are some other way to perform TTS with output being Cantonese?
Thanks!!
1 - The Google TTS Engine at its current version does not support Cantonese as output yet. Putonghua works fine.
2 - Ekho is a TTS Engine that supports Cantonese.
You might want to give a try on the TTS app I developed that works with Ekho and Google TTS Engine: Voice Out TTS
As far as I know there's no specific Locale in JAVA to distinguish between Cantonese or Putonghua because Cantonese is a Chinese dialect. The Locale in JAVA refers only to the writings (Simplified or Traditional).
For example you can read a string written in Traditional Chinese with Cantonese or Putonghua.
#Pearmak: you can check the language that are supported in your device
int i = mTts.isLanguageAvailable(Locale.ENGLISH);
where mTts is object of TextToSpeech
If you get the value of i >=0 then that language is supported on you device otherwise not.
You may also pass the language locale string.
int i = mTts.isLanguageAvailable(new Locale("zh_CN")); //for chinese simplified
Yue, a tiny Chinese text to speech (TTS) synthesis engine of Cantonese, Mandarin for offline embedded system. Yue is extremely small size, offline, independent, and PCM audio output no needs of server or network connection. It has high naturalness of synthesised voice for hybrid text input, the Cantonese and Mandarin speech synthesis for same text input, with Yale, Jyutping and Pinyin romanization. The engine can continues produce and play voice for long text, the length of the text without limit. It has build-in intelligent detecter that can handle any traditional Chinese, simplified Chinese, English, number and punctuations, symbol mixed text input. Yue is written in ANSI C, no dependent of third part library, running on ARM, AVR embedded system such as watch, toy, robot and iPhone, Android, … mobile platforms, of course normal desktops, ebook, news paper reader, story teller. Yue can be loaded into memory and embedded in other programs, because of its extremely small size, it is well suited to embedded systems, and is also suitable for desktop operating systems. The engine can have bindings for a large number of programming languages.
The link:http://www.sevenuc.com/en/tts.html
Google TTS recently added support for Cantonese (and also Mandarin). http://www.androidpolice.com/2015/07/24/google-tts-now-supports-four-new-languages-including-cantonese-and-mandarin/
some phones have the cantonese locale that you can use with TTS.
try
new Locale("yue", "HK"); //yue for 粤语
Once you have set the system language to Cantonese, then you can use setLanguage(Locale.getDefault()).

Android: switch to a different IME programmatically

http://developer.android.com/guide/topics/text/creating-input-method.html#GeneralDesign
reads:
Because multiple IMEs may be installed on the device, provide a way for the user to switch to a different IME directly from the input method UI.
Let's assume I have the source of two input methods and can modify it.
I want to let the user switch between them quickly and am ready to reserve a button for that.
How do I "switch to a different IME directly from the input method UI"?
Switching to the previous input method from the current input method is:
//final String LATIN = "com.android.inputmethod.latin/.LatinIME";
// 'this' is an InputMethodService
try {
InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
final IBinder token = this.getWindow().getWindow().getAttributes().token;
//imm.setInputMethod(token, LATIN);
imm.switchToLastInputMethod(token);
} catch (Throwable t) { // java.lang.NoSuchMethodError if API_level<11
Log.e(TAG,"cannot set the previous input method:");
t.printStackTrace();
}
If you want to switch to a particular input method whose ID you know, you may do as the commented-out lines suggest.
EDIT #pRaNaY suggested a single .getWindow() in a silent edit (click "edited" below to see the history). I remember that it did not work for Android 2.3; if you consult the docs, you will see that the first call, InputMethodService.getWindow() returns a Dialog (which is not a subclass of Window), and the second call, Dialog.getWindow() returns a Window. There is no Dialog.getAttributes(), so with a single .getWindow() it will not even compile.
You cannot change the user's currently active IME through code for security reasons, sorry.
However, you can show a system provided dialog to allow the user to select one of the other enabled ones.
InputMethodManager imeManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imeManager != null) {
imeManager.showInputMethodPicker();
} else {
Toast.makeText(context ,"Error", Toast.LENGTH_LONG).show();
}
If you have rooted device, you can use /system/bin/ime utility.
List all installed input methods: # ime list -a
Set google's keyboard as default:
ime set com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME

Categories

Resources