In android application we can get WiFi connection link rate using wifiInfo.getLinkSpeed() method.
But is there any way to get Bluetooth connection Link Rate? Any API or method available for this?
I worked on Bluetooth applications and I had the same need as yours but I didn't find a solution to get the Bluetooth connection speed in mbps.
So, this solution may not give you an exact value for Bluetooth link rate as you requested, but it actually gives you a reference to the Bluetooth link quality (good, medium, bad) using the Received Signal Strength Indicator (RSSI).
To read the value of your Bluetooth RSSI, you should add a BroadcastReceiver to your class :
private final BroadcastReceiver receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
if(BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {
//Get the RSSI value here
int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
}
}
};
Your receiver has to be registered using :
registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
Now, you need to know that the data transfer speed increases as the RSSI value increases , so, all you have to do is to define a range for each link quality.
PS: Refer to this link to learn more about RSSI values for Bluetooth Bluetooth RSSI values are always in dBm in all Android devices?
Hope this helps :)
The short answer is no such interface.
The long answer is, the speed in Bluetooth is vary due to hardware and software difference for different device, e.g. BR/EDR/BLE, and Bluetooth only defined the maximum speed data for BR/EDR/BLE. for most cases, the Bluetooth link does not transport user data(except you are listening music or calling), but just keep the link, so it is no meaning for Bluetooth to evaluate the link speed(at least for end user).
Related
Google introduced a set of limitations in Android 8 or 9 regarding Wi-Fi scanning frequency. Apps are restricted in how frequently they're able to scan for Wi-Fi connections, including P2P Wi-Fi peers. What is the situation with Wi-Fi Aware? Does it have the same limitation? Is it easier to bypass it?
This answer is as per the latest comments by OP.
One way to keep track of the RSSI of the network is to register for the intent RSSI_CHANGED_ACTION using a BroadcastReceiver and then extract the raw RSSI values from the Intent's extra values which are stored with the key Wi-FiManager.EXTRA_NEW_RSSI and obtain the threshold levels(usually the workable values) using calculateSignalLevel(). Some approximate code:
} else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
// Default to -200 as its below WifiManager.MIN_RSSI.
int rawRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
int rssiLevel = mWifiManager.calculateSignalLevel(rawRssi);
}
Also, to answer the previous question as to whether Wi-Fi aware is restricted by the same scan restrictions, the answer is 'no', not because it has a waiver vis-a-vis Wi-Fi-Direct but because it operates differently from a Wi-Fi-Direct connection. For a Wi-Fi Direct connection, one needs to make a request() to the WifiManager for initiating a scan and it is these scans that are throttled, with the duration of throttling varying based on whether the app is in foreground/background. This throttling can of course be overridden from the Developer Settings page.
Wi-Fi-Aware works with a different paradigm. If this is regarding the usage of ranging, then one can leverage Wi-Fi-Aware technology between two devices as follows:
Check whether ranging is supported using Wi-Fi-RTTI apis using context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
Check whether Wi-Fi RTT is available by registering for the intent WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED and on its receipt, check for whether Wi-Fi RTT is available.
Create a ranging request
Start ranging
Extract rssi from a successful ranging result.
One thing to note is that the requests for ranging are limited to 20 from each UID as per this code from the framework.
static final int MAX_QUEUED_PER_UID = 20;
Note that if you're running as a regular application, your app would have its own UID.
I'm new to android development and I'm writing a APP as proof of concept for a research project using the BLE Google API. I have two android phones, one of which is advertising some beacon X that carries a scan response Y, while the second phone is scanning for advertisements. I would like to access the RSSI values corresponding to the ScanRequest and ScanReply packets that follow the advertisement.
During device to device communication, when the overwritten onScanCallback method is called on the second phone, I can only obtain a single RSSI value by calling result.getRssi() on the passed ScanResult. Furthermore, as expected, the corresponding ScanRecord provides two ServiceUuids by calling the record.getServiceUuids, where the first UUID corresponds to the advertisement itself, and the second one to the programmed scan reply.
Until now I haven't found any public methods to recover the RSSI of the ScanReply, is there some other way of accessing this second RSSI? And the same applies to the RSSI of the ScanRequest that is automatically sent by the listening device, is there a way of recovering it?
Thanks a lot in advance,
Ivan Morales
The RSSI in the scan callback already corresponds to the RSSI in the scan response packet, not the advertising packet. Android's Bluetooth stack throws away the RSSI value for the first packet. Why do you need it anyway? It should be more or less the same as the first packet since both packets are sent within such a short interval.
You can't get RSSI for a scan request. This info is not sent from controller to host if you read the HCI standard. Even if the Bluetooth stack would listen to "LE Scan Request Received event", that event doesn't include RSSI.
Is BLE supporting pinging, i.e. sending a message to other devices and receiving their status?
I want to write an app on Android, which will ping each of the nearby devices and calculate the time between sending time and receiving answer, is it possible?
As you pointed out in your comment you like to use as time-of-arrival or time-difference-of-arrival algorithm to calculate the distance based on bluetooth.
To my knowledge this is currently more a theoretical approach in a bluetooth environment. As radio signals travel at light speed (~29.979 cm in one nanosecond) you will need a high sampling resolution to get a accurate result. Each nanosecound deviation will cause an error of roughly 30 cm.
With WiFi this is accomplished with a specalized chipset. To my knowledge this is currently not possibile with android as it would need a lot of low level support (Chipset and OS)
Hope this helps!
here are some sources
Android relative positioning, Wifi:Time of Arrival
Evaluation of indoor positioning based on
Bluetooth Smart technology - page 76
You can easily see the timestamp of discovery for each device in your onScanResult method:
#Override
public void onScanResult(int callbackType, ScanResult result){
Long lastSeen = result.getTimestampNanos();
//rest of your code
}
See the Android Documentation. You can use this timestamp and the time that you started your scan to get an approximate response time for each device.
I am having some difficulties with Bluetooth Low Energy on Android. I have closely done the guide I linked, as well as checked the full example code. I have a BLE device I need to connect to and retrieve data frames from. The documentation at one point dictates to
Discover/Enable service: Service UUID UUID1, Characteristic UUID UUID2
Once this has been executed correctly, the device should start streaming frames of 20 bytes formatted in a particular way.
Searching for the device, connecting to it and discovering services on it I have no problem with. But then I'm stuck. To get the services, BluetoothGatt's method getServices() is called. This returns a list of BluetoothGattService's, which on their part also contain a list of BluetoothGattCharacteristic's. Obviously the BluetoothGattService's UUID must be equal to provided UUID1, and BluetoothGattCharacteristic's UUID to UUID2. But I do not know how to 'enable' this service with certain characteristic.
My documentation also does not mention descriptors. I have checked and there is only one descriptor in the UUID2 characteristic. So now I have everything one could possibly need - Service UUID, Characteristic UUID and Descriptor... But how do I read the data?
You can iterate over all found characteristics and get the BluetoothGattCharacteristic object with UUID1 and UUID2. Use "UUID.fromString()" to convert a string representing the UUID to a UUID object, which than can be used with ".equals" to compare with "characteristic.getUuid()".
If I've understood you correctly, you want to read some data of a characteristic. When you call "connectGatt" on your BluetoothDevice, you get an object of type "BluetoothGatt". Use this gatt object after discovering the service and characteristics to call "readCharacteristic()" on it, passing the desired BluetoothCharacteristic as argument.
I hope I could help and let me know if I should clarify my answer
Linard
I want to get the Signal strength of the WiFi network I am connected to , as it changes .
This is my broadcast receiver
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int info = Wifi.getConnectionInfo().getRssi();
textStatus.append("\n\n : " + Integer.toString(info));
}
}, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION));
I am getting it only once . How do i get it as it changes ?
Update: From tests in Android 4.4 and 5.0 the interval between sequential WiFi scans seems to be less than a second. You can take a look at my demo for RF measurements using Android device, here:
https://github.com/panosvas/Measurements
where you can find an implementation of WiFi measurements one after another. I have also created a Server for storing these measurements as well as a remote trigger app using UDP packets where you can find here:
https://github.com/panosvas/IndoorPositioningServer
Actually, you cannot take the RSSI each time it changes because it is possible that the RSSI value changes in a period of mseconds or even faster and each wifi measurement in Android takes approximately 5 seconds depending also on the device.
So, what you advice my answers in the following posts for that:
Wifi Scanner which scans 20 times
How to update wifi RSSI values without a click button