1st version that works
This commit is contained in:
@ -0,0 +1,525 @@
|
||||
package com.safemobile.bluetooth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.safemobile.bluetooth.BlueEvent;
|
||||
import com.safemobile.bluetooth.IBlueListener;
|
||||
import com.safemobile.lib.AppParams;
|
||||
import com.safemobile.lib.R;
|
||||
import com.safemobile.lib.SM;
|
||||
|
||||
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.bluetooth.BluetoothSocket;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public class BluetoothTether {
|
||||
|
||||
private Context mContext;
|
||||
private Activity activity;
|
||||
private AudioManager audioManager;
|
||||
|
||||
private BluetoothAdapter bluetoothAdapter;
|
||||
private BluetoothHeadset bluetoothHeadset = null;
|
||||
private BluetoothDevice bluetoothDevice= null;
|
||||
|
||||
/* For bluComm Microphone */
|
||||
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
|
||||
private List<IBlueListener> _listeners = new ArrayList<IBlueListener>();
|
||||
private Thread bluCommThread = null;
|
||||
private int bluetoothProfile;
|
||||
private BluetoothProfile bluetoothProxy;
|
||||
private BluetoothSocket bluetoothSocket = null;
|
||||
private InputStream inputStream =null;
|
||||
private Boolean socketIsConnected = false;
|
||||
|
||||
public BluetoothTether(Context context, Activity activity) {
|
||||
this.mContext = context;
|
||||
this.activity = activity;
|
||||
|
||||
audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
|
||||
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
bluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
|
||||
|
||||
IntentFilter filter1 = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
|
||||
IntentFilter filter2 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
|
||||
IntentFilter filter3 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
|
||||
|
||||
activity.registerReceiver(mReceiver, filter1);
|
||||
activity.registerReceiver(mReceiver, filter2);
|
||||
activity.registerReceiver(mReceiver, filter3);
|
||||
|
||||
filter3 = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
|
||||
activity.registerReceiver(mReceiver, filter3);
|
||||
}
|
||||
|
||||
private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
|
||||
@Override
|
||||
public void onServiceDisconnected(int profile) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
|
||||
SM.Debug("###BluetoothProfile###", "###Connected###");
|
||||
bluetoothProfile = profile;
|
||||
bluetoothProxy = proxy;
|
||||
|
||||
if(profile == BluetoothProfile.HEADSET)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
bluetoothHeadset = (BluetoothHeadset) proxy;
|
||||
List<BluetoothDevice> test;
|
||||
test = bluetoothHeadset.getConnectedDevices();
|
||||
SM.Debug("###BluetoothProfile###", "Headset Connected devices nr: " + test.size());
|
||||
// check if one of three headsets are connected
|
||||
|
||||
for(BluetoothDevice dev : test)
|
||||
bluetoothDevice = dev;
|
||||
/*
|
||||
if(dev.getAddress().contains(AppParams.MotorolaH730) ||
|
||||
dev.getAddress().contains(AppParams.SamsungWep460) || dev.getAddress().contains(AppParams.BluCom))
|
||||
bluetoothDevice = dev;
|
||||
*/
|
||||
|
||||
if(bluetoothDevice!=null)
|
||||
{
|
||||
if(AppParams.TETHERSOUND)
|
||||
{
|
||||
SM.Debug("###BluetoothProfile###", "Device : " + bluetoothDevice.getName() + " [" + bluetoothDevice.getAddress() + "]");
|
||||
new Handler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(mContext,
|
||||
String.format(mContext.getString(R.string.bthDeviceConnected), bluetoothDevice.getName()), Toast.LENGTH_SHORT).show();
|
||||
TetherSound(bluetoothDevice, true);
|
||||
|
||||
//*
|
||||
|
||||
SM.Debug("### blueComm ###", "BLUEcOMMFunction");
|
||||
new connectTask().execute();
|
||||
//blueCommFunction(bluetoothProfile, bluetoothProxy);
|
||||
|
||||
_fireBluetoothTethered(true);
|
||||
|
||||
final Timer t = new Timer();
|
||||
t.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
// start thread that will manage bluComm button press
|
||||
bluCommThread = new Thread(bluCommRunnable);
|
||||
bluCommThread.start();
|
||||
t.cancel();
|
||||
t.purge();
|
||||
}
|
||||
}, 2500);
|
||||
//*/
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Function that will intercept bluComm button press */
|
||||
private void blueCommFunction(int profile, BluetoothProfile proxy) {
|
||||
//Boolean result = true;
|
||||
SM.Debug("################");
|
||||
if(profile == BluetoothProfile.HEADSET)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// if device connected -> redundant check
|
||||
if(bluetoothDevice != null)
|
||||
{
|
||||
SM.Debug("###HEADSET###","Connected Device Address: " + bluetoothDevice.getAddress());
|
||||
|
||||
final Timer t = new Timer();
|
||||
t.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if(bluetoothDevice!=null)
|
||||
{
|
||||
// create socket and then connect to it
|
||||
bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID);
|
||||
bluetoothSocket.connect();
|
||||
inputStream = bluetoothSocket.getInputStream();
|
||||
SM.Debug("##BTSocketConnected##", "Connection socket ok");
|
||||
socketIsConnected = true;
|
||||
t.cancel();
|
||||
t.purge();
|
||||
}
|
||||
else
|
||||
{
|
||||
t.cancel();
|
||||
t.purge();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
//result = false;
|
||||
//SM.Exception("###BTSocketError###", e.toString());
|
||||
socketIsConnected = false;
|
||||
if(bluetoothSocket!=null)
|
||||
try {
|
||||
bluetoothSocket.close();
|
||||
bluetoothSocket = null;
|
||||
}
|
||||
catch (IOException e1) {
|
||||
SM.Exception("###BTSocketError2###", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
SM.Debug("BTSocketCreated", "bluetooth socket creation ended with result: " + socketIsConnected);
|
||||
/*
|
||||
if(result)
|
||||
_fireDataArrived(blueSOCKET,-1);
|
||||
else
|
||||
_fireDataArrived(noBlueSOCKET,-1);
|
||||
*/
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
SM.Exception("###BTSocketInterruptedException###", e.toString());
|
||||
}
|
||||
}
|
||||
}, 500, 3000);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Runnable to intercept bluComm button press */
|
||||
private Runnable bluCommRunnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
SM.Debug("####HERE####", "after Profile");
|
||||
|
||||
int read = 0;
|
||||
byte[] buffer = new byte[20];
|
||||
|
||||
while(true)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (socketIsConnected)
|
||||
{
|
||||
|
||||
//SM.Debug("####Socket####", "Socket is Connected");
|
||||
try
|
||||
{
|
||||
//Log.d("DECIVE STATUS", bhead.getConnectionState(mybluedev) + "");
|
||||
read = inputStream.read(buffer);
|
||||
/*
|
||||
String buf = "";
|
||||
for(int k=0;k<read;k++)
|
||||
buf += buffer[k] + " | "; */
|
||||
//SM.Debug("###SocketRead###", buf);
|
||||
if (read==6)
|
||||
{
|
||||
if (buffer[5]==80)
|
||||
{
|
||||
SM.Debug("##BTpttPress##", "PTTON");
|
||||
AppParams.BluCommState = 2;
|
||||
_fireDataArrived(AppParams.PTTON,-1);
|
||||
}
|
||||
if (buffer[5]==82)
|
||||
{
|
||||
SM.Debug("##BTpttPress##", "PTTOFF");
|
||||
AppParams.BluCommState = 1;
|
||||
_fireDataArrived(AppParams.PTTOFF,-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
//Log.d("bigutag", "Error on read");
|
||||
/*
|
||||
cntError++;
|
||||
if (cntError>10)
|
||||
{
|
||||
_fireDataArrived(-1,0);
|
||||
Disconect();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
Log.d("bigutag", "Error on");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** BroadcastReceiver that will manage BlueTooth Connection and Disconnection */
|
||||
public final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
if(device!=null)
|
||||
Log.d("BlueTooth State Changed", "DEVICE " + device.getName() + " [" + device.getAddress() + "]" + " is now : " + action );
|
||||
|
||||
// Tether sound only if selected in setup
|
||||
if(AppParams.TETHERSOUND)
|
||||
{
|
||||
if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
|
||||
if(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1) == BluetoothAdapter.STATE_OFF)
|
||||
untetherSound(bluetoothDevice);
|
||||
}
|
||||
else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
|
||||
Toast.makeText(mContext, mContext.getString(R.string.bthDeviceFound) + ":" + bluetoothDevice.getName(), Toast.LENGTH_SHORT).show();
|
||||
|
||||
}
|
||||
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
|
||||
//Toast.makeText(mContext, "Done searching", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
else
|
||||
if(device.getAddress()!= null) /* && (device.getAddress().contains(AppParams.MotorolaH730) ||
|
||||
device.getAddress().contains(AppParams.SamsungWep460) || device.getAddress().contains(AppParams.BluCom)))*/
|
||||
{
|
||||
// save device
|
||||
bluetoothDevice = device;
|
||||
|
||||
// if bluetooth device has disconnected
|
||||
if(action.contains("_DISCONNECTED"))
|
||||
{
|
||||
untetherSound(device);
|
||||
}
|
||||
// if bluetooth device had connected
|
||||
else
|
||||
{
|
||||
new Handler().post(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(mContext,
|
||||
String.format(mContext.getString(R.string.bthDeviceConnected), bluetoothDevice.getName()), Toast.LENGTH_SHORT).show();
|
||||
// set that bluComm Microphone is connected
|
||||
if(bluetoothDevice != null)
|
||||
{
|
||||
TetherSound(bluetoothDevice, true);
|
||||
|
||||
if(bluetoothDevice.getAddress().contains(AppParams.BluCom))
|
||||
{
|
||||
AppParams.BluCommState = 1;
|
||||
//TetherSound(bluetoothDevice, true);
|
||||
|
||||
_fireBluetoothTethered(true);
|
||||
|
||||
// create bluComm socket
|
||||
new connectTask().execute();
|
||||
|
||||
/*
|
||||
* if bluComm is not connected when RadioPad starts i will need
|
||||
* to create the Thread that reads on socket
|
||||
*/
|
||||
|
||||
if(bluCommThread == null)
|
||||
{
|
||||
final Timer t = new Timer();
|
||||
t.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
SM.Exception("bluComm", "creating blu comm thread");
|
||||
// start thread that will manage bluComm button press
|
||||
bluCommThread = new Thread(bluCommRunnable);
|
||||
bluCommThread.start();
|
||||
t.cancel();
|
||||
t.purge();
|
||||
}
|
||||
}, 2500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* UnTether all the sound when a device is disconnected or then the BlueTooth is turned off
|
||||
* @param device The BlueTooth device which needs to be unTethered
|
||||
*/
|
||||
private void untetherSound(final BluetoothDevice device) {
|
||||
new Handler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(device == null)
|
||||
return;
|
||||
|
||||
Toast.makeText(mContext,
|
||||
String.format(mContext.getString(R.string.bthDeviceDisconnected),
|
||||
(bluetoothDevice.getName() == null ? "?" : bluetoothDevice.getName())), Toast.LENGTH_SHORT).show();
|
||||
|
||||
_fireBluetoothTethered(false);
|
||||
// set that bluComm Microphone is disconnected
|
||||
if(bluetoothDevice!=null && bluetoothDevice.getAddress().contains(AppParams.BluCom))
|
||||
AppParams.BluCommState = 0;
|
||||
socketIsConnected = false;
|
||||
Disconect();
|
||||
|
||||
TetherSound(device, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Unregister BroadcastReceiver **/
|
||||
public void UnregisterReceiver()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(mReceiver!=null && activity!=null)
|
||||
{
|
||||
SM.Debug("#### unregister Receiver ### ", "unregister receiver");
|
||||
activity.unregisterReceiver(mReceiver);
|
||||
}
|
||||
|
||||
if(mProfileListener!=null)
|
||||
activity.unbindService((ServiceConnection) mProfileListener);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Tether sound */
|
||||
private void TetherSound(final BluetoothDevice device, Boolean enable)
|
||||
{
|
||||
if(enable && AppParams.TETHERSOUND)
|
||||
{
|
||||
final Timer t = new Timer();
|
||||
t.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
SM.Debug("### Start Tethering ###", "tethering " + device.getName());
|
||||
audioManager.setBluetoothScoOn(true);
|
||||
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
||||
audioManager.startBluetoothSco();
|
||||
t.cancel();
|
||||
t.purge();
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
else
|
||||
{
|
||||
audioManager.stopBluetoothSco();
|
||||
audioManager.setMode(AudioManager.MODE_NORMAL);
|
||||
socketIsConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Stop BluetoothTether and unregister BroadcastReceiver */
|
||||
public void Stop()
|
||||
{
|
||||
TetherSound(null, false);
|
||||
UnregisterReceiver();
|
||||
Disconect();
|
||||
}
|
||||
|
||||
public void Disconect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(bluetoothSocket!=null)
|
||||
bluetoothSocket.close();
|
||||
socketIsConnected = false;
|
||||
socketIsConnected = false;
|
||||
bluetoothDevice = null;
|
||||
bluetoothSocket = null;
|
||||
//bhead.stopVoiceRecognition(mybluedev);
|
||||
//_fireDataArrived(-1,0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
socketIsConnected = false;
|
||||
bluetoothDevice = null;
|
||||
bluetoothSocket = null;
|
||||
SM.Exception("##BTDisconnectError",e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public synchronized void addBlueListener( IBlueListener l ) {
|
||||
_listeners.add( l );
|
||||
}
|
||||
|
||||
public synchronized void removeBlueListener( IBlueListener l ) {
|
||||
_listeners.remove( l );
|
||||
}
|
||||
|
||||
private synchronized void _fireDataArrived(int PTTClicked, int Connected)
|
||||
{
|
||||
BlueEvent event = new BlueEvent( this,PTTClicked,Connected);
|
||||
Iterator<IBlueListener> listeners = _listeners.iterator();
|
||||
while( listeners.hasNext() ) {
|
||||
( (IBlueListener) listeners.next() ).dataRecv(event);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void _fireBluetoothTethered (boolean isTethered) {
|
||||
Iterator<IBlueListener> listeners = _listeners.iterator();
|
||||
while( listeners.hasNext() ) {
|
||||
( (IBlueListener) listeners.next() ).bluetoothTethered(isTethered);;
|
||||
}
|
||||
}
|
||||
|
||||
public class connectTask extends AsyncTask<String, Void, Void>
|
||||
{
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(String... params) {
|
||||
SM.Debug("### blueComm ###", "recreate bluComm socket");
|
||||
blueCommFunction(bluetoothProfile, bluetoothProxy);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user