Android returning "null" for Bluetooth RSSI - java

I am developing a android application using Eclipse to return the RSSI values of a Bluetooth device. I have modified the Android Bluetooth Chat example to fit my needs, but I am having problems returning the RSSI value. After hitting the scan button to discover nearby devices it returns the device name, device address, and is also suppose to return the RSSI value but instead it says null for the RSSI.
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress() + getRssi());
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String 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);
// Get the Bluetooth RSSI
short Rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
// If it's already paired, skip it, because it's been listed already
// Added getRssi()
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress() + getRssi());
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setProgressBarIndeterminateVisibility(false);
setTitle(R.string.select_device);
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = getResources().getText(R.string.none_found).toString();
mNewDevicesArrayAdapter.add(noDevices);
}
}
}
};

I haven't tried it myself, but maybe this SO answer will help:
https://stackoverflow.com/a/2361630/831918
Supposedly it is possible using the NDK. Good luck!

This is how I am getting RSSI
String deviceRSSI =
(intent.getExtras()).get(BluetoothDevice.EXTRA_RSSI).toString();
private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceRSSI = (intent.getExtras()).get(BluetoothDevice.EXTRA_RSSI).toString();
btArrayAdapter.add(device.getName() + "\n" + device.getAddress() + "\n" + deviceRSSI);
btArrayAdapter.notifyDataSetChanged();
}
if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
} else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
}
}
};

Related

How can i refresh the list of bluetooth devices in java

I am trying to make an android application about localization, i am trying however to make a list of Bluetooth devises found by my smartphone and refresh that lists information every 10 seconds. I want to do that because I am also recording the signal strength (RSSI) and want to record when a beacon is getting out of range when moved or the signal is getting weaker. So refreshing the list will help with that. I have provided some of my code below.
#Override protected void onResume() {
super.onResume();
registerReceiver(devicesFoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
registerReceiver(devicesFoundReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
registerReceiver(devicesFoundReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
}
private final BroadcastReceiver devicesFoundReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int rssid = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
listAdapter.add(device.getName() + "\n" + device.getAddress() + "\n" + " RSSI: " + rssid + "dBm");
listAdapter.notifyDataSetChanged();
}else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
scanningButton.setText("Scan Bluetooth Devices");
}else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
scanningButton.setText("Scanning in progress ...");
}
}
};
use a listview then call notifyDataSetChanged() on your Adapter object

BluetoothDevice getName() return null.

That I use android app to get the hardware's ble name ,but i can get the name that using iOS .I can't find any error of this. so what i should do for this issue.
here, i copy my code for looking .
First:
BluetoothManager bluetoothManager = (BluetoothManager)
getActivity().getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
bluetoothAdapter.startDiscovery();
Next:
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
getActivity().registerReceiver(mReceiver,filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
getActivity().registerReceiver(mReceiver,filter);
last:
public BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e("走进receiver","bluetooth");
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
String sname = device.getName();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
}
}
};

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();
}
}
}
}
};

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.

To discover and pair Bluetooth Devices

How to discover and pair Android Bluetooth devices using Java? Any codes for me to refer to?
the following code will discover the list of paired and the unpaired devices after that u have to implement the Client and server, which takes care of pairing the devices and sending data to the devices, for tat u can make use of the BluetoothChatSample which will give an idea to u.
private Set<BluetoothDevice> pairedDevices;
public static ArrayList<Object> BondedDeviceList;
public static ArrayList<Object> NewDeviceList;
public void makeDiscoverable()
{
discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
activity.startActivity(discoverableIntent);
}
//It will Add the paired device in the BondedDeviceList
public void queryPairedDevice(){
pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if(pairedDevices==null)
{
//No Bonded Devices
}else
{
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
BondedDeviceList.add(device);
}
BondedDeviceList.add("End");
}
}
}
//Broadcast Receiver will find the Available devices and the discovery finished
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action.trim())) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
NewDeviceList.add(device);
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
if (NewDeviceList.isEmpty() == true) {
String noDevices = "No Devices";
NewDeviceList.add(noDevices);
}
System.out.println("Discovery Finished!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
NewDeviceList.add("End");
}
}
};
//This is query for the bluetooth devices
public void queryDevices(){
actionFoundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
activity.registerReceiver(mReceiver, actionFoundFilter);
// Don't forget to unregister during onDestroy
discoveryFinishedFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
activity.registerReceiver(mReceiver, discoveryFinishedFilter);
// Don't forget to unregister during onDestroy
queryPairedDevice();
mBluetoothAdapter.startDiscovery();
}
//Unregister the receivers
public void unregisterReceiver() {
// Make sure we're not doing discovery anymore
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
}
// Unregister broadcast listeners
activity.unregisterReceiver(mReceiver);
}
Cheers.

Categories

Resources