Reworked Bluetooth manager for Android 3.0+, working better now
This commit is contained in:
parent
734c3b7625
commit
d73ff36208
3 changed files with 279 additions and 174 deletions
|
@ -17,13 +17,22 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener.AudioState;
|
||||
import org.linphone.compatibility.Compatibility;
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.mediastream.Version;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
|
||||
|
@ -32,50 +41,248 @@ import android.os.Build;
|
|||
*/
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public class BluetoothManager extends BroadcastReceiver {
|
||||
private static BluetoothManager instance;
|
||||
|
||||
private Context mContext;
|
||||
private AudioManager mAudioManager;
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
private BluetoothHeadset mBluetoothHeadset;
|
||||
private BluetoothDevice mBluetoothDevice;
|
||||
private BluetoothProfile.ServiceListener mProfileListener;
|
||||
private BroadcastReceiver bluetoothActionReceiver = new BluetoothActionReceiver();
|
||||
private boolean isBluetoothConnected;
|
||||
private boolean isUsingBluetoothAudioRoute;
|
||||
|
||||
public static BluetoothManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new BluetoothManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not call !
|
||||
*/
|
||||
public BluetoothManager() {
|
||||
isBluetoothConnected = false;
|
||||
isUsingBluetoothAudioRoute = false;
|
||||
try {
|
||||
mContext = LinphoneManager.getInstance().getContext();
|
||||
mAudioManager = ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE));
|
||||
instance = this;
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
public void startBluetooth() {
|
||||
if (isBluetoothConnected) {
|
||||
Log.e("Bluetooth already started");
|
||||
return;
|
||||
}
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction("android.bluetooth.device.action.ACL_CONNECTED");
|
||||
filter.addAction("android.bluetooth.device.action.ACL_DISCONNECTED");
|
||||
filter.addAction("android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED");
|
||||
mContext.registerReceiver(this, filter);
|
||||
Log.d("Bluetooth receiver started");
|
||||
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
if (mBluetoothAdapter.isEnabled()) {
|
||||
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
||||
if (mProfileListener != null) {
|
||||
Log.w("Bluetooth headset profile was already opened, let's close it");
|
||||
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
|
||||
}
|
||||
|
||||
mProfileListener = new BluetoothProfile.ServiceListener() {
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
if (profile == BluetoothProfile.HEADSET) {
|
||||
Log.d("Bluetooth headset connected");
|
||||
mContext.registerReceiver(bluetoothActionReceiver, new IntentFilter(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT));
|
||||
mBluetoothHeadset = (BluetoothHeadset) proxy;
|
||||
isBluetoothConnected = true;
|
||||
}
|
||||
}
|
||||
public void onServiceDisconnected(int profile) {
|
||||
if (profile == BluetoothProfile.HEADSET) {
|
||||
mContext.unregisterReceiver(bluetoothActionReceiver);
|
||||
mBluetoothHeadset = null;
|
||||
isBluetoothConnected = false;
|
||||
Log.d("Bluetooth headset disconnected");
|
||||
LinphoneManager.getInstance().routeAudioToSpeaker();
|
||||
}
|
||||
}
|
||||
};
|
||||
boolean success = mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
|
||||
if (!success) {
|
||||
Log.e("Bluetooth getProfileProxy failed !");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.w("Bluetooth interface disabled on device");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean routeAudioToBluetooth() {
|
||||
return routeAudioToBluetooth(false);
|
||||
}
|
||||
|
||||
private boolean routeAudioToBluetooth(boolean isRetry) {
|
||||
if (mBluetoothAdapter == null) {
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
|
||||
if (mBluetoothAdapter.isEnabled() && mAudioManager.isBluetoothScoAvailableOffCall()) {
|
||||
isUsingBluetoothAudioRoute = isBluetoothHeadsetAvailable();
|
||||
|
||||
if (isUsingBluetoothAudioRoute) {
|
||||
if (mAudioManager != null) {
|
||||
mAudioManager.setBluetoothScoOn(true);
|
||||
mAudioManager.startBluetoothSco();
|
||||
LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
|
||||
}
|
||||
} else {
|
||||
LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER);
|
||||
}
|
||||
|
||||
isUsingBluetoothAudioRoute = mBluetoothHeadset.isAudioConnected(mBluetoothDevice);
|
||||
if (!isUsingBluetoothAudioRoute && !isRetry) {
|
||||
Log.w("Routing audio to bluetooth headset failed, retry....");
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {}
|
||||
return routeAudioToBluetooth(true);
|
||||
} else if (isRetry) {
|
||||
if (isUsingBluetoothAudioRoute) {
|
||||
Log.d("Retry worked, audio is routed to bluetooth headset");
|
||||
} else {
|
||||
Log.e("Retry not worked, audio isn't routed to bluetooth headset...");
|
||||
disableBluetoothSCO();
|
||||
}
|
||||
} else {
|
||||
Log.d("Routing audio to bluetooth headset worked at first try");
|
||||
}
|
||||
|
||||
return isUsingBluetoothAudioRoute;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUsingBluetoothAudioRoute() {
|
||||
return mBluetoothHeadset.isAudioConnected(mBluetoothDevice);
|
||||
}
|
||||
|
||||
public boolean isBluetoothHeadsetAvailable() {
|
||||
if (mBluetoothAdapter == null) {
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
|
||||
if (mBluetoothAdapter.isEnabled() && mAudioManager.isBluetoothScoAvailableOffCall()) {
|
||||
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
||||
boolean isHeadsetConnected = false;
|
||||
if (mBluetoothHeadset != null) {
|
||||
List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
|
||||
for (final BluetoothDevice dev : devices) {
|
||||
if (mBluetoothHeadset.getConnectionState(dev) == BluetoothHeadset.STATE_CONNECTED) {
|
||||
mBluetoothDevice = dev;
|
||||
isHeadsetConnected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Log.d(isHeadsetConnected ? "Headset found, bluetooth audio route available" : "No headset found, bluetooth audio route unavailable");
|
||||
}
|
||||
return isHeadsetConnected;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void disableBluetoothSCO() {
|
||||
isUsingBluetoothAudioRoute = false;
|
||||
if (mAudioManager != null) {
|
||||
mAudioManager.stopBluetoothSco();
|
||||
mAudioManager.setBluetoothScoOn(false);
|
||||
Log.w("Bluetooth sco disconnected!");
|
||||
}
|
||||
}
|
||||
|
||||
public void stopBluetooth() {
|
||||
Log.w("Stopping bluetooth...");
|
||||
isBluetoothConnected = false;
|
||||
isUsingBluetoothAudioRoute = false;
|
||||
|
||||
if (mAudioManager != null) {
|
||||
mAudioManager.stopBluetoothSco();
|
||||
mAudioManager.setBluetoothScoOn(false);
|
||||
}
|
||||
|
||||
if (mProfileListener != null && mBluetoothHeadset != null) {
|
||||
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
|
||||
mContext.unregisterReceiver(bluetoothActionReceiver);
|
||||
mProfileListener = null;
|
||||
mBluetoothHeadset = null;
|
||||
}
|
||||
mBluetoothDevice = null;
|
||||
|
||||
Log.w("Bluetooth stopped!");
|
||||
|
||||
if (LinphoneManager.getLc().getCallsNb() > 0) {
|
||||
Log.w("Bluetooth disabled, Going back to incall mode");
|
||||
Compatibility.setAudioManagerInCallMode(mAudioManager);
|
||||
}
|
||||
|
||||
try {
|
||||
mContext.unregisterReceiver(this);
|
||||
Log.d("Bluetooth receiver stopped");
|
||||
} catch (Exception e) {}
|
||||
|
||||
if (LinphoneManager.isInstanciated()) {
|
||||
LinphoneManager.getInstance().routeAudioToSpeaker();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
try {
|
||||
stopBluetooth();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!LinphoneManager.isInstanciated())
|
||||
return;
|
||||
|
||||
String action = intent.getAction();
|
||||
LinphoneManager lm = LinphoneManager.getInstance();
|
||||
|
||||
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
|
||||
Log.e("Bluetooth Received Event" + " ACTION_ACL_DISCONNECTED" );
|
||||
Log.d("Bluetooth Received Event" + " ACTION_ACL_DISCONNECTED");
|
||||
|
||||
if (lm != null) {
|
||||
lm.scoDisconnected();
|
||||
lm.routeAudioToReceiver();
|
||||
}
|
||||
stopBluetooth();
|
||||
}
|
||||
else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
|
||||
Log.e("Bluetooth Received Event" + " ACTION_ACL_CONNECTED" );
|
||||
|
||||
if (lm != null) {
|
||||
lm.scoConnected();
|
||||
}
|
||||
Log.d("Bluetooth Received Event" + " ACTION_ACL_CONNECTED");
|
||||
startBluetooth();
|
||||
}
|
||||
else if (AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED.equals(action)) {
|
||||
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 0);
|
||||
Log.e("Bluetooth sco state changed : " + state);
|
||||
Log.d("Bluetooth sco state changed : " + state);
|
||||
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
|
||||
if (lm != null) {
|
||||
lm.scoConnected();
|
||||
}
|
||||
startBluetooth();
|
||||
} else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
|
||||
if (lm != null) {
|
||||
lm.scoDisconnected();
|
||||
lm.routeAudioToReceiver();
|
||||
}
|
||||
stopBluetooth();
|
||||
}
|
||||
}
|
||||
//Using real value instead of constant because not available before sdk 11
|
||||
else if ("android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED".equals(action)) { //BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED
|
||||
int currentConnState = intent.getIntExtra("android.bluetooth.adapter.extra.CONNECTION_STATE", //BluetoothAdapter.EXTRA_CONNECTION_STATE
|
||||
0); //BluetoothAdapter.STATE_DISCONNECTED
|
||||
Log.e("Bluetooth state changed: " + currentConnState);
|
||||
if (lm != null && currentConnState == 2) { //BluetoothAdapter.STATE_CONNECTED
|
||||
lm.startBluetooth();
|
||||
Log.d("Bluetooth state changed: " + currentConnState);
|
||||
if (currentConnState == 2) { //BluetoothAdapter.STATE_CONNECTED
|
||||
startBluetooth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ public class InCallActivity extends FragmentActivity implements
|
|||
slideOutTopToBottom = AnimationUtils.loadAnimation(this, R.anim.slide_out_top_to_bottom);
|
||||
}
|
||||
|
||||
if (LinphoneManager.getInstance().isBluetoothScoConnected) {
|
||||
if (BluetoothManager.getInstance().isBluetoothHeadsetAvailable()) {
|
||||
try {
|
||||
if (routeLayout != null)
|
||||
routeLayout.setVisibility(View.VISIBLE);
|
||||
|
@ -292,7 +292,7 @@ public class InCallActivity extends FragmentActivity implements
|
|||
} else {
|
||||
speaker.setBackgroundResource(R.drawable.speaker_off);
|
||||
routeSpeaker.setBackgroundResource(R.drawable.route_speaker_off);
|
||||
if (LinphoneManager.getInstance().isUsingBluetoothAudioRoute) {
|
||||
if (BluetoothManager.getInstance().isUsingBluetoothAudioRoute()) {
|
||||
routeReceiver.setBackgroundResource(R.drawable.route_receiver_off);
|
||||
routeBluetooth.setBackgroundResource(R.drawable.route_bluetooth_on);
|
||||
} else {
|
||||
|
@ -404,13 +404,14 @@ public class InCallActivity extends FragmentActivity implements
|
|||
hideOrDisplayAudioRoutes();
|
||||
}
|
||||
else if (id == R.id.routeBluetooth) {
|
||||
LinphoneManager.getInstance().routeAudioToBluetooth();
|
||||
if (BluetoothManager.getInstance().routeAudioToBluetooth()) {
|
||||
isSpeakerEnabled = false;
|
||||
routeBluetooth.setBackgroundResource(R.drawable.route_bluetooth_on);
|
||||
routeReceiver.setBackgroundResource(R.drawable.route_receiver_off);
|
||||
routeSpeaker.setBackgroundResource(R.drawable.route_speaker_off);
|
||||
hideOrDisplayAudioRoutes();
|
||||
}
|
||||
}
|
||||
else if (id == R.id.routeReceiver) {
|
||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
||||
isSpeakerEnabled = false;
|
||||
|
@ -493,9 +494,12 @@ public class InCallActivity extends FragmentActivity implements
|
|||
}
|
||||
|
||||
private void showVideoView() {
|
||||
isSpeakerEnabled = true;
|
||||
if (!BluetoothManager.getInstance().isBluetoothHeadsetAvailable()) {
|
||||
Log.w("Bluetooth not available, using speaker");
|
||||
LinphoneManager.getInstance().routeAudioToSpeaker();
|
||||
isSpeakerEnabled = true;
|
||||
speaker.setBackgroundResource(R.drawable.speaker_on);
|
||||
}
|
||||
video.setBackgroundResource(R.drawable.video_off);
|
||||
|
||||
LinphoneManager.stopProximitySensorForActivity(InCallActivity.this);
|
||||
|
@ -547,6 +551,7 @@ public class InCallActivity extends FragmentActivity implements
|
|||
speaker.setBackgroundResource(R.drawable.speaker_on);
|
||||
LinphoneManager.getLc().enableSpeaker(isSpeakerEnabled);
|
||||
} else {
|
||||
Log.d("Toggle speaker off, routing back to earpiece");
|
||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
||||
speaker.setBackgroundResource(R.drawable.speaker_off);
|
||||
}
|
||||
|
|
|
@ -78,10 +78,6 @@ import org.linphone.mediastream.video.capture.hwconf.Hacks;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
|
@ -143,18 +139,8 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
private int mLastNetworkType=-1;
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
private WakeLock mIncallWakeLock;
|
||||
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
private BluetoothHeadset mBluetoothHeadset;
|
||||
private BluetoothProfile.ServiceListener mProfileListener;
|
||||
private BroadcastReceiver bluetoothReiceiver = new BluetoothManager();
|
||||
private BroadcastReceiver bluetoothActionReceiver = new BluetoothActionReceiver();
|
||||
public boolean isBluetoothScoConnected;
|
||||
public boolean isUsingBluetoothAudioRoute;
|
||||
private boolean mBluetoothStarted;
|
||||
|
||||
public String wizardLoginViewDomain = null;
|
||||
|
||||
private static List<LinphoneSimpleListener> simpleListeners = new ArrayList<LinphoneSimpleListener>();
|
||||
|
@ -208,13 +194,8 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver();
|
||||
|
||||
private void routeAudioToSpeakerHelper(boolean speakerOn) {
|
||||
isUsingBluetoothAudioRoute = false;
|
||||
if (mAudioManager != null && mBluetoothStarted) {
|
||||
//Compatibility.setAudioManagerInCallMode(mAudioManager);
|
||||
mAudioManager.stopBluetoothSco();
|
||||
mAudioManager.setBluetoothScoOn(false);
|
||||
mBluetoothStarted = false;
|
||||
}
|
||||
Log.w("Routing audio to " + (speakerOn ? "speaker" : "earpiece") + ", disabling bluetooth audio route");
|
||||
BluetoothManager.getInstance().disableBluetoothSCO();
|
||||
|
||||
if (!speakerOn) {
|
||||
mLc.enableSpeaker(false);
|
||||
|
@ -222,10 +203,15 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
mLc.enableSpeaker(true);
|
||||
}
|
||||
|
||||
audioStateChanged(speakerOn ? AudioState.SPEAKER : AudioState.EARPIECE);
|
||||
}
|
||||
|
||||
public void audioStateChanged(AudioState state) {
|
||||
for (LinphoneOnAudioChangedListener listener : getSimpleListeners(LinphoneOnAudioChangedListener.class)) {
|
||||
listener.onAudioStateChanged(speakerOn ? AudioState.SPEAKER : AudioState.EARPIECE);
|
||||
listener.onAudioStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
public void routeAudioToSpeaker() {
|
||||
routeAudioToSpeakerHelper(true);
|
||||
}
|
||||
|
@ -240,110 +226,10 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
return userAgent.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void routeAudioToReceiver() {
|
||||
routeAudioToSpeakerHelper(false);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
@SuppressWarnings("deprecation")
|
||||
public void startBluetooth() {
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (mBluetoothAdapter.isEnabled()) {
|
||||
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
||||
mProfileListener = new BluetoothProfile.ServiceListener() {
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
if (profile == BluetoothProfile.HEADSET) {
|
||||
Log.d("Bluetooth headset connected");
|
||||
mServiceContext.registerReceiver(bluetoothActionReceiver, new IntentFilter(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT));
|
||||
mBluetoothHeadset = (BluetoothHeadset) proxy;
|
||||
isBluetoothScoConnected = true;
|
||||
}
|
||||
}
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public void onServiceDisconnected(int profile) {
|
||||
if (profile == BluetoothProfile.HEADSET) {
|
||||
mServiceContext.unregisterReceiver(bluetoothActionReceiver);
|
||||
mBluetoothHeadset = null;
|
||||
isBluetoothScoConnected = false;
|
||||
Log.d("Bluetooth headset disconnected");
|
||||
routeAudioToReceiver();
|
||||
}
|
||||
}
|
||||
};
|
||||
mBluetoothAdapter.getProfileProxy(mServiceContext, mProfileListener, BluetoothProfile.HEADSET);
|
||||
} else {
|
||||
try {
|
||||
mServiceContext.unregisterReceiver(bluetoothReiceiver);
|
||||
} catch (Exception e) {}
|
||||
|
||||
Intent currentValue = mServiceContext.registerReceiver(bluetoothReiceiver, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED));
|
||||
int state = currentValue == null ? 0 : currentValue.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 0);
|
||||
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
|
||||
isBluetoothScoConnected = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isBluetoothScoConnected = false;
|
||||
scoDisconnected();
|
||||
routeAudioToReceiver();
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public boolean routeAudioToBluetooth() {
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (bluetoothAdapter.isEnabled() && mAudioManager.isBluetoothScoAvailableOffCall()) {
|
||||
mAudioManager.setBluetoothScoOn(true);
|
||||
mAudioManager.startBluetoothSco();
|
||||
mBluetoothStarted=true;
|
||||
|
||||
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
||||
isUsingBluetoothAudioRoute = false;
|
||||
if (mBluetoothHeadset != null) {
|
||||
List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
|
||||
for (final BluetoothDevice dev : devices) {
|
||||
isUsingBluetoothAudioRoute |= mBluetoothHeadset.getConnectionState(dev) == BluetoothHeadset.STATE_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isUsingBluetoothAudioRoute) {
|
||||
Log.d("No bluetooth device available");
|
||||
scoDisconnected();
|
||||
} else {
|
||||
//Why is this for:
|
||||
//mAudioManager.setMode(AudioManager.MODE_IN_CALL);
|
||||
for (LinphoneOnAudioChangedListener listener : getSimpleListeners(LinphoneOnAudioChangedListener.class)) {
|
||||
listener.onAudioStateChanged(AudioState.SPEAKER);
|
||||
}
|
||||
}
|
||||
}
|
||||
return isUsingBluetoothAudioRoute;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void scoConnected() {
|
||||
Log.i("Bluetooth sco connected!");
|
||||
isBluetoothScoConnected = true;
|
||||
}
|
||||
|
||||
public void scoDisconnected() {
|
||||
Log.w("Bluetooth sco disconnected!");
|
||||
isUsingBluetoothAudioRoute = false;
|
||||
isBluetoothScoConnected = false;
|
||||
if (mAudioManager != null) {
|
||||
//why is this for ?
|
||||
//mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
||||
mAudioManager.stopBluetoothSco();
|
||||
mAudioManager.setBluetoothScoOn(false);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static final LinphoneManager createAndStart(Context c, LinphoneServiceListener listener) {
|
||||
if (instance != null)
|
||||
throw new RuntimeException("Linphone Manager is already initialized");
|
||||
|
@ -654,7 +540,7 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
|
||||
updateNetworkReachability();
|
||||
|
||||
startBluetooth();
|
||||
BluetoothManager.getInstance().startBluetooth();
|
||||
resetCameraFromPreferences();
|
||||
}
|
||||
|
||||
|
@ -741,19 +627,7 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
if (LinphoneService.isReady()) // indeed, no need to crash
|
||||
ChatStorage.getInstance().close();
|
||||
|
||||
try {
|
||||
mServiceContext.unregisterReceiver(bluetoothReiceiver);
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mServiceContext.unregisterReceiver(bluetoothActionReceiver);
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30))
|
||||
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
|
||||
} catch (Exception e) {}
|
||||
|
||||
BluetoothManager.getInstance().destroy();
|
||||
try {
|
||||
mTimer.cancel();
|
||||
mLc.destroy();
|
||||
|
@ -994,6 +868,7 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
}
|
||||
|
||||
if (Hacks.needSoftvolume()) {
|
||||
Log.w("Using soft volume audio hack");
|
||||
adjustVolume(0); // Synchronize
|
||||
}
|
||||
}
|
||||
|
@ -1027,7 +902,21 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state == State.StreamsRunning) {
|
||||
if (BluetoothManager.getInstance().isBluetoothHeadsetAvailable()) {
|
||||
BluetoothManager.getInstance().routeAudioToBluetooth();
|
||||
// Hack for Android 4.2.2: we have to retry later, the first call will fail
|
||||
if (Build.VERSION.SDK_INT == 17) {
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
BluetoothManager.getInstance().routeAudioToBluetooth();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
if (mIncallWakeLock == null) {
|
||||
mIncallWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "incall");
|
||||
}
|
||||
|
@ -1148,8 +1037,11 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
|
||||
isRinging = false;
|
||||
// You may need to call galaxys audio hack after this method
|
||||
if (!BluetoothManager.getInstance().isBluetoothHeadsetAvailable()) {
|
||||
Log.d("Stopped ringing, routing back to earpiece");
|
||||
routeAudioToReceiver();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String extractADisplayName(Resources r, LinphoneAddress address) {
|
||||
|
@ -1360,6 +1252,7 @@ public class LinphoneManager implements LinphoneCoreListener {
|
|||
if (activity != null) {
|
||||
TelephonyManager tm = (TelephonyManager) activity.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
if (state == State.CallEnd && mLc.getCallsNb() == 0 && tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
|
||||
Log.d("All call terminated, routing back to earpiece");
|
||||
routeAudioToReceiver();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue