#977 - Reconnexion casque BT par éloignement part #2

This commit is contained in:
Jimmie Matsson 2020-02-13 21:02:07 +01:00
parent bc02a84f37
commit 4ad3159feb
6 changed files with 171 additions and 71 deletions

Binary file not shown.

View file

@ -5,6 +5,7 @@ import android.os.Build;
import com.dixitmobile.common.BuildConfig;
import com.dixitmobile.common.Lg;
import com.voixtreme.vocalengine.json.Bluetooth;
import com.voixtreme.vocalengine.service.VoiXtremeService;
import java.util.HashMap;
@ -316,12 +317,15 @@ public class AudioSystem {
/**
* Enforce Bluetooth headset
*/
void routeSoundBluetooth() {
void routeSoundBluetooth(String audioMode) {
if (mLastRoute == 2) {
return;
}
final boolean useNormal = audioMode.equals(Bluetooth.AUDIO_MODE_NORMAL);
final boolean useCommunication = audioMode.equals(Bluetooth.AUDIO_MODE_IN_COMMUNICATION);
mLastRoute = 2;
Lg.v(TAG, "routeSoundBluetooth(): " + Build.MODEL);
Lg.i(TAG, "eml: input type send error #16");
@ -332,22 +336,17 @@ public class AudioSystem {
}
Lg.i(TAG, "eml: input type send error #7");
switch (Build.MODEL) {
case VoiXtremeService.MODEL_ZEBRA_WT6000:
case VoiXtremeService.MODEL_ZEBRA_TC8000:
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mAudioManager.setSpeakerphoneOn(false);
Lg.i(TAG, "eml: input type send error #18");
if (useNormal || (!useCommunication && Build.MANUFACTURER.equals(VoiXtremeService.MANUFACTURER_ZEBRA))) {
Lg.i(TAG, "eml: audioMODE: " + Bluetooth.AUDIO_MODE_NORMAL);
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mAudioManager.setSpeakerphoneOn(false);
setDeviceConnectionState(DEVICE_IN_BLUETOOTH_SCO_HEADSET, true);
setDeviceConnectionState(DEVICE_OUT_BLUETOOTH_SCO_HEADSET, true);
break;
default:
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.setSpeakerphoneOn(false);
Lg.i(TAG, "eml: input type send error #19");
break;
setDeviceConnectionState(DEVICE_IN_BLUETOOTH_SCO_HEADSET, true);
setDeviceConnectionState(DEVICE_OUT_BLUETOOTH_SCO_HEADSET, true);
} else {
Lg.i(TAG, "eml: audioMODE: " + Bluetooth.AUDIO_MODE_IN_COMMUNICATION);
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.setSpeakerphoneOn(false);
}
Lg.e(TAG, "eml: setBluetoothScoOn(): true");

View file

@ -138,10 +138,15 @@ public class BluetoothSCOManager extends BroadcastReceiver {
Lg.i(TAG, "eml: start()");
mStarted = true;
mAudioSystem.routeSoundBluetooth();
mAudioSystem.routeSoundBluetooth(mService.getJson().microphone.bluetooth.audioMode);
registerReceivers();
}
public AudioManager getAudioManager() {
return mAudioManager;
}
/**
* Stop a SCO connection
*/
@ -198,7 +203,7 @@ public class BluetoothSCOManager extends BroadcastReceiver {
mHandler.removeCallbacks(mReStartRunnable);
if (mService != null && !mService.getJson().microphone.bluetooth.reconnectText.trim().isEmpty()) {
if (!mService.getJson().microphone.bluetooth.reconnectText.trim().isEmpty()) {
mService.getTTSParams().mWelcomeMessage = mService.getJson().microphone.bluetooth.reconnectText;
}
@ -317,7 +322,6 @@ public class BluetoothSCOManager extends BroadcastReceiver {
}
mConnectedSCO = true;
mBTDevice = getConnectedMAC();
Lg.v(TAG, "eml: scoConnected(): " + (mBTDevice == null ? "NULL" : mBTDevice.getAddress()));
// if (!mStarted) {
@ -391,24 +395,6 @@ public class BluetoothSCOManager extends BroadcastReceiver {
}
};
/**
* Try to get the MAC address of the Headset connected with BluetoothSCO
*
* @return Bluetooth headset device
*/
private BluetoothDevice getConnectedMAC() {
for (BluetoothDevice device : mBTAdapter.getBondedDevices()) {
if (BluetoothHelper.isMajorHeadset(device)) {
if (BluetoothHelper.isConnected(device)) {
return device;
}
}
}
return null;
}
/**
* Helper class for re-establishing a SCO connection with the headset
*/
@ -548,7 +534,7 @@ public class BluetoothSCOManager extends BroadcastReceiver {
Lg.i(TAG, "eml: deviceConnected #002");
start();
Lg.i(TAG, "eml: deviceConnected #003");
mAudioSystem.routeSoundBluetooth();
mAudioSystem.routeSoundBluetooth(mService.getJson().microphone.bluetooth.audioMode);
if (mReconnectSCO != null) {
Lg.i(TAG, "eml: deviceConnected #004");
@ -645,6 +631,7 @@ public class BluetoothSCOManager extends BroadcastReceiver {
if (isSameMAC && !mDeviceLost) {
mDeviceLost = true;
mDisconnectedTime = System.currentTimeMillis();
mHandler.removeCallbacks(mDisconnectedRunnable);
if (mLostSCO) {
mLostSCO = false;
@ -750,10 +737,11 @@ public class BluetoothSCOManager extends BroadcastReceiver {
*
* @param callback The callback interface used to get the status (will be cleared once done)
*/
public void testSCOStatus(SCOStatusInterface callback) {
public void testSCOStatus(SCOStatusInterface callback, BluetoothDevice device) {
Lg.i(TAG, "eml: testSCOStatus(): " + mConnectedSCO);
mSCOStatusCallback = callback;
mBTDevice = device;
if (mConnectedSCO) {
mSCOStatusCallback.connected();

View file

@ -7,9 +7,15 @@ import java.io.Serializable;
public class Bluetooth implements Serializable {
private static final long serialVersionUID = 6021273296241839069L;
public transient static final String AUDIO_MODE_NORMAL = "MODE_NORMAL";
public transient static final String AUDIO_MODE_IN_COMMUNICATION = "MODE_IN_COMMUNICATION";
@SerializedName("AbortSpeechWhenLost")
public boolean abortSpeechWhenLost;
@SerializedName("AudioMode")
public String audioMode;
@SerializedName("ScoReconnectTime")
public int scoReconnectTime;

View file

@ -106,6 +106,13 @@ public class VoiXtremeReceiver extends BroadcastReceiver {
mHandler.sendMessage( Message.obtain( mHandler, command));
break;
case BroadcastParams.COMMAND_BEEP_TEST:
Lg.i(TAG, "Intent COMMAND_BEEP_TEST");
Message m = Message.obtain( mHandler, command);
m.arg1 = (intent.getExtras().getBoolean(BroadcastParams.EXTRAS_DATA, false) ? 1 : 0);
mHandler.sendMessage(m);
break;
case BroadcastParams.COMMAND_REGISTER_LICENSE:
Lg.i(TAG, "Intent COMMAND_REGISTER_LICENSE");
// Trick to send strings with a handler

View file

@ -2,12 +2,18 @@ package com.voixtreme.vocalengine.service;
import android.app.Notification;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
@ -56,6 +62,7 @@ import java.util.Map;
public class VoiXtremeService extends VoiXtremeServiceBase
implements VocalizerEngineListener {
public static final String MANUFACTURER_ZEBRA = "Zebra Technologies";
public static final String MODEL_ZEBRA_WT6000 = "WT6000";
public static final String MODEL_ZEBRA_TC8000 = "TC8000";
public static final String MODEL_UNITECH_WD100 = "WD100";
@ -70,6 +77,8 @@ public class VoiXtremeService extends VoiXtremeServiceBase
private IncomingHandler mIncomingHandler= new IncomingHandler( this);
// Engines ASR and TTS -----------------------------------------
private MediaPlayer mMediaPlayer;
private Handler mHandler;
// The VoiXtreme API
private VxtEngineApi mVxtEngineApi = null;
@ -188,6 +197,7 @@ public class VoiXtremeService extends VoiXtremeServiceBase
startLoggerService(getApplicationContext(), getString(R.string.app_name));
super.onCreate();
mIsConfigured = false;
mHandler = new Handler(Looper.getMainLooper());
Lg.i(TAG, "eml: onCreate()");
@ -1133,35 +1143,19 @@ public class VoiXtremeService extends VoiXtremeServiceBase
sendLicence();
break;
case BroadcastParams.COMMAND_BEEP_TEST:
Lg.i(TAG, "update COMMAND_BEEP_TEST");
mVxtEngineApi.nativelog( 0, TAG, "updateFromHandler COMMAND_BEEP_TEST");
beepTest(idx == 1);
break;
case BroadcastParams.COMMAND_INITIALIZE_TTS:
Lg.i(TAG, "update COMMAND_INITIALIZE_TTS Voice=" + mVxtPkgManager.ttsVoice);
mVxtEngineApi.nativelog( 0, TAG, "updateFromHandler COMMAND_INITIALIZE_TTS Voice="+ mVxtPkgManager.ttsVoice);
if (mVxtEngineApi.vxtInitializeTTS( mVxtPkgManager.ttsVoice)) {
mIsConfigured = true;
final String path = Common.getPathExternalStorage(true)
+ "voixtreme/_vxt_configuration.jcf";
try {
FileReader fileReader = new FileReader(path);
mJson = new Gson().fromJson(fileReader, JsonMain.class);
} catch (Exception e) {
Lg.printStackTrace(TAG, e);
}
if (mJson == null || mJson.microphone == null || mJson.microphone.bluetooth == null) {
mJson = new JsonMain();
mJson.microphone = new Microphone();
mJson.microphone.bluetooth = new Bluetooth();
}
if (mJson.microphone.bluetooth.reconnectText == null) {
mJson.microphone.bluetooth.reconnectText = "";
}
if (mJson.microphone.bluetooth.scoReconnectTime <= 0) {
mJson.microphone.bluetooth.scoReconnectTime = 999;
}
Lg.v(TAG, "eml: json in params: " + new Gson().toJson(mJson));
}
break;
@ -1237,12 +1231,65 @@ public class VoiXtremeService extends VoiXtremeServiceBase
String textId = Integer.toString(mSay.mSayTtsId);
mIsUniqueResponse= true;
ttsEngine.speak( mVxtTtsManager.sayPhrase, false, textId);
if (ttsEngine != null && ttsEngine.isInitialized()) {
ttsEngine.speak( mVxtTtsManager.sayPhrase, false, textId);
} else {
Lg.e(TAG, "eml: IGNORING command, TTS not initialized: " + mVxtTtsManager.sayPhrase);
}
break;
}
}
private void beepTest(boolean start) {
Lg.v(TAG, "eml: beepTest(): " + start);
if (start) {
mSCOManager.getAudioManager().startBluetoothSco();
mMediaPlayer = new MediaPlayer();
try {
AssetFileDescriptor afd = getAssets().openFd("informational.wav");
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mMediaPlayer.prepare();
mHandler.postDelayed(mBeepRunnable, 1500);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intentOut = new Intent( mVxtPkgManager.intentPackage);
intentOut.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intentOut.putExtra(BroadcastParams.EXTRAS_ACTION, BroadcastParams.COMMAND_BEEP_TEST);
sendBroadcast(intentOut);
}
}, 1500);
} catch (Exception e) {
e.printStackTrace();
}
} else {
mHandler.removeCallbacks(mBeepRunnable);
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
}
private Runnable mBeepRunnable = new Runnable() {
@Override
public void run() {
if (mMediaPlayer != null) {
mMediaPlayer.start();
mHandler.postDelayed(this, 1500);
}
}
};
private class FailSave extends Thread {
@Override
@ -1345,7 +1392,7 @@ public class VoiXtremeService extends VoiXtremeServiceBase
sendInputConnectionStatus(false);
} else {
Lg.i(TAG, "eml: input type send error #5.1");
mSCOManager.testSCOStatus(mSCOTestCallback);
getBTDeviceSCO();
}
break;
@ -1360,7 +1407,7 @@ public class VoiXtremeService extends VoiXtremeServiceBase
sendInputConnectionStatus(false);
} else {
Lg.i(TAG, "eml: input type send error #8");
mSCOManager.testSCOStatus(mSCOTestCallback);
getBTDeviceSCO();
}
break;
}
@ -1403,10 +1450,40 @@ public class VoiXtremeService extends VoiXtremeServiceBase
}
};
private void getBTDeviceSCO() {
/**
* Inform calling app if input connection is available or not
*/
BluetoothAdapter.getDefaultAdapter().getProfileProxy(this, new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
int counter = 1;
BluetoothHeadset bluetoothHeadset = (BluetoothHeadset) proxy;
for (BluetoothDevice headset : bluetoothHeadset.getConnectedDevices()) {
Lg.v(TAG, "eml: headset proxy connected: " + counter + ": " + headset.getAddress());
if (counter++ == 1) {
mSCOManager.testSCOStatus(mSCOTestCallback, headset);
}
}
if (counter == 1) {
sendInputConnectionStatus(false);
}
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HEADSET, proxy);
}
public void onServiceDisconnected(int profile) {
}
}, BluetoothProfile.HEADSET);
}
/**
* Inform calling app if input connection is available or not
*/
public void sendInputConnectionStatus(boolean allOK) {
Lg.i(TAG, "eml: sendInputConnectionStatus(): " + allOK);
@ -1487,9 +1564,32 @@ public class VoiXtremeService extends VoiXtremeServiceBase
public JsonMain getJson() {
if (mJson == null) {
mJson = new JsonMain();
mJson.microphone = new Microphone();
mJson.microphone.bluetooth = new Bluetooth();
final String path = Common.getPathExternalStorage(true) + "voixtreme/_vxt_configuration.jcf";
try {
FileReader fileReader = new FileReader(path);
mJson = new Gson().fromJson(fileReader, JsonMain.class);
} catch (Exception e) {
Lg.printStackTrace(TAG, e);
}
if (mJson == null || mJson.microphone == null || mJson.microphone.bluetooth == null) {
mJson = new JsonMain();
mJson.microphone = new Microphone();
mJson.microphone.bluetooth = new Bluetooth();
}
if (mJson.microphone.bluetooth.reconnectText == null) {
mJson.microphone.bluetooth.reconnectText = "";
}
if (mJson.microphone.bluetooth.scoReconnectTime <= 0) {
mJson.microphone.bluetooth.scoReconnectTime = 999;
}
if (mJson.microphone.bluetooth.audioMode == null) {
mJson.microphone.bluetooth.audioMode = "DEFAULT";
}
Lg.v(TAG, "eml: json in params: " + new Gson().toJson(mJson));
}
return mJson;