How to disconnect A2DP profile Bluetooth Connection? - android

I am working on A2DP connection with headset and other Bluetooth device but when I connect Bluetooth device but when I Disconnect but It didn't disconnect with it. My code is:
try {
Method connect = mA2dpService.getClass().getDeclaredMethod("disconnect", BluetoothDevice.class);
connect.invoke(device);
} catch (Exception e) {
e.printStackTrace();
}

Finally I found
Call getProfileProxy to get a2dp proxy
adapter.getProfileProxy(c, listner, BluetoothProfile.A2DP);
listenr should implement onA2DPProxyReceived.
Then Callback onA2DPProxyReceived will be called.
public void onA2DPProxyReceived (BluetoothA2dp proxy) {
Method disconnect = null;
try {
disconnect = BluetoothA2dp.class.getDeclaredMethod("disconnect", BluetoothDevice.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
BluetoothDevice device = findBondedDeviceByName(mBtAdapter, myDevice);
disconnect.setAccessible(true);
try {
int result = disconnect.invoke(proxy,device);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
Refer to sites below
getDeclaredMethod : https://www.tutorialspoint.com/java/lang/class_getdeclaredmethod.htm
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothA2dp.java
Invoking : https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html

Related

How to make a Bluetooth SPP connection process more reliable?

We are about to release the new version of our software, and for the version afterward, our goal is to make the connection process for our Bluetooth SPP connections more reliable. We use the RN42 module in our products, and currently, at times it may take more than one try to connect to our boards.
Here is my current code:
class ConnectThread extends Thread {
BluetoothDevice mDevice;
public ConnectThread(BluetoothDevice device) throws SecurityException, NoSuchMethodException {
mDevice = device;
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
btSocket = mDevice.createInsecureRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
Log.e("Error", "Could not create socket!");
}
}
public void cancel() {
interrupt();
try {
Log.i("Treadmill", "in connect thread cancellation");
btSocket.close();
} catch (IOException localIOException) {
Log.e("Treadmill", "exception + " + localIOException.getMessage());
}
}
public void run() {
btAdapter.cancelDiscovery();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("whatever", "InterruptedException: " + e.getMessage(), e);
}
try {
btSocket.connect();
Log.i("Treadmill", "After Connect");
} catch (IOException ioe) {
Log.i("Treadmill", "Trying Fallback");
try {
Method m;
try {
btSocket.close();
m = mDevice.getClass().getMethod("createInsecureRfcommSocket", new Class[]{int.class});
btSocket = (BluetoothSocket) m.invoke(mDevice, 1);
Thread.sleep(500);
btSocket.connect();
} catch (IllegalArgumentException e) {
Log.e("whatever", "IllegalArgumentException: " + e.getMessage(), e);
} catch (IllegalAccessException e) {
Log.e("whatever", "IllegalAccessException: " + e.getMessage(), e);
} catch (InvocationTargetException e) {
Log.e("whatever", "InvocationTargetException: " + e.getMessage(), e);
} catch (NoSuchMethodException e) {
Log.e("whatever", "NoSuchMethodException: " + e.getMessage(), e);
} catch (InterruptedException e) {
Log.e("whatever", "InterruptedException: " + e.getMessage(), e);
}
} catch (IOException ioe2) {
Log.e("Treadmill", "Failed to connect to Bluetooth device: " + ioe2.getMessage());
eventHandler.obtainMessage(MESSAGE_ERRORCONNECT, 0, 0, getResources().getString(R.string.connerr) + ": " + ioe2.getMessage()).sendToTarget();
try {
btSocket.close();
} catch (IOException localIOException2) {
Log.e("Error", "IO Exception!");
}
return;
}
}
eventHandler.obtainMessage(MESSAGE_CONNECT, 0, 0, "").sendToTarget();
synchronized (this) {
connectThread = null;
}
manageConnectedSocket(btSocket);
}
}
Even with the fallback to reflection the connection intermittently fails on some devices. I get the following error:
find_rfc_slot_by_id unable to find RFCOMM slot id: XX (XX being a number that increments on each attempted connection).
followed by this:
Failed to connect to Bluetooth device: read failed, socket might closed or timeout, read ret: -1
Does anyone know how to avoid these errors.
Interestingly, for comparison. I am testing on two tablets. One tablet, the Samsung Galaxy Tab 4 seems to work extremely well, while another, the Astro Tab A10, seems to be a bit more intermittent unless you wait several seconds between connecting and disconnecting.
For more reliable connection means even app was closed, Bluetooth should be keep connected in the background.
Below is the working solution I followed in my app to keep Bluetooth connection background.
First create a class which extends service, because service runs in the background even app closed until you call stopService or stopSelf methods
while starting BluetoothService class pass Bluetooth Mac address to connect and run in the background.
Sample code:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null){
String deviceg = intent.getStringExtra("bluetooth_device");
if (deviceg != null){
connectToDevice(deviceg);
}
}
return START_STICKY;
}
Below is the connect to device method which identifies mac Address into Bluetooth Device.
public synchronized void connectToDevice(String macAddress){
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
if (mConnectedThread != null){
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectThread = new ConnectBtThread(device);
toast("connecting");
mConnectThread.start();
}
This is my Thread class inside BluetoothService which runs in a separate thread
Code:
private class ConnectBtThread extends Thread{
private final BluetoothSocket mSocket;
private final BluetoothDevice mDevice;
public ConnectBtThread(BluetoothDevice device){
mDevice = device;
BluetoothSocket socket = null;
try {
socket = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(B_UUID));
} catch (IOException e) {
e.printStackTrace();
}
mSocket = socket;
}
#Override
public void run() {
if (mBluetoothAdapter.isDiscovering()){
mBluetoothAdapter.cancelDiscovery();
}
try {
mSocket.connect();
Log.d("service","Bluetooth one running (connected)");
} catch (IOException e) {
try {
mSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
connected(mSocket);
}
public void cancel(){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
It works perfectly fine for our app.
If you want to access service methods bind this service to your activity

Why cant Android open connection with RN-41 Roving network device?

I am just trying to open socket with RN-41 microchip, as far as I know the chip listens for incoming connections all the time, is discoverable, etc.. Why do socket gets always closed directly?
private class Connect extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public Connect(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString("EB46DDA9-0D00-4C34-9365-D6AA6C111D1C"));
Log.v("SOCKET SUCCESS", "HAST SOCKET");
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
try {
mmSocket.connect();
Log.v("SOCKET SUCCESS", "VERBUNDEN");
} catch (IOException connectException) {
Log.v("SOCKET SUCCESS", "KEINE VERBINDUNG");
try {
mmSocket.close();
Log.v("SOCKET SUCCESS", "SOCKET CLOSED");
} catch (IOException closeException) {
Log.v("SOCKET SUCCESS", "SOCKET CLOSE FAIL");
}
return;
}
}
I've been googling all day long and got things work. Unfortunately I still dont know why and how it works, but it works perfectly. I changed my Connect class constructor code like this:
public Connect(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
//try {
// MY_UUID is the app's UUID string, also used by the server code
//ParcelUuid[] ids = device.getUuids();
//UUID deviceID = ids[0].getUuid();
//tmp = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));//deviceID);//UUID.fromString("EB46DDA9-0D00-4C34-9365-D6AA6C111D1C"));
Method m = null;
try {
m = mmDevice.getClass().getMethod("createInsecureRfcommSocket", new Class[] { int.class });
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
tmp = (BluetoothSocket)m.invoke(mmDevice, Integer.valueOf(1));
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.v("SOCKET SUCCESS", "HAST SOCKET");
//} catch (IOException e) { }
mmSocket = tmp;
}
Source:
Android Bluetooth SPP with Galaxy S3
P.s. If somebody would have a bit time to explain code above, I would appreciate it a lot. Thank you.

Use java code to enable portable wi-fi hotspot

currently I am building a very small native app for my android phone. I want to active the portable wi-fi hotspot when I click one button in the app. But I didn't know how to invoke Android API to active portable wi-fi hotspot. I know how to do it through the UI. Can anyone show me?
// code to enable portable wifi hotspot
public void EnableWifiHotspot(){
try{
WifiManager wifi_manager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wifi_configuration = null;
Method wifiHotspotEnabledMethod=wifi_manager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
wifiHotspotEnabledMethod.invoke(wifi_manager, wifi_configuration, true);
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
e.printStackTrace();
}
}
//code for disabling portable wifi hotspot
public void DisableWifiHotspot(){
try{
WifiManager wifi_manager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wifi_configuration = null;
Method wifiHotspotEnabledMethod=wifi_manager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
wifiHotspotEnabledMethod.invoke(wifi_manager, wifi_configuration, false);
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
e.printStackTrace();
}
}

Android pairing does not work - "connection reset by peer"

As the title explains I'm having a hard time sending some data via Bluetooth to my PC. I'm trying to establish a connection with my android phone as client and my PC as server. When I'm trying to actually establish a connection via BluetoothSocket.connect() my phone prompts for a pin. After entering it my PC also prompts for the same pin but before I can enter it, the connect() - method throws an IOException. I assume that the connect()-Method times out before I can enter the correct pin on my PC, but how can I get it to wait long enough for me to enter the PIN?
EDIT: After Re-Pairing the PC with my Phone it worked, because the pairing dialog doesn't appear in my app anymore. If I unpair the PC and start my app, the pairing dialog pops up but disappears after several seconds and the socket throws an exception ("connection reset by peer"). Apparently the connection is reset before the pairing is done, but why?
Here is my code:
private void connectToDevice(BluetoothDevice device)
{
mBluetoothAdapter.cancelDiscovery();
BluetoothSocket socket = null;
try
{
socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101- 0000- 1000-8000-00805F9B34FB"));
}
catch (IOException e)
{
Log.e("HeliRemote", "Couldn't get socket.");
return;
}
try
{
socket.connect();
}
catch (IOException e)
{
try
{
socket.close();
}
catch (IOException e1)
{
Log.e("HeliRemote", "Couldn't close connection");
}
// That's the message I get in LogCat
Log.e("HeliRemote", "Couldn't connect to Socket.");
return;
}
Log.i("HeliRemote", "connected.");
}
I would be glad if somebody could give me any good words of advice regarding the problem.
Method m = mBluetoothDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
mBluetoothSocket = (BluetoothSocket) m.invoke(mBluetoothDevice, 1);
// mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(applicationUUID);
mBluetoothAdapter.cancelDiscovery();
mBluetoothSocket.connect();
}
catch (IOException eConnectException)
{
Log.d(TAG, "CouldNotConnectToSocket", eConnectException);
closeSocket(mBluetoothSocket);
return;
} catch (SecurityException e) {
Log.d(TAG, "CouldNotConnectToSocket", e);
closeSocket(mBluetoothSocket);
} catch (NoSuchMethodException e) {
Log.d(TAG, "CouldNotConnectToSocket", e);
closeSocket(mBluetoothSocket);
} catch (IllegalArgumentException e) {
Log.d(TAG, "CouldNotConnectToSocket", e);
closeSocket(mBluetoothSocket);
} catch (IllegalAccessException e) {
Log.d(TAG, "CouldNotConnectToSocket", e);
closeSocket(mBluetoothSocket);
} catch (InvocationTargetException e) {
Log.d(TAG, "CouldNotConnectToSocket", e);
closeSocket(mBluetoothSocket);
}
}
try this one...

Android Bluetooth: Connect()/Disconnect()

I currently am designing an app which needs to connect to a device, write/read data, and close the connection reliably. Currently I have the write/read solid. My disconnect and then reconnect is terribly unreliable, and often actually crash the phone.. and sometimes Eclipse. I've been looking through numerous articles trying to figure it out and.. no luck..
****CONNECT FUNCTION**
public boolean connect()
{
ConfigData.getInstance();
BluetoothSocket tmp = null;
BluetoothDevice device = ConfigData.m_SharedBluetoothDevice;
Method m;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);//(BluetoothSocket)
m.invoke(device, 1);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
ConfigData.m_SharedBluetoothSocket = tmp;
try {
ConfigData.m_SharedBluetoothSocket.connect();
ConfigData.bIsBTConnected = true;
} catch (IOException e) {
try {
closeSocket();
m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(device, 1);
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} catch (IllegalArgumentException e1) {
e.printStackTrace();
} catch (IllegalAccessException e1) {
e.printStackTrace();
} catch (InvocationTargetException e1) {
e.printStackTrace();
}
ConfigData.m_SharedBluetoothSocket = tmp;
try {
ConfigData.m_SharedBluetoothSocket.connect();
ConfigData.bIsBTConnected = true;
} catch (IOException e1) {
ConfigData.m_BluetoothException += e1.toString();
ConfigData.bIsBTConnected = false;
return false;
}
e.printStackTrace();
return true;
}
return true;
}
****Disconnect Function**
public void destroySocket()
{
try {
if(m_InStream != null)
{
m_InStream.close();
m_InStream = null;
}
if(m_OutStream != null)
{
m_OutStream.close();
m_OutStream = null;
}
if(ConfigData.m_SharedBluetoothSocket != null)
{
ConfigData.m_SharedBluetoothSocket.close();
ConfigData.m_SharedBluetoothSocket = null;
}
if(m_InStream == null && m_OutStream == null && ConfigData.m_SharedBluetoothSocket == null)
{
ConfigData.bIsBTConnected = false;
}
} catch (IOException e1) {
m_InStream = null;
m_OutStream = null;
ConfigData.m_SharedBluetoothSocket = null;
e1.printStackTrace();
}
}
So the disconnect is successful and returns everything null. The problem is that when I reconnect it blocks at the 2nd connect attempt and will either just sit there or completely crash the phone, causing several reboots.
Does anyone have any advice here? Its been extremely frustrating. Any help would be much appreciated!!
Thanks and Gig 'Em!
TxAg
What phone are you using? What OS? See this answer:
Disconnect a bluetooth socket in Android
The close is actually not working properly on some HTC 2.1update1 phones

Categories

Resources