I was trying to use:
_tts = new TextToSpeech(this, this);
_tts.setLanguage(new Locale("en"));
The result is always -2 (LANG_NOT_SUPPORTED), so I thought that I made a mistake in the string given to the constructor.
Then I tried using (Obviously English is supported, no?)
_tts.setLanguage(Locale.US);
But to no avail and with the same result.
Why can't I change the language of the TTS engine?
My device's Android is version 2.3, TTS engine is PICO.
public void onInit(final int status) {
if (status == TextToSpeech.SUCCESS) {
_init = true; Log.d(TAG, "TTS init completed succesfully.");
setQueueMode(TextToSpeech.QUEUE_FLUSH);
}
}
The problem is that you are trying to set the language before initializing the TTS engine, instead of setting the language after creating the object do it at onInit callback.
public void onInit(final int status) {
if (status == TextToSpeech.SUCCESS) {
_init = true;
Log.d(TAG, "TTS init completed succesfully.");
int result = _tts.setLanguage(Locale.US);
}
}
Related
I am currently implement a feature where the users are requested to ignore battery optimisation for the application. The reason for doing so, is that the main functionality of the application is unfortunately drastically affected by power save mode.
To achieve my goal, I prompt the users by creating an Intent and setting the Action to ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS.
Although, before firing the Intent, I both check for isPowerSaveMode() and isIgnoringBatteryOptimizations() to ensure that I don't prompt the users when power save mode is not enabled; which is a requirement for the feature. The way I do so is by:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isPowerSaveMode = pm.isPowerSaveMode(); // always returns false for Huawei devices
This works fine for the most devices, but for Huawei devices, isPowerSaveMode() always returns false. Consequently, since the preconditions fail, the prompt is never shown.
Has anyone else possibly encountered this issue? If so, what did you do to solve it?
As a note, the same issue is also present in the Xamarin.Android SDK.
Some Chinese ROM like Huawei or Xiaomi didn't implement the standard API for power save mode query. But like other system settings, a state flag will be saved to database when user turn power save mode on/off.
So we can utilize this state flag to solve the compatibility problem. Also a specific intent will send by system when toggle power save mode, we can listen this intent action to monitor power save mode changing.
Below is the detailed kotlin code implementation for Huawei or Xiaomi devices.
object PowerManagerCompat {
private const val TAG = "PowerManagerCompat"
interface PowerSaveModeChangeListener {
/**
* will be called when power save mode change, new state can be query via [PowerManagerCompat.isPowerSaveMode]
*/
fun onPowerSaveModeChanged()
}
private val POWER_SAVE_MODE_VALUES = mapOf(
"HUAWEI" to 4,
"XIAOMI" to 1
)
private val POWER_SAVE_MODE_SETTING_NAMES = arrayOf(
"SmartModeStatus", // huawei setting name
"POWER_SAVE_MODE_OPEN" // xiaomi setting name
)
private val POWER_SAVE_MODE_CHANGE_ACTIONS = arrayOf(
"huawei.intent.action.POWER_MODE_CHANGED_ACTION",
"miui.intent.action.POWER_SAVE_MODE_CHANGED"
)
private const val monitorViaBroadcast = true
/**
* Monitor power save mode change, only support following devices
* * Xiaomi
* * Huawei
*/
fun monitorPowerSaveModeChange(context: Context, powerSaveModeChangeListener: PowerSaveModeChangeListener) {
if (Build.MANUFACTURER.toUpperCase(Locale.getDefault()) !in POWER_SAVE_MODE_VALUES.keys) {
Log.w(TAG, "monitorPowerSaveModeChange: doesn't know how to monitor power save mode change for ${Build.MANUFACTURER}")
}
if (monitorViaBroadcast) {
context.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
powerSaveModeChangeListener.onPowerSaveModeChanged()
}
}, IntentFilter().also {
for (a in POWER_SAVE_MODE_CHANGE_ACTIONS) {
it.addAction(a)
}
})
} else {
val contentObserver = object : ContentObserver(null) {
override fun onChange(selfChange: Boolean) {
super.onChange(selfChange)
powerSaveModeChangeListener.onPowerSaveModeChanged()
}
}
for (name in POWER_SAVE_MODE_SETTING_NAMES) {
context.contentResolver.registerContentObserver(
Uri.parse("content://settings/system/${name}"), false, contentObserver)
}
}
}
/**
* Check the system is currently in power save mode
* #see [PowerManager.isPowerSaveMode]
*/
fun isPowerSaveMode(context: Context): Boolean {
if (Build.MANUFACTURER.toUpperCase(Locale.getDefault()) in POWER_SAVE_MODE_VALUES.keys) {
return isPowerSaveModeCompat(context)
}
val powerManager = context.getSystemService(Context.POWER_SERVICE) as? PowerManager
return powerManager?.isPowerSaveMode ?: false
}
private fun isPowerSaveModeCompat(context: Context): Boolean {
for (name in POWER_SAVE_MODE_SETTING_NAMES) {
val mode = Settings.System.getInt(context.contentResolver, name, -1)
if (mode != -1) {
return POWER_SAVE_MODE_VALUES[Build.MANUFACTURER.toUpperCase(Locale.getDefault())] == mode
}
}
return false
}
}
Each oem modifies the SDK to suit their needs . Huawei devices don't use the default power saver function , instead they use something called "Protected apps". Protected apps are set of apps which are allowed to run even when the screen is turned off. So that's the reason it always returns false . Its better to throw a intent to protected apps screen but there is no way to know if your app is added to the protected apps list.
What is protected apps ?
I've found a way to manually request current Huawei Power Mode state and receive change events by adding a custom action to the IntentFilter:
(Note tested only on Huawei P20 Lite (ANE-LX3) # EMUI 8.0.0)
// Manually request Power Save Mode:
public Boolean isPowerSaveMode(Context context) {
if (Build.MANUFACTURER.equalsIgnoreCase("Huawei")) {
return isPowerSaveModeHuawei(context);
} else {
return isPowerSaveModeAndroid(context);
}
}
#TargetApi(21)
private Boolean isPowerSaveModeAndroid(Context context) {
boolean isPowerSaveMode = false;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (pm != null) isPowerSaveMode = pm.isPowerSaveMode();
}
return isPowerSaveMode;
}
private Boolean isPowerSaveModeHuawei(Context context) {
try {
int value = android.provider.Settings.System.getInt(context.getContentResolver(), "SmartModeStatus");
return (value == 4);
} catch (Settings.SettingNotFoundException e) {
// Setting not found? Return standard android mechanism and hope for the best...
return isPowerSaveModeAndroid(context);
}
}
// Listening for changes in Power Save Mode
public void startMonitoringPowerSaveChanges(Context context) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mPowerSaveChangeReceiver != null) {
return;
}
// Register for PowerSaver change updates.
mPowerSaveChangeReceiver = new PowerSaveChangeReceiver();
// Registering the receiver
IntentFilter filter = new IntentFilter();
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
// Add custom huawei action
filter.addAction("huawei.intent.action.POWER_MODE_CHANGED_ACTION");
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
filter.addAction(android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
}
context.registerReceiver(mPowerSaveChangeReceiver, filter);
}
}
#TargetApi(21)
class PowerSaveChangeReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
boolean isPowerSaveMode = false;
// Oh, Huawei...why don't you play by the same rules as everyone else?
if (intent.getAction().equals("huawei.intent.action.POWER_MODE_CHANGED_ACTION")) {
Bundle extras = intent.getExtras();
if ((extras != null) && extras.containsKey("state")) {
int state = intent.getExtras().getInt("state");
isPowerSaveMode = (state == 1); // ON=1; OFF=2
}
} else {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
isPowerSaveMode = pm.isPowerSaveMode();
}
Log.d("MyTag", "[powersavechange] isPowerSaveMode? " + isPowerSaveMode);
}
}
I have faced new the same problem while inmplementation handheld and wearable devices.
The only solution I found is to disable battery saver mode for all apps.
I would suggest to detect the result of your methods after disabling such mode for all apps. This bug appear only on Huawei. Awful vendor.
private void isPowerSaveModeHuaweiXiaomi(){
if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) {
try {
int value = android.provider.Settings.System.getInt(getContext().getContentResolver(), "POWER_SAVE_MODE_OPEN");
} catch (Settings.SettingNotFoundException e) {
Log.d("Valor modo bateria:", "Error");
}
}else if (Build.MANUFACTURER.equalsIgnoreCase("Huawei")){
try {
int value = android.provider.Settings.System.getInt(getContext().getContentResolver(), "SmartModeStatus");
} catch (Settings.SettingNotFoundException e) {
Log.d("Valor modo bateria:", "Error");
}
}
}
On new Huawei devices such as Huawei P30 lite for instance the solution to this question is unknown as for now (27.12.2021). calling getInt with the key "SmartModeStatus" will throw a key unknown exception. Therefore the best we can do is the following.
private string HuaweiPowerSaveModeSettingsName = "SmartModeStatus";
private int HuaweiPowerSaveModeValue = 4;
public bool IsBatterySaverEnabled
=> Build.Manufacturer?.ToUpper() == "HUAWEI" ? GetIsBatterySaverEnabledHuawei() : GetIsBatterySaverEnabledAllDevicesExceptHuawei();
private bool GetIsBatterySaverEnabledAllDevicesExceptHuawei()
{
return PowerManager.FromContext(Application.Context)?.IsPowerSaveMode ?? false;
}
private bool GetIsBatterySaverEnabledHuawei()
{
try
{
var mode = Settings.System.GetInt(Application.Context.ContentResolver, HuaweiPowerSaveModeSettingsName);
return HuaweiPowerSaveModeValue == mode;
} catch (Exception e)
{
return GetIsBatterySaverEnabledAllDevicesExceptHuawei();
}
}
For huawei vtr-al00, SmartModeStatus 1 could be ultra save mode or the normal mode. I've used reflection to handle this.
final int _HX = Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")?2
:Build.MANUFACTURER.equalsIgnoreCase("Huawei")?1
:0;
// “No Kotlin”
private boolean isPowerSaveModeCompat(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& powerManager.isPowerSaveMode()) { // hopefully...
return true;
}
if (_HX==0) {
return false;
}
else if (_HX==1) {
try {
int value = Settings.System.getInt(getContentResolver(), "SmartModeStatus");
CMN.debug("isPowerSaveModeCompat::huawei::"+value);
// value 4==Save Mode; 1==Ultra Save Mode==Normal Mode;
// ( tested on my huawei vtr-al00 )
if(value==4) {
return true;
}
if(value==1) {
// what if Ultra save mode???
// https://github.com/huaweigerrit
// https://github.com/SivanLiu/HwFrameWorkSource
// https://stackoverflow.com/questions/2641111/where-is-android-os-systemproperties
// Class sysProp= Class.forName("android.os.SystemProperties");
// Method sysProp_getBool = sysProp.getMethod("getBoolean", new Class[]{String.class, boolean.class});
// Object[] parms = new Object[]{"sys.super_power_save", false};
// CMN.debug("huawei::UltraPowerSave::", sysProp_getBool.invoke(null, parms));
// CMN.debug("huawei::UltraPowerSave::", getSystemProperty("sys.super_power_save"));
return "true".equals(getSystemProperty("sys.super_power_save"));
}
} catch (Exception e) {
CMN.debug(e);
}
}
else if (_HX==2){
try {
int value = Settings.System.getInt(getContentResolver(), "POWER_SAVE_MODE_OPEN");
CMN.debug("isPowerSaveModeCompat::xiaomi::"+value);
// dont have xiaomi. not tested.
return value==1;
} catch (Exception e) {
CMN.debug(e);
}
}
// else if...
return false;
}
// https://stackoverflow.com/questions/9937099/how-to-get-the-build-prop-values
public String getSystemProperty(String key) {
String value = null;
try {
value = (String) Class.forName("android.os.SystemProperties")
.getMethod("get", String.class).invoke(null, key);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
Java is just shorter kotlin, even with so many comments and dirty tests!
:)
i'm beginner of BLE(Bluetooth-LowEnergy). I wanted to get data from android device via BLE.
I've already read about characteristic in Google Document.
and i've already searched on google too.
my device didn't respond to my request byte code.
i think it's because i set wrong characteristics.
cus i think i didn't understand about characteristics perfectly.
does anybody help me to set right characteristics please ?
Here's custom Uuid(it's better to see added Images on the top.)
CUSTOM SERVICE
0783b03e-8535-b5a0-7140-a304d2495cb7
NOTIFY Uuid : 0783B03E-8535-B5A0-7140-A304D2495CB8
Read Uuid : 00002a19-0000-1000-8000-00805f9b34fb
Write Uuid : 0783b03e-8535-b5a0-7140-a304d2495cba
and Here's Uuid I set
public final UUID serviceUuid = UUID.fromString("0783b03e-8535-b5a0-7140-a304d2495cb7");
public final UUID notifyUuid = UUID.fromString("0783b03e-8535-b5a0-7140-a304d2495cb8");
public final UUID readUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
public final UUID writeUuid = UUID.fromString("0783b03e-8535-b5a0-7140-a304d2495cba");
and Here's my code
BluetoothHandler.java
targetGattCharacteristic = targetGattService.getCharacteristic(Define.GetInstance().notifyUuid);
BluetoothGattCharacteristic readGattCharacteristic = targetGattService.getCharacteristic(Define.GetInstance().notifyUuid);
if (readGattCharacteristic != null) {
mBleService.setCharacteristicNotification(readGattCharacteristic, true);
} else {
callInterface();
return;
}
(BluetoothService.java)
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
BluetoothGattDescriptor gD = new BluetoothGattDescriptor(UUID.fromString(Define.GetInstance().readUuid.toString()), BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattDescriptor.PERMISSION_READ);
characteristic.addDescriptor(gD);
if (Define.GetInstance().notifyUuid.equals(characteristic.getUuid())) {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
UUID.fromString(Define.GetInstance().readUuid.toString()));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
i solved it by referring to this site.
https://medium.com/#avigezerit/bluetooth-low-energy-on-android-22bc7310387a
So, I am developing a Java BLE Android Module using Eclipse (to code the module and Appcelerator (to make the Android App). I am trying to receive data from a BLE Device and show it on an Android Phone. I can scan the device and connect to it.
But I really, really can't receive any data from it.
I have tried at least 10 different stuff but...
The main problem is that I don't know the BLE API very well, and I am a little noobie in Java. Can anyone please help a poor soul to actually read the data from the device?
The main problem is setting the Bluetooth Characteristic UUID (which I have). I just don't know how to do it...
Bellow are the codes for the Module...
public class AndroidbleModule extends KrollModule {
public static final String LCAT = "BLE";
private BluetoothManager btManager;
private BluetoothAdapter btAdapter;
private BluetoothDevice btDevice;
private TiApplication appContext;
private Activity activity;
private KrollFunction onFound;
private KrollFunction onConnections;
private BluetoothLeScanner btScanner;
private UUID uuid;
BluetoothGatt bluetoothGatt;
BluetoothGattCharacteristic btChar;
BluetoothGattCallbackHandler btData;
KrollDict kd;
Boolean isConnected = false;
BluetoothGatt connectedGatt;
private ScanCallback scanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
if (device != null) {
BluetoothDeviceProxy btDeviceProxy = new
BluetoothDeviceProxy(device);
if (device.getName() != null) {
Log.d(LCAT, "Found: " + device.getName() + " " +
device.getAddress());
ArrayList<String> ids = new ArrayList<String>();
if (device.getUuids() != null) {
for (ParcelUuid id1 : device.getUuids()) {
ids.add(id1.toString());
}
}
btDevice = device;
kd = new KrollDict();
kd.put("name", btDevice.getName());
kd.put("macaddress", btDevice.getAddress());
fireEvent("nb_DevicesFound", kd);
btScanner.stopScan(scanCallback);
}
}
}
};
#Kroll.method
public boolean connect()
{
try {
bluetoothGatt = btDevice.connectGatt(appContext, true,
new BluetoothGattCallbackHandler(AndroidbleModule.this));
if (bluetoothGatt != null) {
System.out.println("***** ***** Connected to: =====>>>>> " + btDevice.getAddress() + " " + btDevice.getName());
this.fireEvent("nb_onConnect",null);
isConnected = true;
bluetoothGatt = connectedGatt;
}
} catch (Exception e) {
isConnected = false;
this.fireEvent("nb_NoConnection", null);
}
return true;
};
#Kroll.method
public void readData()
{
System.out.println("WHAT THE HELL DO I DO????");
}
}
public final class BluetoothGattCallbackHandler extends
BluetoothGattCallback {
private static final String LCAT = AndroidbleModule.LCAT;
private KrollProxy proxy;
private static final String UUID_SERVICE_TS002004 = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
private static final String UUID_CHARACTERISTIC_WRITE_TS002004 = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E";
private static final String UUID_CHARACTERISTIC_NOTIFY_TS002004 = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";
BluetoothGattCharacteristic btCharacteristic;
public BluetoothGattCallbackHandler(KrollProxy proxy) {
super();
this.proxy = proxy;
}
#Override
public void onConnectionStateChange(final BluetoothGatt gatt,
final int status, final int newState) {
KrollDict kd = new KrollDict();
kd.put("newState", newState);
kd.put("status", status);
if (proxy.hasListeners("didConnectionStateChange")) {
proxy.fireEvent("didConnectionStateChange", kd);
}
gatt.discoverServices();
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
Log.i(LCAT,"onServicesDiscovered");
if (status != BluetoothGatt.GATT_SUCCESS) return;
btCharacteristic =
gatt.getService(UUID.fromString(UUID_SERVICE_TS002004)).getCharacteristic(UUID.fromString(UUID_CHARACTERISTIC_NOTIFY_TS002004));
gatt.setCharacteristicNotification(btCharacteristic,true);
BluetoothGattDescriptor descriptor = btCharacteristic.getDescriptor(UUID.fromString(UUID_CHARACTERISTIC_WRITE_TS002004));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic) {
byte[] data = characteristic.getValue();
Log.i(LCAT, "Char changed " + data.toString());
for (BluetoothGattDescriptor descriptor :
characteristic.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
}
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
Log.i(LCAT,"onCharacteristicRead");
}
#Override
public void onDescriptorRead(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
Log.i(LCAT,"onDescriptorRead");
}
}
I expect to some good soul that will go to Heaven to have mercy on me and help me get those sweet bytes of data.
One of the things that is missing in your code, is to Set Notifications, so the Central can listen to the Peripheral's response.
Try something like this:
public void setNotifications() {
BluetoothGattService service = bluetoothGatt.getService(SERVICE_UUID);
BluetoothGattCharacteristic characteristic = service.getCharacteristic(CHARACTERISTIC_UUID);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(DESCRIPTOR_UUID);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
characteristic.addDescriptor(descriptor);
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
bluetoothGatt.writeDescriptor(descriptor);
bluetoothGatt.setCharacteristicNotification(characteristic, true);
}
After that, you can send commands to the device and hear it's return.
public void returnData(String data) {
BluetoothGattService service = bluetoothGatt.getService(SERVICE_UUID);
BluetoothGattCharacteristic characteristic = service.getCharacteristic(CHARACTERISTIC_UUID);
String dataString = data;
dataString.getBytes();
writeCharacteristic.setValue(dataString);
writeCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
bluetoothGatt.writeCharacteristic(writeCharacteristic);
}
First of all, read the bluetooth overview. Check if bluetooth permissions have been added to the project.
One thing that is wrong here is that isConnected=true is set too early, because you can consider that you are connected after ble services has been discovered and (status == BluetoothGatt.GATT_SUCCESS). Otherwise, you can't read and write characteristics.
A good starting point can be this repo from google. It is old project and I'm not sure if you have to update some dependency to make it compile, but nothing important.
Establish a connection and start reading bytes is easy, but if you want establish a reliable connection with ble device, due to android fragmentation and manufacturerers that don't follow the bluetooth specs, it can be super difficult, almost imposible to make a bluetooth low energy that works perfect for all devices.
Once you have started to read some bytes, I suggest this video to learn some important tricks about. If you want go deeper, read carefully this fantastic resource about ble.
Once you start to get desperate with ble, probably it will be a good moment to read this list of known issues
Finally, you will discover that the best thing that you can do with ble low energy in android is use open source libraries like the Nordic semiconductor ble library or RxAndroid Ble.
But before use a ble library, it is a good practice understand what is doing the library and understand why you need it.
EDIT: I have never used appcelerator, but here you have a bluetooth module for appcelerator titanium.
You have the wrong uuid for the Client Characteristic Configuration Descriptor. It should be 00002902-0000-1000-8000-00805f9b34fb but you have written 6E400002-B5A3-F393-E0A9-E50E24DCCA9E.
I'm working on an android Studio project, requiring text to speech.
I would like to implement a program which can recognize in which language the text is written and read it with the appropriate pronunciation.
Example : if i have a text in English, i want the application to pronounce it in English with the English pronunciation.
Is it possible ?
Thank you
I have successfully implemented TTS in French and it works fine.
mTTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = mTTS.setLanguage(Locale.FRENCH);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "Language not supported");
} else {
mButtonSpeak.setEnabled(true);
}
} else {
Log.e("TTS", "Initialization failed");
}
}
});
I would like to have a multilingual text to speech app
Thank you
You can identify the language of a text with Android ML Kit
Add the dependencies for the ML Kit Android libraries to your module (app-level) Gradle file (usually app/build.gradle):
dependencies {
// ...
implementation 'com.google.firebase:firebase-ml-natural-language:20.0.0'
implementation 'com.google.firebase:firebase-ml-natural-language-language-id-model:20.0.0'
}
To identify the language of a string, get an instance of FirebaseLanguageIdentification, and then pass the string to the identifyLanguage()method.
For example:
FirebaseLanguageIdentification languageIdentifier =
FirebaseNaturalLanguage.getInstance().getLanguageIdentification();
languageIdentifier.identifyLanguage(text)
.addOnSuccessListener(
new OnSuccessListener<String>() {
#Override
public void onSuccess(#Nullable String languageCode) {
if (languageCode != "und") {
Log.i(TAG, "Language: " + languageCode);
} else {
Log.i(TAG, "Can't identify language.");
}
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Model couldn’t be loaded or other internal error.
// ...
}
});
this method keep returning 0. According to the developer docs this method should return something like SUCCES if the device got the newest version of google play. Does anybody know how to use this?
#Override
public void onResume() {
super.onResume();
GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
System.out.println("henkie: " + GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext()));
}
It is returning SUCCESS. The documentation clearly states that the method had an int return type, and returns a
status code indicating whether there was an error. Can be one of
following in ConnectionResult: SUCCESS, SERVICE_MISSING,
SERVICE_VERSION_UPDATE_REQUIRED, SERVICE_DISABLED, SERVICE_INVALID.
To check against what was returned, use something like:
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if(status == ConnectionResult.SUCCESS) {
//Success! Do what you want
}
Please read the documentation: 0 is SUCCESS
public static final int SUCCESS
The connection was successful.
Constant Value: 0 (0x00000000)
Documentation
Simply
int statusCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (statusCode == ConnectionResult.SUCCESS) {
//OK
}
int state = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (state == ConnectionResult.SUCCESS) {
Toast.makeText(this, "SUCCESS", Toast.LENGTH_LONG).show();
//goAhead();
} else {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(state, this, -1);
dialog.show();
}