setting an accuracy timer for gps app in android - android

i'm new to coding so please be gentle
i have an gps app that i want to alter its accuracy .
i want it too only log when it has a strong signal, not signal that comes and goes.
below 20 plots perfectly well but when signal is a bit in and out it will plot extremes
so what i was thinking was if the accuracy was say below 10 for a 10 seconds then start logging, and if over 30 for 30 seconds stop logging.
but set accuracy to 20 while logging.
i can work out how to use the simple command of
if(currentAccuracy <= 20.0)
but how would i implement the timer section
all i can find on timers is count down clocks
it is currently this
public boolean shouldLog(float currentAccuracy) { if(currentAccuracy <= 20.0) return true; else return false; } –
im sure this is simple if you know your way around but im at a loss
thanks for your help

Related

Android NDK Sensor strange report interval to event queue

I try to access the accelerometer from the NDK. So far it works. But the way events are written to the eventqueue seems a little bit strange.
See the following code:
ASensorManager* AcquireASensorManagerInstance(void) {
typedef ASensorManager *(*PF_GETINSTANCEFORPACKAGE)(const char *name);
void* androidHandle = dlopen("libandroid.so", RTLD_NOW);
PF_GETINSTANCEFORPACKAGE getInstanceForPackageFunc = (PF_GETINSTANCEFORPACKAGE) dlsym(androidHandle, "ASensorManager_getInstanceForPackage");
if (getInstanceForPackageFunc) {
return getInstanceForPackageFunc(kPackageName);
}
typedef ASensorManager *(*PF_GETINSTANCE)();
PF_GETINSTANCE getInstanceFunc = (PF_GETINSTANCE) dlsym(androidHandle, "ASensorManager_getInstance");
return getInstanceFunc();
}
void init() {
sensorManager = AcquireASensorManagerInstance();
accelerometer = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
accelerometerEventQueue = ASensorManager_createEventQueue(sensorManager, looper, LOOPER_ID_USER, NULL, NULL);
auto status = ASensorEventQueue_enableSensor(accelerometerEventQueue,
accelerometer);
status = ASensorEventQueue_setEventRate(accelerometerEventQueue,
accelerometer,
SENSOR_REFRESH_PERIOD_US);
}
That's how I initialize everything. My SENSOR_REFRESH_PERIOD_US is 100.000 - so 10 refreshs per second. Now I have the following method to receive the events of the event queue.
vector<sensorEvent> update() {
ALooper_pollAll(0, NULL, NULL, NULL);
vector<sensorEvent> listEvents;
ASensorEvent event;
while (ASensorEventQueue_getEvents(accelerometerEventQueue, &event, 1) > 0) {
listEvents.push_back(sensorEvent{event.acceleration.x, event.acceleration.y, event.acceleration.z, (long long) event.timestamp});
}
return listEvents;
}
sensorEvent at this point is a custom struct which I use. This update method gets called via JNI from Android every 10 seconds from an IntentService (to make sure it runs even when the app itself is killed). Now I would expect to receive 100 values (10 per second * 10 seconds). In different tests I received around 130 which is also completly fine for me even it's a bit off. Then I read in the documentation of ASensorEventQueue_setEventRate that it's not forced to follow the given refresh period. So if I would get more than I wanted it would be totally fine.
But now the problem: Sometimes I receive like 13 values in 10 seconds and when I continue to call update 10 secods later I get the 130 values + the missing 117 of the run before. This happens completly random and sometimes it's not the next run but the fourth following or something like that.
I am completly fine with being off from the refresh period by having more values. But can anyone explain why it happens that there are so many values missing and they appear 10 seconds later in the next run? Or is there maybe a way to make sure I receive them in their desired run?
Your code is correct and as i see only one reason can be cause such behaviour. It is android system, for avoid drain battery, decreases frequency of accelerometer stream of events in some time after app go to background or device fall asleep.
You need to revise all axelerometer related logic and optimize according
Doze and App Standby
Also you can try to work with axelerometer in foreground service.

Scan period of beacons in android not working as expected

