Android: Use progress dialog till a new activity loads up - java

I am trying to connect to a bluetooth device(BLE HC05 module) using my app, to do some IOT functionality
Below snippet shows the code which is used to go to a new activity when user clicks on a particular device to connect to.
This is in BluetoothActivity.java
lvPairedDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final Intent intent = new Intent(BluetoothActivity.this, TemperatureActivity.class);
intent.putExtra("Bluetooth Device Address", mBTPairedDevices.get(position).getAddress());
startActivity(intent);
}
});
As it is mentioned, I am sending the Bluetooth device's MAC Address. Using it an attempt to connect to the device is made.
This is in TemperatureActivity.java
Intent intent = getIntent();
Bundle extras = intent.getExtras();
deviceAddress = extras.getString("Bluetooth Device Address");
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
device = bluetoothAdapter.getRemoteDevice(deviceAddress);
try {
btSocket = device.createInsecureRfcommSocketToServiceRecord(myUUID);
bluetoothAdapter.cancelDiscovery();
btSocket.connect();
if(btSocket.isConnected())
Toast.makeText(TemperatureActivity.this,"Connected to " + device.getName() + " successfully", Toast.LENGTH_SHORT).show();
else
Toast.makeText(TemperatureActivity.this,"Couldn\'t connect to " + device.getName() + " properly", Toast.LENGTH_SHORT).show();
outStream = btSocket.getOutputStream();
connectedThread = new ConnectedThread(btSocket);
connectedThread.start();
} catch (IOException e) {
Log.d(TAG, "onResume: Bluetooth device could not be connected using RFCOMM");
Toast.makeText(TemperatureActivity.this, "Connection to device " + device.getName() + " using RFCOMM has failed", Toast.LENGTH_SHORT).show();
finish();
}
According to the above code, if the device is offline or has declined to connect, an exception will arise.
With the current situation, is there any possibility of using Progress dialog in the BluetoothActivity.java and stop it in both cases(bluetooth connection is established successfully or not) in TemperatureActivity.java
I will go to TemperatureActivity with the device's MAC address, if it is successful in connecting to the device it should stay in that page(TemperatureActivity) otherwise, return to the original page (BluetoothActivity) saying "Couldn't connect to the device"
I searched a lot, could not find an answer. Thanks in advance.

Related

How do I connect programatically the bluetooth(RN4020) with Android app?

I am developing an Android app that is going to communicate with target miroprocessor(ARM processor) board through a bluetooth device(RN4020).
Since the pair PIN is random for each bluetooth module, I just want the app source code to connect the app with that RN4020 module (without pairing manually since I don't know the pair PIN).
Also, I just want to know the UUID for RN4020 module, I have tried to find the UUID through some Android app it shows more than ten UUIDs. I am confused to choose the appropriate UUID.
Here is my code:
private static String address = "00:1E:C0:19:DB:A6";
private static final UUID MY_UUID = UUID.fromString("00002A00-0000-1000-8000-00805F9B34FB");
connect.setOnClickListener(new View.OnClickListener()
{
public void onClick(View V)
{
Toast.makeText(getApplicationContext(), "Connecting to ... RN4020_D694", Toast.LENGTH_SHORT).show();
if (mBluetoothAdapter.isEnabled())
Connect();
}
});
public void Connect() {
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Toast.makeText(getApplicationContext(), "Connecting to ... " + device, Toast.LENGTH_SHORT).show();
mBluetoothAdapter.cancelDiscovery();
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect();
Toast.makeText(getApplicationContext(), "Connection made", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
changingText.setText("Unable to end the connection");
}
Log.d(TAG, "Socket creation failed");
}
beginListenForData();
}
When I tried to press the connect button, my app got stuck and it's not responding.
To avoid pairing you need to go for an insecure UUID rfcomm.
Replace:
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
with
btSocket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);

Android BluetoothDevice notify remote unbond change state

Problem: I am being notified when a bluetooth device is pairing, or becomes paired. However, I do not know how to get notified when a device is being unpaired. How could I get my app to recognize when it has become unpaired with my device?
Example: Let's say that I pair my surface tablet and my android phone through code. My broadcast receiver will register the ACTION_BOND_STATE_CHANGED intent and allow me to process it however I want. Now, if I want to unpair my surface tablet, I do not get notified on my phone that the device has become unpaired. If I check, device.getBondState() for the device after it has been unpaired, it equals BOND_BONDED (which it clearly isnt) I can get it to recognize it is unpaired again after I try to connect to the unpaired device, then the app crashes and then when I turn the app on again, only then does it recognize it as unpaired.
Scenario: I have a BroadcastReceiver registered to listen for intents caused by a BluetoothDevice
getActivity().registerReceiver(broadcastReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
getActivity().registerReceiver(broadcastReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
getActivity().registerReceiver(broadcastReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED));
getActivity().registerReceiver(broadcastReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED));
I process these Actions with this BroadcastReciever:
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
System.out.println("ACTION: "+ action);
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
list();
// Get the BluetoothDevice object from the intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
System.out.println("FOUND: " + device.getName() + " STATE: " + device.getBondState());
mapInput(device);
// Add the name and the mac address of the object to the array adapter
BTSimpleAdapter.notifyDataSetChanged();
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
System.out.println("UPDATE Name " + device.getName() + " Value " + device.getAddress() + " Bond state " + device.getBondState());
for (Map<String, String> entry : data) {
if (entry.get("Name").equals(device.getName()) && entry.get("Value").equals(device.getAddress())) {
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
entry.put("Paired", "Unpaired");
} else if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
entry.put("Paired", "Pairing");
} else {
entry.put("Paired", "Paired");
}
BTSimpleAdapter.notifyDataSetChanged();
}
}
}
}
};

