PerceptualRobotics
PerceptualRobotics

Reputation: 451

How long does wifi rssi take in android?

I have the code to display the RSSI value of a connected network. A background process continually calls getRssi and the loop time is a few milliseconds.

In the loop I post values by a handler to the UI thread where I display the current time, along with the loop rate.

However, the UI display updates every few seconds whereas the loop rate is a few milliseconds. Why the discrepancy?

package uk.co.moonsit.apps.wifi;

import uk.co.moonsit.apps.sensors.R;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.Time;
import android.view.View;
import android.widget.TextView;

public class WifiRssiActivity extends Activity {

private WifiManager wifi;
private Handler handler = new Handler();
// private String toastText;
private TextView tvStrength;
private TextView tvSpeed;
private TextView tvSSID;
private TextView tvTime;
private View view;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_wifi_rssi);

    tvStrength = (TextView) findViewById(R.id.textViewWifiRssi);
    tvSpeed = (TextView) findViewById(R.id.textViewSpeed);
    tvSSID = (TextView) findViewById(R.id.textViewSSID);
    tvTime = (TextView) findViewById(R.id.textViewTime);

    String service = Context.WIFI_SERVICE;
    wifi = (WifiManager) getSystemService(service);

    Thread thread = new Thread(null, doBackgroundThreadProcessing,
            "Background");
    thread.start();
    view = this.getWindow().getDecorView();
    view.setKeepScreenOn(true);
}

private Runnable doBackgroundThreadProcessing = new Runnable() {

    public void run() {
        backgroundThreadProcessing();
    }
};

private boolean isRunning = true;

// Method which does some processing in the background.
private void backgroundThreadProcessing() {

    long mark = System.currentTimeMillis();
    while (isRunning) {
        int strength = 0;
        int speed = 0;
        String units = null;
        String ssid = null;
        long ms = 0;
        WifiInfo info = wifi.getConnectionInfo();
        if (info.getBSSID() != null) {
            strength = WifiManager
                    .calculateSignalLevel(info.getRssi(), 100);
            speed = info.getLinkSpeed();
            units = WifiInfo.LINK_SPEED_UNITS;
            ssid = info.getSSID();
        }
        long now = System.currentTimeMillis();
        ms = now - mark;
        mark = now;
        GUIRunnable doUpdateGUI = new GUIRunnable(strength, speed, units,
                ssid, ms);
        handler.post(doUpdateGUI);
    }
}

public class GUIRunnable implements Runnable {

    private int strength;
    private int speed;
    private String units;
    private String ssid = null;
    private long ms;

    public GUIRunnable(int st, int sp, String u, String ss, long m) {
        strength = st;
        speed = sp;
        units = u;
        ssid = ss;
        ms = m;
    }

    public void run() {
        updateGUI(strength, speed, units, ssid, ms);
    }
}

private void updateGUI(int strength, int speed, String units, String ssid,
        long ms) {
    Time today = new Time(Time.getCurrentTimezone());
    today.setToNow();

    String millis = String.valueOf(System.currentTimeMillis());
    String time = today.format("%k:%M:%S.")
            + millis.substring(millis.length() - 3);

    tvStrength.setText("" + strength);
    tvTime.setText(time + " - " + ms);

    if (speed > 0)
        tvSpeed.setText("" + speed + units);
    if (ssid == null || ssid.length() == 0)
        tvSSID.setText("No wifi connection");
    else
        tvSSID.setText(ssid);
    // Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_LONG)
    // .show();
}

@Override
protected void onResume() {
    super.onResume();
    isRunning = true;

}

@Override
protected void onPause() {
    super.onPause();
    // ssid = null;
    isRunning = false;
}

}

Upvotes: 0

Views: 2445

Answers (2)

Safi
Safi

Reputation: 43

checked google sources and it appears to me Android will only poll WIFI RSSI once every 3 seconds (most likely to save CPU and battery resources).

Here is the snippet from WifiStateMachine.java:-

/**
 * Interval in milliseconds between polling for RSSI
 * and linkspeed information
 */
private static final int POLL_RSSI_INTERVAL_MSECS = 3000;

Upvotes: 2

iheanyi
iheanyi

Reputation: 3113

The android api doesn't specify the rate at which RSSI is updated or when it is updated, but in general I doubt it is faster than once a second for power saving purposes.

I found an article on how to use a broadcast receiver to get RSSI updates (rather than continuously polling): http://android-er.blogspot.com/2011/01/check-rssi-by-monitoring-of.html

The API does suggest that getRSSI and other methods are simply returning data from the last scan, so likely the update rate is the wifi scan interval. This is typically controlled by the build.prop file (see line 103 of this example file: http://androidforums.com/threads/stock-build-prop-download.561012/) and could vary from device to device so likely, the most efficient way to update the user on RSSI (or other wifi parameters) is to use a broadcast receiver and update when available.

Note, based on the answers to this question, some wifi device drivers don't support being configured by the build.prop file, so even if one had root access to modify the file, it doesn't guarantee that you can change the scan interval: https://android.stackexchange.com/questions/37621/where-can-i-find-settings-for-wifi-internal-scan-period

Upvotes: 0

Related Questions