I am working with beacons in xamarin android. I want the scan to be done over 60 seconds and a period of 30 seconds to wait between the next cycle of scan.
public async void DetectAvailableBeacons()
{
_monitorNotifier = new MonitorNotifier();
_rangeNotifier = new RangeNotifier();
_tagRegion = new Region("Region",null, null, null);
_beaconManager.Bind(this);
_beaconManager.SetBackgroundScanPeriod(60000);
_beaconManager.SetForegroundScanPeriod(60000);
_beaconManager.SetBackgroundBetweenScanPeriod(30000);
_beaconManager.SetForegroundBetweenScanPeriod(30000);
_rangeNotifier.DidRangeBeaconsInRegionComplete += RangingBeaconsInRegionComplete;
}
The method RangingBeaconsInRegionComplete fills my list foundBeacons with the beacons detected.
Also, I have a method that gets all the available detected beacons as follows:
ObservableCollection<DetectedBeacon> BeaconLocator.GetAvailableBeacons()
{
return !_paused ? foundBeacons : null;
}
Now, I call the method GetAvailableBeacons() as follows:
public void PopulateBeacons() {
beaconsOnList = be.GetAvailableBeacons();
PopulateBeacons();
}
My issue is that sometimes it is missing some beacons, that is some beacons are not being detected. Also, the interval of scan does not seem to be working properly. Can someone advise what is wrong ?
In order for your scan periods to take effect right away, the easiest solution is to move the calls to set them before the call to bind so it looks like this:
_beaconManager.SetBackgroundScanPeriod(60000);
_beaconManager.SetForegroundScanPeriod(60000);
_beaconManager.SetBackgroundBetweenScanPeriod(30000);
_beaconManager.SetForegroundBetweenScanPeriod(30000);
_beaconManager.Bind(this);
By default, the scan will happen every 1.1 seconds and give you a result of all beacons seen in that period. This is probably what you are seeing happening without the code change above.
With shorter scan intervals, it is common for beacons with low advertising rates (e.g. ones that advertise only once every second) to not appear in the detection list for a single scan cycle. You can solve this by increasing the length of the scan cycle as you say you want to do, by increasing the advertising rate of the beacons, or building code logic that maintains a full list of beacons detected recently even if they weren't seen in the most recent scan cycle.
Short answer: If you increase your scan period successfully, I suspect this problem will go away.

Android Fused Location Won't Deliver Periodic Updates

I want to get a hard location fix every certain minutes & a soft location fix every certain minutes and if user has moved more then certain meters. I been testing the logic with following piece of code walking (tried it with larger parameters as well while driving) but it doesn't really return me periodic location fixes. It would return a location fix right away when request starts then sometime return 1 location fix few minutes later that but then for up-to an hour it won't return a location fix.
LocationRequest locationRequest = LocationRequest.create();
int priority = PRIORITY_BALANCED_POWER_ACCURACY;
locationRequest.setPriority(priority);
locationRequest.setInterval(localInterval); //set to 6 minutes
locationRequest.setFastestInterval(localFastestInterval); //set to 3 minutes
locationRequest.setSmallestDisplacement(smallestDisplacement); //set to 10 meters
locationRequest.setNumUpdates(numUpdates); //set to Int.MAX_VALUE
locationRequest.setExpirationDuration(expirationDuration); // set to Long.MAX_VALUE
LocationServices.FusedLocationApi.requestLocationUpdates(locationClient, locationRequest, pendingIntent);
If I set displacement to 0 then I get periodic location updates. Any idea what is going on?
After long exhaustive testing & experimentation I've found that if you don't call setFastestInterval you will get periodic updates exactly according to the interval set with setInterval.
However as other applications can cause location fixes to be delivered very fast to you so just put a check for ignoring location fixes delivered faster than a certain threshold of time passed.
According to documentation: If setFastestInterval(long) is set slower than setInterval(long), then your effective fastest interval is setInterval(long) but that doesn’t happen: e.g. setting following parameters should give you a hard location fix every 1 minute but it does not (on Marshmallow at-least):
interval = 1 min
fastestInterval = 20 min
displacement = 0
If anyone can disprove my findings with a piece of code that would be great.

Android Sensor Data Collection is not working properly

