How to get android bluetooth RSSI (receiver signal strength)

pzqpzq
edited February 2017 in Android Mode

Hi,

I'm just diving into processing.org and java programming and wonder, how could i get the RSSI method called from the android libraries.

I know the rssi is within this lib: import android.bluetooth.BluetoothDevice; And there: String EXTRA_RSSI https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#EXTRA_RSSI

The problem is, i have no clue how i should code this into my project... I'm using Ketai bluetooth to connect between android and a microcontroller RN41 bluetooth module and ketais libraries doesn't include any RSSI fetching method or what so ever.

I just tried this: String rssi = android.bluetooth.BluetoothDevice.EXTRA_RSSI;

The code compiles ok but doesn't work... -> i use text(rssi, width/3, height/2); to print the value to device screen, The result is just that there is a text string on screen "android.bluetooth.device.extra.RSSI"

Let me know if you other experienced java coders know how i could get the EXTRA_RSSI value... printed on the screen correctly.

Answers

  • Thanks. I will try bake something out of those threads.

    I'll return when im stuck again :)

  • @pzq===

    android.bluetooth.device.extra.RSSI is a String with constant value "android.bluetooth.device.extra.RSSI": that is the reason why you get this text see here: https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#EXTRA_RSSI

    the value you are looking for is not a string, it is an int which is returned when

    -some device is discovered scanning and an intent is delivered with ACTION_FOUND

    • and it is now that you have to ask for your value with:: int value = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
  • pzqpzq
    edited February 2017

    Hi,

    thanks for the help so far. I tried figuring out how to override methods with the help of a new class and it would be quite easy to implement into the ketai library with override but i read that its not possible to override final marked methods/classes:

    Any tips how i could override the onReceive method.

    /** The m receiver. */
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device != null) {
                    discoveredDevices
                            .put(device.getName(), device.getAddress());
                    PApplet.println("New Device Discovered: "
                            + device.getName());
                }
            }
        }
    };
    

    If it would be possible to override making the ketai lib to use this method instead of the one in ketai lib, i could add the intent.getAction()... and print out the RSSI per device, i suppose.

  • edited February 2017

    @pzq=== right, this is the source code from ketai and as you wrote this class is a final one, so you cannot override it...Two solutions i think = first one to recompile ketai lib...rather tedious and long...second one, much more simpler to rewrite the part of your code which creates the connection using native android and overriding the broadcastreceiver class, something like this:

        private final BroadcastReceiver r = new BroadcastReceiver(){
                @ Override
                public void onReceive(Context context, Intent intent) {
    
                    String action = intent.getAction();
                    if(BluetoothDevice.ACTION_FOUND.equals(action)) {
                        int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
                        String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
    
                       System.out.println(name + " ==== " + rssi );
                    }
                }
            };
    
  • Thanks.

    I found this one. https://github.com/tutsplus/Android-BluetoothScannerFinishedProject

    I downloaded only the DeviceListFragment.java file from https://github.com/tutsplus/Android-BluetoothScannerFinishedProject/blob/master/BluetoothScanner/app/src/main/java/com/tutsplus/matt/bluetoothscanner/

    The problem i get is with the package on the first row which processing doesn't understand. Or states unexpected token: package.

    I was thinking, may it mean that i need to copy the .java files found here: https://github.com/tutsplus/Android-BluetoothScannerFinishedProject/blob/master/BluetoothScanner/app/src/main/java/com/tutsplus/matt/bluetoothscanner/ and place them into my processing "project" from menu

    sketch > add file

    well, i tried it but i got like 78 problems.

    Do you think i could get the scanner to work only with DeviceListFragment.java file by implementing the setup() and draw() methdos from other projects to visualize things ? I mean that could i just take the ketai example, drop out the calls for ketaibluetooth and replace it with the extends and overrided functions from the file ?

    --- ooh, this is so horrbile... sorry. Some tips again and maybe i'll get some ideas what to try next.

    -Pzq

  • I think i found something rather close :) https://github.com/joshuajnoble/blepdroid

    Can you help me out what i should do so that i can use the blepdroid library when its not in the processing ide as a library yet ? Must i download each .java file and the manifest or should i download the whole blepdroid repo and paste it under documets/processing/libraries/blepdroid etc. Let me know. It would help me out very much.

    -pZq

  • @pzq=== blepdroid can work but you have to compiled it as a processing library; i have done that and it worked. Yet you have to use Eclipse for that and it is not so simple. As i dont know if ketai is only for the connection and info about devices connected i cannot help you more; yet, in my mind, the best solution is to use the standard native android API for bluetooth: it is very simple to integrate.

  • @akenaton I got Joshua (the guy who developed blepdroid) to include the library so that i didn't need to compile the library. I'm still facing problems finding any devices with eg. the hello.pde example.

    If you happen to have a good native bluetooth example (which i haven't found yet) please let me know.

  • @pzq=== ok; i think i have that (bluetooth native android) somewhere on my computer and i ll post as soon as possible.

  • pzqpzq
    edited February 2017

    I found one good tutorial for native android BT at arduinobasics.blogspot.fi/2013/03/arduino-basics-bluetooth-android.html

    But i did only part 1 yesterday. I will continue and see if the tut. Is ment for my purposes.

  • @pzq===

    be prudent with this tuto:

    it s written for processing 2 and it is possible that something has to be changed

    it uses APWidgets lib which is not (i believe) updated for P3

  • Here is what I did a year ago. It means I lost most of the project:

    Uninstall Ketai.

    Copy KBluetoothConnection.java, KBluetoothListener.java and KetaiBluetooth.java to your sketch folder (I also had KetaiSensor.java but don't remember why. Maybe Bluethooth needs Sensor).

    Edit KetaiBluetooth.java:

         /** The discovered devices. */
          private HashMap<String, String> discoveredDevices;
          private HashMap<String, String> discoveredDevicesRSSI;//<---
    ...    
          discoveredDevices = new HashMap<String, String>();
          discoveredDevicesRSSI = new HashMap<String, String>();//<---
    ...    
          public void discoverDevices() {
            discoveredDevices.clear();
            discoveredDevicesRSSI.clear();//<---
    ...    
          public void cancelDiscovery() {
            if (bluetoothAdapter.isDiscovering()) bluetoothAdapter.cancelDiscovery();
            discoveredDevices.clear();
            discoveredDevicesRSSI.clear();//<---
    ...    
          /** The m receiver. */
          private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
              String action = intent.getAction();
              if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);//<---
                if (device != null) {
                  discoveredDevices.put(device.getName(), device.getAddress());
                  discoveredDevicesRSSI.put(device.getName(), String.valueOf(rssi));//<---
                }
              }
            }
          };
    

    I also wrote a function to get RSSI by device Name:

      public String getRSSIByName(String _name) {
        String rssi = "";
        if (discoveredDevicesRSSI.containsKey(_name)) {
          rssi = discoveredDevicesRSSI.get(_name);
        }
        return rssi;
      }
    

    At sketch, import ketai.net.bluetooth.*;

    I remember I had partial success. Code wouldn't compile on certain android versions but worked with others.

    I dropped this project because I couldn't achieve what I wanted: a permanent RSSI monitoring. It seems it only can be measured at discovery.

  • With android its possible to measure rssi for longer time periods of several devices. At least NextGen bluetooth program on google play does this quite nicely.

    But anyways, if you did want to measure while connected, then its maybe not possible with android API. With Microcontroller bluetooth modules it is possible to read RSSI during connected state.

  • pzqpzq
    edited February 2017

    Hello,

    With the tutorial i found, i managed to read the RSSI of discoverable BT devices! Neat, or so... but @akenaton, do you happen to know if the discovering process can be faster in the way that i would get more frequent RSSI values per dive than 1 RSSI per around 4 seconds ?

    The nextgen bluetooth app seems to be able to do a little more frequent polling when selecting a specific device to show RSSI gauge meter. If i could manage to get the polling frequency to around once per 2 seconds, it would be good. 4-5 seconds is quite anoying time to wait for the values to update.

    With the whole code from this page: http://arduinobasics.blogspot.fi/2013/03/arduinobasics-bluetooth-android.html I managed to get the discovering done by adding short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE); inside public void onReceive(Context context, Intent intent) {

    and printed it out inside the same method with text(); function

    @linuxman, i couldnt get working that HashMap thing. Processing thought that i'm missing a curly brace '}' if i have the rows:

    private HashMap<String, String> discoveredDevices; private HashMap<String, String> discoveredDevicesRSSI;

    i placed those right after imports on outside any classes and methods. (globally)

  • @pzq=== as for HashMap<,>you only have to add a java import:

    `import java.util.Map;`
    

    as for the frequency i never thought to that till now; i have to try, i ll tell the result

  • @pzq===

    sorry, the discovery process cannot be accelerated (you can only stop it as soon as some precise device is got or some number of devices added to an array); then i cannot see anyway with classic bluetooth to get the rssi value: it is only returned while scanning and in classic bluetooth getRemoteDevice.getRSSI() or .ReadSSI() does not exist (it seems to exist with ble GATT) ; looking at that i have seen that it exists a lib doing that called Bluecove bluetooth library, but i never used that...

  • Ok!

    I think i can live with current timings. Thank you for all the help to all who was involved in this thread!

    Quite fast to get things done when you just want something to be done => pointing to the fact that i started with the whole environment on saturday or sunday :)

    I couldn't have achieved this so fast without you help. I appreciate all the help i got. Thanks again.

  • pzqpzq
    edited February 2017

    Returning to the speed. I can get the discovery RSSI reading faster like this:

    in draw() {}

    discoverDevices();
    delay(500);
    

    where discoverDevices() is like this

    public void discoverDevices() {
        if (bluetooth.isDiscovering()) {
          bluetooth.cancelDiscovery();
          delay(100); // DONT CHANGE 100ms GOOD VALUE
          bluetooth.startDiscovery();
        } else {
          bluetooth.startDiscovery();
        }
    }
    

    So if we are discovering? > cancel discovery > wait 100ms > start discovery > wait at least 500ms > start over

    in this way i can get the reading a little bit more frequently but ofcourse its not at a constant rate we receive the rssi values. They seem to be received in a "random" timely maner.

Sign In or Register to comment.