How to get the WiFi noise level in Android? - java

I want to implement an app which measures the quality of the WiFi signal from an indoor environment. From my research I found that the best way to get an accurate measurement is not to get only the RSSI but instead to use the SNR (Signal to Noise Ratio).
How can I obtain the noise level from the Android SDK? As I heard, there is no API available for this. However, I've found a method which provides the SNR (getEvdoSnr()). Unfortunately, this one works only for a GSM/CDMA signal and not for a WiFi connection.
Is anything possible to calculate the SNR in Android? I believe that's doable because I've found an app on Play store (called WiFi SNR) which successfully measures this ratio.
NOTE: The Android ScanResult doesn't provide the noise level, even if it's specified in the official documentation:
Describes information about a detected access point. In addition to the attributes described here, the supplicant keeps track of quality, noise, and maxbitrate attributes, but does not currently report them to external clients.

Use https://developer.android.com/reference/android/net/wifi/ScanResult.html.
Describes information about a detected access point. In addition to the attributes described here, the supplicant keeps track of quality, noise, and maxbitrate attributes, but does not currently report them to external clients.
I bet something like this will give to you desired information:
WifiManager manager = (WifiManager) getApplication().getSystemService(Context.WIFI_SERVICE);
for (ScanResult result : wifiManager.getScanResults()) {
// do your stuff
}

Related

How to find the distance between bluetooth devices

Description :
I'm trying to find a way to calculate the distance between the application, and nearby Bluetooth devices.
That, or only detect devices that are x meters away from the device with the application.
Tried so far :
I tried using the Bluetooth's signal strength, but it is not reliable, as it has so many variables other than the distance (rotation of the device, objects between the 2 devices, etc). For example, I kept an eye on a device that was still on a table, and the numbers went up by 10 mBw without neither of the devices moving.
I also thought of using GPS for distance calculation, but GPS's accuracy is vary big compared to the accuracy I'm looking for (+-1m).
I look for lowering the strength of the Bluetooth signal before searching (on newer Bluetooth versions), to find less devices within a lower range. But the people who have tried it say it is unreliable because even at the lowest energy for Bluetooth, the Bluetooth was able to find devices that are about 10m away.
Examples around us :
If anyone has an Apple Watch and a Mac, they'd know that it is possible to unlock your Mac by simpley being close to your Mac while wearing your Watch.
Also, car keys. When you get close enough to the car while carrying the key on you, the car is unlocked.
Notes :
Assume all the devices are Android devices with high their hardware. It's a special implementation, not for everyone
A good discussion of techniques for calculating distance using Bluetooth devices is here: https://vimeo.com/171186055#t=40m15s.
With respect to the Apple Watch and Mac, Apple is using Time-of-Flight via peer-to-peer WiFi to determine proximity at that level of accuracy.
Typical automatic remote keyless entry systems utilize radio pulse, not bluetooth. More advanced systems, like Tesla's Phone key, uses Bluetooth on the phone device, but relies on the driver to physically touch the door handle to complete the process.
This might be possible but not much accurately.
You should approach to it like this:-
You should measure the signal strength, and then measure the distance using the speed of bluetooth (it usually travels 1cm in 100ps). Timing it would be difficult though.
Then, using the data you can easily measure the distance ( it is usually less that 10 m but can go farther).
You would get an answer but it would be really an approximate one.
As per me, the exact measuring is not possible.

startScan() in WifiManager deprecated in Android P