Android Bluetooth- MAC address

I am trying to get the MAC address of a bluetooth device when I click on a device in the listview. I want to pass in the MAC address in
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Is there a way I can extract the MAC address when I choose a device on the listview. Thanks
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
if (listAdapter.getItem(i).contains("Paired")) {
BluetoothDevice selectedDevice = devices.get(i);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
mBluetoothAdapter.cancelDiscovery();
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
}
}
}
}
}
In Android, after starting a bluetooth device scan, we get the address of remote bluetooth devices, as a broadcast message on a BroadcastReceiver we have registered. Below code sample does that.
//receive remote device details including address
BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Sring action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceAddress = device.getAddress());
}
}
}
//register receiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
//start bluetooth scan
BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
mBtAdapter.startDiscovery();
To answer your specific case, I assume you are using the BluetoothChat(1) Android sample code to create a ListView from paired devices after the scan. If that is the case, you can get the device address as in the Android code sample(2)
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String info = ((TextView) view).getText().toString();
String address = info.substring(info.length() - 17);
}
BluetoothDevice
has method to get the mac address getAddress REF

Bluetooth LE Gatt connection Android 4.4 to read real-time RSSI

I am trying to write a small android app (4.4) which searches for several Bluetooth LE devices. Once it has found each device it needs to connect to it and then continually read the RSSI of each device as quickly as it can. I have been trying to get this to work with 6 devices. My current code is as follows:
public class BluetoothGatt extends Activity {
private BluetoothAdapter mBluetoothAdapter;
private static final int REQUEST_ENABLE_BT = 1;
int count = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
System.out.println("Adapter: " + mBluetoothAdapter);
BTScanStart();
}
// Start the Bluetooth Scan
private void BTScanStart() {
if (mBluetoothAdapter == null) {
System.out.println("Bluetooth NOT supported. Aborting.");
return;
} else {
if (mBluetoothAdapter.isEnabled()) {
System.out.println("Bluetooth is enabled...");
// Starting the device discovery
mBluetoothAdapter.startLeScan(mLeScanCallback);
}
}
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
count++;
System.out.println("Found " + count + ":" + device + " " + rssi + "db");
device.connectGatt(null, false, mGattCallback);
if (count > 5) mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
};
// Gatt Callback
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
System.out.println(gatt.getDevice() + ": Connected.. ");
gatt.readRemoteRssi();
}
if (newState == BluetoothProfile.STATE_DISCONNECTED) {
System.out.println(gatt.getDevice() + ": Disconnected.. ");
}
}
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
System.out.println(gatt.getDevice() + " RSSI:" + rssi + "db ");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
gatt.readRemoteRssi();
}
};
}
I am having the following problems:
1) It connects to the devices successfully, but they all disconnect after around 5 seconds with a 'btm_sec_disconnected - Clearing Pending flag' error. Is there a was to keep them connected?
2) The code works fine for a single device, however when using more than one device only one device prints RSSI updates regularly, others update randomly and some don't update at all.
3) I am not sure what context I should supply when calling device.connectGatt .
Thank you in advance for your thoughts!
For the RSSI issue I will second Sam's answer (https://stackoverflow.com/a/20676785/4248895). It seems that for your use case continuously scanning should be sufficient. You don't want to add the overhead of connection if you can avoid it.
I will answer your other question in that if you do need to connect to these devices for some reason, your stability issues may be related to the fact that you're connecting and scanning simultaneously. Generally speaking, you should not perform any two gatt operations (scanning, connecting, reading, writing, etc.) at the same time.
How about just use startLeScan and get rssi?
If your android device filter the ble devices (like nexus 7), you could stopLeScan/ startLeScan repeatedly.
If not(like samsung s4 with android 4.3), just let it scan, onLeScan(...) will give every devices' rssi continuously.

Why am I losing bluetooth client/server connection?

I am trying to connect from a desktop application (written in Java) to a Android application through Bluetooth.
For the desktop application I am using BlueCove API.
When I start the server (desktop application) and I start the Android application, the connection works fine. (i.e. The client sends a "Hello World" and the server prints it in the console). But when I leave the application (by pressing Back or Home button) and return back to it, the socket connection seems to be lost.
How can you check if a Bluetooth socket is already connected?
I would like to check the connection of the socket to not having connecting again.
What should I write (if it is the case) in the onPause, onResume methods?
I suppose that in the onDestroy method I should close the socket.
Here is the source code of the client server:
Server
Client
I also tried using IntentFilter to check for the state of the connection, but it didn't work.
#Override
public void onCreate(Bundle savedInstanceState) {
// .....
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);
this.registerReceiver(mReceiver, filter1);
this.registerReceiver(mReceiver, filter2);
this.registerReceiver(mReceiver, filter3);
}
//The BroadcastReceiver that listens for bluetooth broadcasts
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//Device found
Toast.makeText(BluetoothClient.this, "Device not found", 2).show();
}
else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
//Device is now connected
Toast.makeText(BluetoothClient.this, "Device connected", 2).show();
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//Done searching
Toast.makeText(BluetoothClient.this, "Done searching", 2).show();
}
else if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
//Device is about to disconnect
Toast.makeText(BluetoothClient.this, "Device about to connect", 2).show();
}
else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
//Device has disconnected
Toast.makeText(BluetoothClient.this, "Device disconnected", 2).show();
}
}
};
Server
Client
I have modified the 2 source code files.
Now it should work fine. There are some small bugs regarding if the BT is not opened before entering the mobile app (it get stuck too much in a while) and for those who want to use this client/server you should take a look at onPause(), onResume(), onDestroy() functions.
The problem was that I did not use the socket correctly.
I hope that it will be useful for those who want to implement such an application with BT.

Categories

Resources