I developed a Data collector which collects data from Accelerometer, Gyroscope, Magnetometer and it worked fine for a while. Then I added Linear Acceleration to it as well (After 4 months, this week). Now both the version are behaving very strangely. Sometime they log the data perfectly when I do some physical activities like walking etc. However, sometimes it doesn't update sensors values and just repeat old values i.e each sensor value is updated lets after 5 seconds, 2 sec etc randomly and I need a sampling rate of 50 samples per second. I experimented with 10-15 participants and all my data was invalid because of this. The strange things is that the same app has worked perfectly before. I can't find any problem in it. I am placing some of the snapshots here. May be if someone can point to any bug or something ?
The buffered Writter:
FileWriter fow;
BufferedWriter bow;
extfile = new File(extfilepath, message + ".csv");
fow = new FileWriter(extfile);
bow = new BufferedWriter(fow);
This bow.writer is then being used in timertask thread to log data every 20 milliseconds.
Can anyone please comment or help me with this ? This weird behavior of this app is beyond my understanding.
Check that you have a wake lock acquired if your application goes to background. I've used PowerManager.PARTIAL_WAKE_LOCK successfully in a data collection application.
When your display turns off, your application is at least paused (and system might even stop it). The partial wake lock "Ensures that the CPU is running; the screen and keyboard backlight will be allowed to go off." So reading between the lines it means that otherwise your CPU might go to sleep for small periods of time in order to save power.
Did you forget to paste in:
else if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION){} ?
Are you using the accelerometer data, then subtracting gravity?
OK. What's your code look like to call the timer?? Something like this?
Timer updateTimer = new Timer("linear accel");
updateTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
updateGUI();
}
}, 0, 100);
}
private void updateGUI() {
runOnUiThread(new Runnable() {
public void run() {} } ?

How can i stress my phone's CPU programatically?

So i overclocked my phone to 1.664ghz and I know there are apps that test your phone's CPU performance and stressers but I would like to make my own someway. What is the best way to really make your CPU work? I was thinking just making a for loop do 1 million iterations of doing some time-consuming math...but that did not work becuase my phone did it in a few milliseconds i think...i tried trillions of iterations...the app froze but my task manager did not show the cpu even being used by the app. Usually stress test apps show up as red and say cpu:85% ram: 10mb ...So how can i really make my processor seriously think?
To compile a regex string:
Pattern p1 = Pattern.compile("a*b"); // a simple regex
// slightly more complex regex: an attempt at validating email addresses
Pattern p2 = Pattern.compile("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b");
You need to launch these in background threads:
class RegexThread extends Thread {
RegexThread() {
// Create a new, second thread
super("Regex Thread");
start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {
while(true) {
Pattern p = Pattern.compile("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b");
}
}
}
class CPUStresser {
public static void main(String args[]) {
static int NUM_THREADS = 10, RUNNING_TIME = 120; // run 10 threads for 120s
for(int i = 0; i < NUM_THREADS; ++i) {
new RegexThread(); // create a new thread
}
Thread.sleep(1000 * RUNNING_TIME);
}
}
(above code appropriated from here)
See how that goes.
I would suggest a slightly different test, it is not a simple mathematical algorithms and functions. There are plenty of odd-looking tests whose results always contains all reviews. You launch the application, it works for a while, and then gives you the result in standard scores. The more points more (or less), it is considered that the device better. But that the comparison results mean in real life, is not always clear. And not all.
Regard to mathematics, the first thing that comes to mind is a massive amount of counting decimal places and the task to count the number "pi"
OK. No problem, we will do it:
Here's a test number one - "The Number Pi" - how long it takes your phone to calculate the ten million digits of Pi (3.14) (if someone said this phrase a hundred years ago, exactly would be immediately went to a psychiatric hospital)
When you feel that the phone is slow. You turn / twist interface. But how to measure it - it is unclear.
Angry Birds run on different devices at different times - perhaps test "Angry Birds"
We think further - get a couple more tests, "heavy book" and "a large page."
algorithm of calculation:
Test "of Pi"
Take the Speed Pi.
Count ten million marks by using a slow algorithm "Abraham Sharp Series. Repeat measurements several times, take the average.
Test "Angry Birds"
Take the very first Angry Birds (not required, but these versions are not the most optimized)
Measure the time from launch to the first sounds of music. Exit. Immediately run over and over again. Repeat several times and take the average.
Test "Large Page"
Measure the load time of heavy site pages. You can do it with your favorite browser :)
You can use This link (sorry for the Cyrillic)
This page is maintained by using "computers browser" along with pictures. Total turns out 6.5 Mb and 99 files (I'm still on this page in its stored version of a small sound file)
All 99 files upload to the phone. Turn off Wi-Fi and mobile Internet (this is important!)
Page opens with your browser. Click the "back" button. And now click "Forward" and measure the time the page is fully loaded. And so a few times. Back-forward, backward-forward. As usual, we take the average.
All results are given in seconds.
During testing all devices that support microSD cards, was one and the same card-Transcend 16 Gb, class 10. And all data on it.
Well, the actual results of the tests for some devices TEST RESULT
https://play.google.com/store/apps/details?id=xcom.saplin.xOPS - the app crunches numbers (integer and float) on multiple threads (2x number of cores) and builds performance and CPU temperature graphs.
https://github.com/maxim-saplin/xOPS-Console/blob/master/Saplin.xOPS/Compute.cs - that's the core of the app

Categories

Resources