Scanning for beacons multiple times in a second (Android-Java) - java

I'm using the following method (taken from the android beacon library)
public void didRangeBeaconsInRegion(final Collection<Beacon> collection, Region region)
This callback method "detects" beacons every 1.1 seconds. To be more precise, it fires every 1.1 seconds. My beacon device (Kontakt i.o). Sends packets every 200ms. I've found out that there isn't a way to somehow decrease the firing interval of the above method so my question is, is there an alternative for this method so that I can do my distance calculations more often.
Basically I'm providing the RSSI and TxPower as arguments and doing some more calculation to make the distancing more accurate so I would like to get my RSSI every 200ms not every second...

Create an instance of the BeaconManager, you can set a couple of methods regarding the scanning:
BeaconManager manager = BeaconManager.getInstanceForApplication(context);
manager.setBackgroundScanPeriod(milliseconds); //defaults to 10
manager.setBackgroundBetweenScanPeriod(miliseconds); //Period between scans
manager.setForegroundBetweenScanPeriod(miliseconds); //Period between scans
manager.setForegroundScanPeriod(milliseconds); //defaults to 1.1
You can find some more methods when you look at the BeaconManager source.

Related

Android: How can I start a timer that begins at the next exact multiple of 2 seconds?

I am new to android and have been thrown in at the deep end with a somewhat complicated project.
I effectively have a number of devices running the same app and they are either staff or Exclusion zones.
I need to use bluetooth beacons to have the devices transmit their GPS coordinates, and the exclusion zones also transmit their boundary size (Bluetooth beacon distance detection was not reliably accurate enough.)
What I want to do is have a service running (I think) that has the staff devices listen for one second, whilst the exclusion zones broadcast, then all devices flip between listening and broadcasting for the next second, then repeat.
Any detected boundary violations calculated by taking the distance between the devices own GPS coordinate and any that have been broadcast by other devices of the opposing type are then to be logged.
How can I get a timer to start, and repeatedly call the function every 2 seconds, at the next exact multiple of 2 seconds?
NOT 2 seconds from the point at which the function is called. For instance if the time is 12h:35m:01s:223ms I want the repeating function to be called at 12:35:02
Compute the time remaining to the next two-second mark and then use that to schedule a delayed, one-time task that will start a two-second repeating timer.

Android Periodic Sensor Data

For an Android App, that will show the value of an internal sensor (e.g. Acceleration) in a graph, i need to find a way to access this signal periodically.
At the moment i am using a SensorEventListener, but unfortunately this only gives me the possibility to get a value whenever it changes.
Since I want to display the graph (point to point) in dependency of the time, this means it would directly draw a line from the old to the new value (and if the old value has been a long time, it looks like a linear changing of the value).
So my question: How can I get access to a sensor's data periodically?
The documentation for SensorManager says that registerListener(android.hardware.SensorEventListener, android.hardware.Sensor int)
"Registers a SensorEventListener for the given sensor at the given sampling frequency."
To get these events, though, your application would need to be active (hold a partial wake lock). It would be better to do this in a background service so that the application doesn't need to remain active. See for example, SensorEventListener in a service
So in the end i used a timer, which checked the values from my sensor, which I put into an array, periodically.
Unfortunately registerListener didnt work, since the value is just a suggestion for the system.
Thanks though for the help.

Android BLE proximity notifications