How to get scan result from wifi for example every 3 seconds, without mWifimanager.startScan();
Google says :
startScan()
This method was deprecated in API level P. The ability for apps to trigger scan requests will be removed in a future release.
Notice for this API level i'm using
List<ScanResult> results = mWifiManager.getScanResults(); without calling startScan , the list contains the wifi AP's but it makes updated very very slow
Update to 12 January 2019 : https://issuetracker.google.com/issues/112688545
Google has now documented the limitations for startScan() function in Android P:
"We are further limiting the number of scans apps can request to improve network performance and improve battery life.
The WifiManager.startScan() usage is limited to:
- Each foreground app is restricted to 4 scans every 2 minutes.
- All background apps combined are restricted to one scan every 30 minutes."
Source:
https://issuetracker.google.com/issues/79906367
Edit 8-Aug-2018: Information has been added also here:
https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling
I think in API level P they're planning to move startScan() to a different class (WifiScanner) all together with some key differences.
See: https://android.googlesource.com/platform/frameworks/base/+/android-p-preview-1/wifi/java/android/net/wifi/WifiScanner.java
If there's an alternative solution to this, I'd love to hear it as well.
For now, I might just use startScan() until official docs are released.
startScan() is actually pretty buggy on P, as I raised Google Issue 79906367.
I don't think that WifiScanner is the replacement either, as that is marked as a SystemApi which means no access for Apps...
Hopefully we will hear soon, as RTT still means you need to scan for APs which support 802.11mc using ScanResult is80211mcResponder which you check before performing RTT Ranging on the AP.
StartScan() method is deprecated in Android P and new RTT protocol from 802.11mc standard has to be used with trilateration Algorithms.
https://android-developers.googleblog.com/2018/03/previewing-android-p.html
X,Y position of the AP should to be knonw for accurate positioning and the AP should support 802.11mc's Fine Time Measurement. IntelĀ® Wireless-AC 9260 support 802.11mc and several APs start supporting 802.11mc standard.
A couple of examples:
https://medium.com/#rafaelmiguel.ortega/android-p-first-taste-of-rtt-support-febefb679775
https://medium.com/#plinzen/perform-wifi-round-trip-time-measurements-with-android-p-9ffc5277ac6a
From WifiManager#EXTRA_RESULTS_UPDATED
Note: Apps holding android.Manifest.permission.NETWORK_SETTINGS permission are exempted from scan throttling.
Note: This is a system permission, regular apps can't use it without rooting and moving the app to the 'privileged' location or having it baked into a custom ROM.
I would guess the intention is to have developers/users use WifiRttManager instead for indoor location atleast [1].
Or rely on usual Google Play location services, which is an option in some use cases, but definitely not all. It's optimised for the average use case. No use case is the average use case.
Unfortunately with the way WifiRttManager calculates location it requires the wifi accesspoints to have 802.11mc. However you don't need to connect to these points.
Virtually 0 routers today have this standard. [2] [3] [4]
With 3 access points you can get location close to 1-2m accuracy.
Who knows if they'll place restrictions on this functionality as well though.
I'm not happy that this functionality is being taken away from users and developers - all it needs is a permission.
So it appears there will be a dark age for indoor location over the next few years until 802.11mc is popular.
Perhaps a workaround is to have devices you are connected to and ping them.
[1] https://developer.android.com/reference/android/net/wifi/rtt/WifiRttManager
[2] https://github.com/Plinzen/android-rttmanager-sample
Additional reading
[3] https://en.wikipedia.org/wiki/IEEE_802.11mc
[4] https://fit-iot.com/web/wifi-indoor-positioning/
I think google is planning to restrict application from scanning wifi.
This method was deprecated in API level 28. The ability for apps to
trigger scan requests will be removed in a future release.
Check the documentation here.

Having problems getting Weight Data with Android from a BLE Scale

I'm currently developing an android app for a weight scale I received that transmits data through bluetooth low energy.
I was looking at documentation and if I got the information correctly, there are specific UUIDs for data. I received a BLE scale with a Chinese protocol document found here: http://www.anj.fyi/protocol.pdf
I found and was able to get a functioning scanner working that lists the device name and the UUIDs it broadcasts.
Lets say I want just the weight data to show up in the UI, nothing else and nothing more.
I don't know what UUID they used for the weight data, and there are a lot of UUIDs. Probably 20+. I checked a UUID compilation and the usual weight data UUID does not show up.
How do I get the data from those UUIDs?
I'm thinking it might be the ones that are notifications, indications or read properties.
Looking at the UUID for example, f000ffc2.
How would I get data from that characteristic? Would anyone have an example code to grab the data from those UUIDs, or tutorials because I'm terribly lost right now.
I really appreciate it.
There are no weight information on the document you list http://www.anj.fyi/protocol.pdf, it is only shows the BLE module hardware interface spec, i.e. it does not specify the detailed service and characteristic.(I an a native Chinese speaker).
Regarding to the UUID you want to know which is the one to represent the weight, yes you are right it should be the read/notification feature without write permission. Can you use the apps e.g. lightblue on iOS to receive the notification(meanwhile change the value on your device) to test it? this will help you to understand which characteristic is the one you want.

