We want to track some data for water sports, so something that is really important for us is to store information in the DataLogger module.
We noticed the logger stops approximately one minute after we lose the Bluetooth connection with the device. So, my question is, is there a timeout or something related to the DataLogger module that forces to stop the logger? Is there any way to avoid this behavior? If there is a constant, where is it located? We need to keep logging as much as the storage permits. What is the best way to do it?
My guess is that you are using the default app that Movesense sensor comes with (hr_wakeup_app or similar) that goes to power off after 1 minute without Whiteboard/BLE connection. If you flash your sensor with plain_app or some other app that never shuts down the logging will continue.
We are in process of improving the sample app to take into account the running DataLogger when deciding to go PowerOff, but that is not out yet.
Full disclaimer: I work for the Movesense team
Related
I am developing an android app for our custom healthcare hardware device that, among other things, should receive data from 5 sensos. The sensor data are sent via Bluetooth and is received using delegates that fire at 64Hz, 1000Hz, 4Hz,4Hz, and 32Hz respectively. I have successfully created an app that received the sensor data. Unfortunately, at the moment, the sensor acquisition runs on the main UI thread. This is unacceptable because it is expected that the app should keep recording the data uninterrupted throughout the day. After spending some time exploring my options, many tutorial online suggest to use a service to achieve this. However, there are many types of services (IntentServices, foreground services, background services...) to choice from and I am not sure what is the best approach. Also, my app will target android O and it seems that using background services are somehow discouraged. Would any experienced android developer gives some suggestion on how to tackle this problem? Please note that, at the moment, this is just a demo and the battery and other resource usage is not an issue.
Best approach for things that you want to achieve is to use Foreground Service, that will keep connection with ble device and get notifications from gatt services. Also you will need to use WakeLock to keep your service alive in sleep mode.
One year ago was making sample app for internal ble device. Check bluetooth/gatt package, was really useful such implementation.(project isn't good for production, but as sample/demo is pretty nice)
What I want to do is is there a very way to prevent user from turning off Mobile Data & Location services?
My scenario is this, I am creating a mobile application for a big project we have now. This application is restricted for the use of their employees going out of the field, now this phone by any means should not turn off mobile data and location services as I have an application service that sends constant location data to the administration API.
OR maybe an existing application that prevent native functions like this from being accessed. This may sound crazy but I just have thought if there is something like this.
Thank you!
I hope someone could enlighten me.
No, you can't do that.
Even if you could, it would not solve anything, because there are many other reasons why those services may not work. For example when one is driving through a tunnel and there is no signal or out of town there may sometimes be no signal or the network may be overloaded or something. So you can't rely on these services anyway. Intermittent loss of connectivity is pretty common in mobile devices. You will have to take it into account (log data and send them when you succeed in reconnecting).
If the users need the application, and connectivity in it, to do their job, they won't be turning it off, because they need it. So all that is needed is to create a notification when connectivity and/or location is lost so the user can do something about it if:
the application fails to connect when they turn it on at the start of their shift or
the application looses connection for extended period of time for whatever reason.
And of course if there is somebody in the company using the data (some dispatcher), which I suppose there is, they will notice the particular worker is not sending anything and will try to contact them by calling or something. These should take care of mistakes and faults.
If the users don't need it and it is intended to spy on them (so they may have a reason to disable it), it is probably illegal anyway.
You cannot prevent user from turning off Mobile data. But you can simple record location in a file with time while data is off and send it immediately after user turn on the data.
That is impossible unless the device is rooted.
And it makes perfect sense, because that would compromise the user's experience of Android and/or security.
You must anticipate circumstances like the user turning off the data or connection and act appropriately (for example gracefully stall your connections with the internet and resume them later, inform the user that his device has been disconnected from the internet and that your application requires internet access etc...).
I want to send to my server every 24 hours how many steps I walked. I have an AlarmManager to go off alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),1000*60*60*24, pendingIntent1)
Now this is where I am stuck... how should I measure the daily steps?(remember I need to send this in the background) I can use this a service that could override this function public void onSensorChanged(SensorEvent event) this doesn't seem so accurate since my Service could be destroyed(and battery will get drained very fast).
Or
I can try and use the Google Fitness but I need to request connection from user every time I try to get the data mGoogleApiClient.connect()(I need to get this data in the background)
Anyone have experience doing this?
onSensorChanged() does work properly. Sensor should be good enough in the device that it should not count vibration as a step. But the only problem while capturing the step count with onSencorChanged() is that if we shake the device it count it as a step. To avoid this, most of the solutions will implement tracking the location and send to the backend so that backend would calculate if the device has actually moved. It sends the actual step count back to device which can be displayed.
Leaving this, for your case if you think service-gets-destroyed is your concern, you can restart it in a guaranteed way. See my answer to Unable to restart the service. This explains how to restart service using UncaughtExceptionHandler when app is killed through recent tasks or by system in low memory situation. Your service does not run in deep sleep mode. You can get it run using WakefulBroadcastReceiver and startWakefulService().
You should reduce the frequency of sending data to backend to as less as possible to avoid draining battery.
I am not sure of GoogleFit API. Research on this for yourself and you can add answer to your question. ;-)
UPDATE:
Read Suspend Mode about sensors in android.
Nice point to note :
“Suspend” is a low-power mode where the SoC (System on Chip) is not
powered. The power consumption of the device in this mode is usually
100 times less than in the “On” mode.
Let me summarize my problem and what I would like to achieve.
I have a SonyEricsson X10i phone with Android 2.3.3. I realized that sometimes my phone not receiving calls even if it indicating full coverage. I checked myself in the MSC/VLR and it indicates that I registered and my phone is currently active (and also there is no IMSI DETACH flag), so it should working correctly (only the last Activate Date is a little bit old ~couple of hours, which can be good as well, without SMS/Call/Location Update), as I mentioned before the phone indicates full coverage and it seems it’s on the network. But when I tried to call it I only reached the Voice Mail.
In the MSC/VLR I see No Paging Response Cause for the call, but the phone does nothing. I tried with other SW version (4.0.3 ICS), but the same result. But I not noticed similar behaviour with a different handset (same type).
Sorry for the long summary.
So because what I described above, I ‘m trying to write an application/service which will perform GSM/UMTS location update in 15-20 minutes, but I couldn’t find any kind of procedure in android.telephony.gsm.GsmCellLocation, android.telephony.TelephonyManager which will do this for me.
My other concern is the
getState()/setStateOutOfService()/ setState() procedures from ServiceState class…
It seems they not really working. For example, when I first call the getState() I always get back STATE_OUT_OF_SERVICE, which is not true…
When I’m set the state to STATE_POWER_OFF or STATE_IN_SERVICE, at least I get back that state from getState() afterwards, but the phone does nothing for that . (Not even indicate out of coverage,etc…)
Every suggestion/comment are welcome.
I have also seen this problem many times (2 phones from the same manufacturer as yours). From your question, I understand that you want to force the phone to send an MM periodic location update (which it should be sending anyway).
This is too low level, and there's nowhere you can force this directly in the programming interface. The mobility management procedure is part of the phone stack, and is specified in detail in 3GPP TS 24.008, available from www.3gpp.org. Paragraph 4.2.2 defines when the phone is supposed to send these location updates.
The only other thing would be to try by indirect means to force the phone into a condition where it would send a location update. You might be able to do that by trying to select another network manually. If it's successful, and you then manually re-select your home network, then you would trigger a location update. If it's rejected and falls back to its home network, then I think a location update would be triggered as well.
But there would also be small costs to this - battery use while it does a networks scan, and time lost while it scans and does manual network selection.
(My personal experience is that the lost calls don't happen often enough to justify this.)
We have an android(or iphone) client we are developing. The client allows the android user to send entries to a server which we also develop. If the client does not have data services (GPRS) at the moment the user sends the entry to the server, the client also supports saving the entry to an offline database and sending it later to the server.
One important aspect of the whole process is accuracy of the timestamps on which the user sent the entry to the server (whether the entry is made in real time or sent by the client from the offline database)
When available on the client, we get a GPS location and are able to use the GPS timestamp to send that to the server (or save the GPS timestamp on the offline DB and send it later to the server). However if the user has turned off the GPS (and all other location services), the device will not have a GPS fix and therefore the server can not determine accurately when an entry was made.
We can not use the local device clock as the user may change the clock to make entries on different times than they actually occurred (these entries are part of the users salary so he might have an interest to "fix" them).
So basically I am searching for a way to determine as best I can the time some entry was made when I can not trust the internal clock of the mobile. The algorithm should support both entries sent in real time or entries sent from an offline DB. the algorithm should also support cases where the user changes the time of the mobile, turns the mobile on/off, turns the GPS on/off while the application is running on the mobile etc...
Few ideas that I thought of:
Although I can not trust the mobile's time, it can still perform as a stop watch:
Have a class that will loop until the application exists, the loop will sleep 1 second and increase an internal clock variable by 1 second. On every GPS location my code gets we update the internal clock variable. This way I have an absolute clock that came from outside the device (from the GPS) and when the client sends an entry to the server, we can use the internal clock as an absolute time.
PROS: the user can not modify this clock as it is only updated when we get a location from the GPS
CONS: the application needs at least one GPS fix before the user can make any reliable entries
I can take advantage of the fact that the server has an accurate clock which is correct. If the client would send to the server info that the age of the entry is 10 minutes, the server could use its internal time and know the exact time the entry was made on.
The biggest problem is how to know the entry age? I thought about saving the entries to the offline DB with an age of 0, then every 1 second increase the age of the entry in the DB. The problem is that if the app is closed and/or the device is off this will now happen
This is where I am currently stuck. Any ideas on how to solve this are more than welcome
Thanks
Here's how I handle this issue for iPhone. When the app starts, I call my server and ask for the current GMT time (you could also call a public NTP server if you preferred). I then compare it to the system time. If it is different by more than X then I popup a message saying, sorry your system time is wrong so you can't use the app until you fix this. I then monitor for the user changing the system time while the app is running and if they do that, then I do the compare again (and popup the error message if the time is off by more than X). This ensures that their system time is always correct (within some reasonable allowance) and you can trust [NSDate date]. However, this solution does require a valid network connection. If this solution works for you, I can post the sample code.
i think i am going to combine Jules and Joel's answers into one solution which will provide for my needs the best solution:
since the user might change the clock when the mobile doed not have GPRS, just detecting the time change event will not help us as we can not validate at that moment the new time is correct.
As Joel recommended i will pull the time from my server when my application is started (at that point i still must have communications with the server or else my application will not start). The time pulled from the server along with the current device upTime will be saved.
when the user wants to make an entry i will calculate the current time using (Server Base Time + Current UpTime - Base UpTime). this way i will have an independent source of time regardless of the current clock of the device
this will defenitly work on android
on iPhone we will try to use something out of http://www.cocoadev.com/index.pl?FindingUptime to get the upTime
Jules & Joel, thanks for your answers!
Look into android.os.SystemClock. Specifically, elapsedRealtime() returns a time since the phone was switched on, which is not affected if the clock is changed by the user.
You can correlate times in event the phone is switched off by having code that runs when it is switched on and checks the realtime clock. As the clock can't be changed when the phone is off, I suspect you could use this to put together a system that will catch any simple attempts at cheating. (If the user roots the phone all bets are off -- they could modify the behaviour of the APIs from under you).
Running code every second will kill the phone's battery life. Most phones would be unlikely to last a day if you did this.