I've been working on developing an application that interacts with BLE devices. Everything works great, I can scan, connect, and consume services.
I've been reading through all the docs and I do not see anything that gives the developer the option of listening for BLE devices. Basically I would like to trigger a broadcast receiver when the devices enters the range of a BLE device.
I know I could continually scan for this, but battery use is way too high and I would like this to be invoked even when my application is not being used.
Is this feature not supported or am I missing a section of the docs that discuss this?
I have done a project recently, and from what I read in your question it has some similarity to what I did.
I know I could continually scan for this but battery use is way too high and I would like this to be invoked even when my application is not being used.
Regarding battery problem, having Bluetooth on all the time is power consuming, but at the same time you can not detect BLE with out having Bluetooth on.
What I did is two experiments and both are useful but are different and I can not say which one is best, but you need to test it so it fits your requirement.
Having Thread running that turns Bluetooth on and listen to iBeacon and off (with sleeping time) for while programmatically. It can be done many ways.
Using a package called Altbeacon, has a lot of useful features, one of those features is Auto Battery Saving with example code:
public class MyApplication extends Application implements BootstrapNotifier {
private BackgroundPowerSaver backgroundPowerSaver;
public void onCreate() {
super.onCreate();
// Simply constructing this class and holding a reference to it
// in your custom Application class
// enables auto battery saving of about 60%
backgroundPowerSaver = new BackgroundPowerSaver(this);
}
}
We need a broadcast event, that wakes up our app once a BLE-device with a certain Service-UUID is in reach. Maybe now there is a better BLE API available than 2 years ago. The most energy saving and most precise method gets rewarded.
Your other part, it is called triggering actions at a specific distance.
I still use the Altbeacon to check beacon range and triggering action. A sample code is something like
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
for (Beacon beacon : beacons) {
if (beacon.getDistance() < 5.0) {
Log.d(TAG, "I see a beacon that is less than 5 meters away.");
// Perform distance-specific action here
}
}
}
So when that said, you can also get distance of specific UUID I build a method based on Altbeacon, looks like this (Look inside the for loop and if statement):
private void startRangeNotifier() {
Log.i(TAG, "Starting range notifier...");
beaconManager.setRangeNotifier(new BeaconRangeListener() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
for (Beacon beacon : beacons) {
Log.d(TAG, "uuid's: " + beacon);
Log.d(TAG, "uuid id1: " + beacon.getId1());
if (beacon.getId1().toString()
.equals("b9407f30-f5f8-466e-aff9-25556b57fe6d")) {
Log.d(TAG, "uuid id1 distance: " + beacon.getDistance());
}
}
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(
new Region(BEACON_MONITORING_ID, null, null, null));
} catch (RemoteException e) {
e.printStackTrace();
}
}
My log output:
D/Main activity:: uuid's: id1: b9407f30-f5f8-466e-aff9-25556b57fe6d id2: 31807 id3: 59251
D/Main activity:: uuid id1: b9407f30-f5f8-466e-aff9-25556b57fe6d
D/Main activity:: uuid id1 distance: 0.2108658568686884
In my answer I wanted to present the concept I used, Beacons project need patience in general. As the other answer mentioned it is also possible to combine the solution here with Geofences and ActivityRecognition.
Note: Since the nature of bluetooth beacon, the distance is proximity and not absolute, and some time even the bluetooth beacon is 1 meter a way it might show 2 meter or 0.5 meter, so have that in mind
Link reference:
https://altbeacon.github.io/android-beacon-library/distance-triggering.html
https://altbeacon.github.io/android-beacon-library/samples.html
https://altbeacon.github.io/android-beacon-library/eddystone-how-to.html
https://github.com/AltBeacon/android-beacon-library-reference
BLE scanning on Android is pretty battery intensive, and it's definitely not something you want to do in the background all the time. If you are working on a background application with stationary bluetooth devices (à la ibeacons) that you know the location of, you can use Geofences to turn scanning on and off when you think you are in the approximate proximity of a device. If you are not careful geofencing can also drain battery.
If you don't know the location of your bluetooth devices I guess you can also play tricks with ActivityRecognition, i.e only scan periodically when the user is walking and stopping it if the user is stationary/running/biking/in vehicle. Again, the activity recognition stuff also takes battery so you are going to have to be judicious.
We need a broadcast event, that wakes up our app once a BLE-device with a certain Service-UUID is in reach.
You probably know how to filter scan results by Service UUID so I won't go into that. About the waking up: if your app is scanning, it is awake by definition. It may or may not be on the foreground, but it is awake.
Maybe now there is a better BLE API available than 2 years ago.
Since SDK version 21, there is a new API that you can use for BLE scanning. To my knowledge, the only difference is the way you access the API and the underlying functionality (regarding power consumption etc.) has not changed.
About the scanning:
It's true that scanning is battery-intensive. Even the docs say so.
The intensity is relative though. It is intensive compared to not scanning at all, but it is not intensive enough that it will hopelessly drain your battery. It's called low energy after all.
An other answer suggest monitoring Geofences and only scan when you know you are in range of BLE devices. While this will lower the battery consumption of the ble scan, it will need that battery power for the GPS, otherwise it can't monitor the Geofences (well, it can, with cellular/wifi data, but then it won't be nearly as accurate).
Depending on how time critical your scanning is (e.g. if there is a device nearby, must you know it right away? or is it okay if it's delayed a couple seconds?) you can implement a pause inbetween scans.
Say you scan for 5 seconds, pause for 5 seconds, scan for 5 seconds again. That way you will be scanning almost all the time, yet only consume roughly half of the battery power. These intervals can be tweaked to match your situation. Maybe you're okay with scanning 3 seconds and pausing for 10. (note that the maximum time between a device's broadcasts is 10.24 seconds).
I have an app with about 50 users that scans with pauses like this (scan for 3 seconds, pause for 3, repeat) 24/7 in the background, and have not received any complaints about excessive battery usage.
If you have a specific BLE peripheral you want to detect, then figure out its advertisement period. If you have different devices, find the longest advertisement period. Scan longer than the advertisement period of the device, so you get at least one advertisement message. Repeat this scanning periodically with the frequency that is suitable for your use case. E.g. Your peripheral is advertising every second once. You would like to detect the device in 5s when it comes to proximity. Then Scan for 1s (or a bit more). Switch off scanning for 4s. This way you can save battery.