Android - Adaptive Bit rate streaming. (HLS) Quality of stream

I'm new to adaptive bit rate streaming. Basically I'm trying to write an app that shows information about the quality of the connection on an Android device.
Since HoneyComb(3.0), Android supports adaptive bit rate streaming through HTTP Live Streaming (HLS). It seams like support for helping developers verify the quality of this connection device side is very limited.
What I would like to know is some low level information about the stream. Such as: the number of segments, the segment duration, number of requests to change bit rate, the bit rate the media player sees (to facilitate the change), etc.
I've been able to get some information about stream quality from the MediaPlayer, MediaController, MediaMetaDataRetriever, CamcorderProfile, MediaFormat, MediaExtractor classes. However, the stuff I'm looking for is even lower level. If possible I'd like to be able to actually see how the player is communicating with the server.
I just started looking at the MediaCodec class, however I can't figure out how to get the MediaCodec from a mediaplayer. Or Maybe I just don't know how to use this properly as I cannot find any good documentation and examples.
Does anyone know if it is possible to access the low level information on the Android that I'm looking for? Is the MediaCodec the way to go? If so, does anyone have any working examples of how I could get the currently used MediaCodec and extract the information I'm looking for out of it? (Or at least point me in the right direction)
Really appreciate any help on this one.
Cheers

how to calibrate the orientation sensor in android?

I'm writing an app in Google Android 2.1 that needs to know which direction (n/w/s/e) the device (HTC Hero) is facing. The sensor and its listener are working great, but the values I get from the sensor are totally crappy. e.g. it tells me I'd be facing north when the device is facing SW or so...
This seems to be a known problem with android devices. The "solutions" I found on the web look like this:
shake the device around
move the device like an eight
tap on the devices back
This is thought to trigger the sensors recalibration. And: the thing with the "moving around" works for me... but that's not very professional I guess...
so - how do I trigger the recalibration of the orientation sensor from the SDK? I need the sensor to be properly calibrated without any fancy stuff that would make users of this app look like complete idiots while they are "manually" recalibrating their phones...
Is there any way to do this "right"?
EDIT:
Or: is there any way to determine PROGRAMMATICALLY, if the device is correctly calibrated or not? As a fallback-option so to speak... then I could warn the user that the device needs "manual" recalibration.
I don't believe there is a way to know programatically if you compass sensor is calibrated correctly unless you use a secondary data source like GPS. If you can use GPS then when the user is moving you can compare the GPS movement with the compass heading and correct. Remember that local magnetic fields can screw up the compass readings and the devices has no idea if you are out in the middle of a forest or next to a transformer.
With these micro devices there is always a bit of skew you'll have to deal with. If you check the values for the accelerometer as well you'll see that at rest they aren't always returning 9.8 m/s^2 (or at least consistently between devices).
In your help you may just need to tell the user to rotate/twist their phone in a figure eight to reset the compass.
I assume you are referring to the Magnetometer inside the Hero.
Callibrating it is a tough one and will/should always require user interaction for a realiable callibration. There are seperate strategies to deal with that. You could ask users to hold there device in north direction and then recallibrate. If the users don't know where north is, you can ask them to direct zhe device towards the sun and based on location and time you can calculate where that is.
Leaving callibration aside, I would guess that your problem is that the readings you get from the sensor are inaccurate. Of course callibration is a prerequisite for accurate readings, but there are also other factors in play.
It is common practice to complement sensor data from one sensor with the data a different sensor to increase accuracy. You could use the GPS to determine a heading when the user is moving. If he's moving slowly however, this is inaccurate as well. You could integrate the data reported by the Accelerometer to guess about orientation changes (not the absolute orientation). But honestly a Gyrometer would be more ideal in this case.
Systems that work like this are sometimes called Inertial Navigation Systems (INS) because they can, given a fixed point in space, determine their subsequent relative position and orientation accurately without further external data. Using a Kalman filter is common practice to recallibrate the system from time to time when an absolute position (e.g. retrieved via GPS) is available.
Although it is unrealistic to implement a full-fledged INS, you can certainly draw a few ideas from how they work to make your orientation readings more accurate.

Categories