I am a complete Android programming newbie.
I have completed some tutorial examples like HelloAndroid and the HelloViews/Layouts, but that is about the extent of my Android programming abilities.
I am not the programmer on this project, I am the tester(QA) for a company that is developing an Android application that will track company owned devices every 1 minute, and send the positions back once 5 or so are stored.(Limiting mobile network usage, to conserve battery.) My company bought and pays for the android devices, and the employees are aware they are being tracked, both for safety purposes of the employees as well as accountability. Behind making phone calls and some mild emailing, this is one of the most important functions/uses of our devices.
Our biggest problem is that our application can be killed at any time by the Android OS, for any number of reasons(device resources, etc.) Right now, we have an Android service that checks if our app is running every so often and if not, it starts it back up. Once our app is running it can be in the background and request positions using a service in the app itself, then send them to our server for processing and storage.
From everything I have read about Android Development practices, this does not seem to be the most Android "appropriate" way to do this. From what I can gather, and this is fairly limited, we should have an Android service that runs in the background and requests then sends positions, but even this can be killed without notice from the OS, right?
Any advice or suggestions anyone could provide that would point me in the right direction?
It might be worth mentioning that this will kill everyones battery extremely fast... but you pretty much have it right as far as the best way to do it. If the OS does kill your app in the background, your service can just restart it.
What are your concerns, that the OS will repeatedly kill it and not allow it to do its job?
Or that the GPS locations wont be accurate? Location.getAccuracy() could help you figure out if the location is worth saving
http://developer.android.com/reference/android/location/Location.html
Related
I have a small test App that with an Android GPS API map fragment. I use FusedLocationProvider. TarketSDK=29. Using Java.
As long as the app is active it works beautifully. On locationUpdates, I add a new point to the track and everything looks great and stays accurate. The goal is to track my hike, total distance and track and show it on the map. Works great.
As soon I lock my phone or loses focus, then the updates stop and I no longer get location updates.
Solution seems to be:
Background Service (discouraged)
Foreground Service
PendingIntent
I have poured over the docs, StackOverflow, all examples/tutorials I can find, developer.android.com, etc. I have downloaded examples of the latter 2 from GitHub; they seem incredibly obtuse (probably just me).
What are the dis/advantages of ForegroundService vs PendingIntent?
How about a bare-bones example illustrating the min features of each to implement location updates while your phone is locked in your pocket or some other app is active? Just the template minimum.
I need to save the locationUpdates that occur while my app is not active or phone is locked; in order to fill in Track when activity is restored to the app.
Some simple end-to-end guidance from my working app to something that will maintain locationUpdates and save the data would be great.
Ok - I have answered my question in a roundabout way.
I had been Searching on "retrieving location updates when app is not active". This lead to the various solutions of background service, foreground service, pendingIntents, etc.
I eventually found that if you just start a Foreground Service with a Notification, even if your phone is locked or you switch active apps, your App continues to receive LocationUpdates; as the Foreground Service runs in the same thread and therefore activates your app code (if I understand the reasons why correctly).
So, I started searching on just how to start a Foreground Service. As anyone knows that has tried to figure this out lately, this has changed more than a couple times over recent versions. The online docs at developer.android.com are not up to date. You will spend a lot of time wondering why things do not work following these docs.
Eventually, with just searching on how to start a foreground service, I came across this simple and straightforward (non-youtube-video - don't you just hate those things) tutorial. https://androidwave.com/foreground-service-android-example/
I just added this code to my existing Mapping code that works when the app is active, and tested with locking the phone and putting it in my pocket and switching apps and doing the same. It appears to solve the problem.
Update: Added code to count number of location updates and average accuracy of each update holding the phone in hand, screen on and app active as the baseline. Phone locked, or App not active no difference in number of updates nor accuracy. Phone locked and in pocket, no difference in number of updates, but accuracy suffered by from an average of 10m to an average of 13m; to be expected I assume whilst in the pocket.
I currently use the Firebase JobDipatcher to perform a periodic task in the background. The problem is the background service only gets executed when battery optimization is disabled and standby state of the app is manually set to ACTIVE under developer options. Is there a way to do the background task without manually changing all this, because i cannot ask every user of the app to do so. And saw many posts that google will suspend the app if the power management permissions are requested within the app. Any help would be much appreciated.
In one word answer is BIG NO
As developers remains unhappy with such small answers, so i am starting the HUGE theory, here we go -
STRATEGY NO - 1 :
Use AlarmManager
All alarms are forgotten by the android on Reboot, so keep all alarms in app Sqlite database, implement BOOT_COMPLETED broadcastreceiver, which is still allowed to define statically & re-schedule all alarms by taking from apps database.
All your project & hard work will work as per your plan, but only on emulators
Because in real world, 99% devices are with chinese ROMs like MIUI, OxygenOs, ColorOs, FunTouchOs, .. which never triggers your apps BOOT_COMPLETED broadcastreceiver.
Because they all are ahead in saving battery life, by stopping all apps background services..!!
Nice question,:- Then why whatsapp, facebook, tiktok, twitter processes are getting executed normally...?? And why not mine...??
Nice answer,:- If Chinese ROMs disallowed above apps background services then no one will buy their devices..!! And lets do not talk about your application as it does not affect the world in any way, your app is useless ( as per chinese ROMs ) , so they disallows all other packages background tasks..!!
All Chinese ROMs never triggers AlarmManagers if the app is not in foreground. Never triggers if app is removed from recents
In short & sweet treat Alarmmanager as depriciated.
STRATEGY NO - 2 :
Use FirebaseJobScedular as you stated
If user updates Google Play Services , then system forgets all jobs..!!
Again FirebaseJobScedular was developed to run all jobs on every device in market, but as chinese ROMs never allows any processes / classes / Jobs from their own wishlist, this makes no sense again.
This library is depriciated by google now.
STRATEGY NO - 3 :
Use WorkManager, the new library which is taking place over the FireBaseJobScedular officially.
Again the same thing, WorkManager is still in development, you can use it, but the case is same that many chinese ROMs discard this libraries jobs too..!!
STRATEGY NO - 4 :
Run all time foreground service.
BOOT_COMPLETED from your broadcastreceiver start it again.
But even if you use START_STICKY, many chinese ROMs used to suspend its tasks, you can see it in foreground, but works gets suspended.
STRATEGY NO - 5 :
Use WakeLocks
But as the android version changes, it has changed to the newer newer implementational strategies in every versions
STRATEGY NO - 6 :
Programatically make battery optimisation off for your app, but google discontinues your app from app store in such case
Navigate user to battery optimisation settings intent, by opening it programatically & let him choose battery optimisations on his own, is allowed by google
But as no user is in market, who knows it, as even many developers dont know this yet, how end users can understand it..??
Again if power saving mode ( it is different than battery optimisation okay ) is made ON by user then, no way your battery optimisations is never considered.
What the ***** should i do then ...?
Nothing as developer.
Train your support / sales team to "LOCK" your app in the recents of every phone, after which, users are unable to swipe it away from the recents, even if it is swiped away, your all above strategies will work & your jobs / alarms / tasks will be executed, as it happens on your android emulator or as on stock android
Train your support / sales team how to make battery optimisations to "Do not optimise for this app" too..
It is so out of the box solution..??
Yes, it is. As in the market you will notice 1% stock android devices and 99% chinese modified ROMs
This all knowledge came to me after i lost last 9 to 10 years resolving the same problem, Hussshhhh
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)
I'm trying to implement a fast communication between two android phones at a certain moment by, preferably, going through a server (since it's easier to be consistent).
The phones have to communicate their gps locations every x seconds, with x being as low as possible, with only one of the phone having to be on the app, the other can be idle (but obviously not turned off).
The first solution I tried is a syncadapter in the app which updates every x seconds, sends requests to server writing its location in a DB, and then the other retrieves the location in the same DB.
Note : I've implemented it this way only because I already had the underlying architecture (REST API and all) beforehand, but I don't know how to do this in the real world, so feel free to cricize my initial choice and advise me on a better solution
Thank you in advance :) !
You can look at Firebase https://www.firebase.com/ which is a real time database. It does have active listeners in the sdk to get real time updates for your GPS coordinates.
The problem you mentioned can be addressed with
https://github.com/firebase/geofire-java/tree/master/examples/SFVehicles
I want to create an application, that runs in the background, and monitors the other running Apps.
Can you tell me, how do I know when an App acces to the GPS, so I can insert the name of the App and the time interval into a sqlite database?
how do I know when an App acces to the GPS
You don't, at least on a standard Android device. I cannot rule out the possibility of determining this on a rooted device or as a system app, though I am not aware of any specific options for those scenarios either.
Generally speaking, one app has no means to spy on the operations of another app. There are some specific exceptions to this, though they tend to get locked down over time.