Error in taking multiple picture in one second on Android

I want to use the Android to take multiple images in one second. The basic idea is to use a Timer at a certain FPS that will trigger the camera to capture images.
The problem is that when I want to trigger the camera more than 1 times in one second, say every 500ms, there will be an error in startPreview. java.lang.RuntimeException: startPreview failed
How can i fixed this?. Thanks.
You should call startPreview() in your onPictureTaken() callback, and nothing guarantees that this callback will be activated at the frame rate you expected. Many cameras provide burst-shot mode, but there is no common API yet. Hopefully, soon this API will arrive.
I take the same error for trying to take many pictures even when the camera is not ready.
So you should define a boolean isItSafeToTakePicture to control if the previous photo-take-action is finished.
Using a boolean like this should solve the issue, even though you may not be able to set 500 ms interval for taking photos, this boolean will define the minimum time limit.

How to detect and manage incoming call (Android)?

I want to create an application that can detect incoming calls and start my custom activity after a certain number of beeps (rings), I mean after 2 or 3 or 5 beeps (rings) my activity is triggered. How can I do it?
Thanks
I don't think you can count the number of rings the phone made since the start of the incoming call. There can't be a definitive measure of a single ring because the user can easily change the ringtone to a non-repetitive tune, for example, a song.
What you can do, however, is count the amount of time that passed since the arrival of the call. Set up a BroadcastReceiver for PHONE_STATE (you will need the corresponding permission in the manifest to receive the event). Once you receive the EXTRA_STATE_RINGING that came with the PHONE_STATE, set an alarm via the AlarmManager that will fire a Service that checks if EXTRA_STATE_OFFHOOK (broadcast when the call is picked up) has been broadcast after your waiting time. If not, then you can start your answering machine.
I have written a quick tutorial in my website on how to catch the call's arrival (when the phone rings), when the call is picked up, and when it ends.
My article about detecting incoming and outgoing calls, with the step-by-step instructions:
Detecting incoming and outgoing phone calls on Android
When you detect incoming call, you can start a timer, with interval equal to beepInterval * beepCount. And launch activity on this timer.

Categories