I want my app to get updates of the current location, and act upon it. I am planning on creating a service, that will host the Google API client code and location update code.
The name though throws me off: Is google location SERVICES a service that will automatically run in the background, like the service I was to create? Or is it just a name and I should go ahead with my plan?
You're not thinking about this correctly - it doesn't matter how Google implemented it. To directly answer your question, I can say with near certainty that it's not called "services" because it's a Service - the two have nothing to do with each other. Google likely uses a whole series of Service's, but you don't have to care about that.
All that you need to know is that it works - for as long as you request updates, and obviously the frequency and accuracy will depend on the filters/providers you request, you will continue to get updates. You do not need to maintain a Service in the background to continue to receive updates. You only need to maintain a Service if you need to receive and continually do something with those updates while your app is in the background.
I will also say that this can come as a disadvantage. If you request location updates and never make the api call to stop receiving updates, you will cause your app to hold a partial wakelock on the system, and you'll kill your users' batteries. Once you've got the location info you need, make the proper call to stop receiving updates.
Think about what you need location for, how often you need it, etc, and know that Google location services will continue to call your callback object as long as it hasn't been garbage collected.
Related
Currently the Android application I have taken in charge performs a "pull" on the server every minute to recover data and update a fragment with this data. Obviously this does not work when the device switches to doze mode. So I decided to use FCM as Google recommends.
Constraints :
The user needs to know that new data is available even in doze mode.
To not change the application too much, I do not want to send the data in the firebase message but rather send an https request to the server when I receive the fcm message.
The fcm message must:
Advise the user that new data is available with a notification.
If the user presses the notification OR returns to the application after turning the screen on, the https request must be triggered and fragment has to be updated.
I will add that it must be triggered at the latest when the user returns to the application.
My solution for now
I used a data message with a high priority instead of a notification message because a notification message need the user to tape the notification to trigger action.
In onMessageReceived :
I send the notification that redirects to my application.
I send my request to the server and update my application.
Disadvantage of my solution :
If my app is killed by the system while the screen was off what's going on?
My request has a time limit to complete when the phone come out of doze mode.
Questions :
Is this solution the best possible ?
Is there another way to proceed?
Perhaps could i schedule a task that runs immediately when user resume my app in onMessage received ? But i dont know how to do that.
Use WorkManager to schedule the background work to run immediately. It will also retry until your code indicates that it's successful.
I answer myself to close the subject and hope it can help someone !
After a night ... I definitely do not like the workmanager solution. Even if in practice it can work I do not like to use APIs for unplanned uses. If google tells me that it is not garanty to launch task immediately, they are (much :)) better than me and I believe them!
In this case, I think that my task may be postponed, for example because the OS wants to group calls with other apps. There may be internal conditions i dont know about.
Especially since I found a much simpler solution.
In onMessageReceived, I use a simple boolean indicator.
In the onResume of the activity I want to update I read this indicator and I launch my request if true for example.
I no longer need a scheduler, and after all if it is not done 100% reliable, it does not matter :
If fcm could send me a message there is a lot of chance there is a network when the user turn on the screen.
Even if there is none it is not very serious since I can warn the user who can proceed otherwise (by phoning for example !!!!)
I was reading about background service limitation in Android 8 and from what I read it seems that you can't run your service in the background for a long time. This seems reasonable but because I use background service to keep connection to server - currently pooling new stuff, sending location and responses I am a bit confused. The responses are OK, I can respond only when interacting with the app, but the pooling new stuff is problematic because it needs to get an stuff from server and if something new come present the user with a notification to respond to it.
If I understand it correctly I can use JobScheduler to schedule some job every several seconds. I can basically schedule the pooling. For the background locations, well there are those restrictions so only foreground service is an option to get updates in requested time.
I will be migrating to websockets and then the pooling is off, the connection to server will be persistent and the app will get updates from server, I was planing to do this in the background service so something would receive stuff from server everytime. However it seems I can't since Android 8. How would you solve this? Should I use foreground service for location and server connection? Or is there a better way to do background networking in an android app on android 8?
Thanks
Here are a few options for performing background work on Android O:
Use JobScheduler. You already seem to have a good grasp on this one- the downside is that it is periodic, not persistent.
Use GCM/FCM or a similar push service to push data to your app when it is relevant instead of constantly holding a connection to your server.
Use a foreground service. This will allow you to continue performing your background work without your app being in the foreground, but will put a notification in the status bar to inform your user that you are doing that work.
Before you select one of these methods, you should take a moment to step back and look at the data that you need from your server and determine why you need a persistent connection and whether the first or second options might be sufficient.
If you absolutely need a persistent connection to your server, the last option is your best option. The idea behind the changes in O is to still allow background work such as what you are describing, but to make it painfully obvious to the user that your app is doing so. That way if they don't think your data is as important as you do, they can take action.
I'm developing an Android app that talks to a Play-framework app, the two apps are passing user data between one another using Volley requests, my question is this:
Is it desirable to have the Android app sync with the Play server constantly to check for changes to the user profile? (like syncing during a fragment change)
Or is it better practice to have the user on the Android app logout and back in before that changes occur.
Or is there some alternative solution that only syncs with the server if a change occurs?
I think the last option would be the most efficient and desirable, but I fail to see how could do the check without sending a request first to the server and if I'm sending a request to check for changes anyway, wouldn't it make sense to have the changes in the response.
You should not sync whenever a fragment changes. It is a waste of the user's battery and data. You also most likely don't want to force a logout/login all that often as it becomes inconvenient for the user.
If you are expecting very infrequent changes to the user profile, it might be better to send a push request from the server using GCM to inform the app that it should invalidate its local cache. Then query the server for new profile information.
If using push is unfeasible for some reason, you might want to look into using a SyncAdapter and syncing infrequently. In most cases, it should be okay if profile information is potentially behind unless the user is specifically checking the profile settings, in which case you might want to check the validity of your cache when they check their settings.
I am trying to develop a mechanism for Sync data with app & server, like Google Drive/Dropbox for one of my android based application where data are stored locally on device and I would like to sync data with server.
Ways thought -
1) Observer which looks for change and call web service
2) Background service which runs in background and check for changes
3) Set Alarm which checks at particular time and sync all the data with server
I have not started to which option to go with, I would like to get experts view on this and like to get some guidance so that I can achieve the sync mechanism in best possible way for my app.
All suggestion are welcome.
Thinking on same line as you have been,the aim should be to achieve a balance between the number of times the server is queried for same set of information AND the data consistency.
for this, I would fire a GCM message from my server to the device for which the data on the server has changed, I would maintain a count for these Update Messages(No Notification genereated). If this count Exceeds the minimum-threshold-count-value, I would immediately call for an UPDATE. Or otherwise, if this count still is less than the threshold-count-value, for a certain period, that I would call the threshold-waiting-period, then too I call for an UPDATE.
The UPDATE would be using Sync Adapters and Services. This link explains its basics.
Hope this prooves to be helpful!
...so that I can achieve the sync mechanism in best possible way for my app
Well, the BEST mechanism depends completely on what kind of application, you are developing. Also, your option 1 and 2 seems very similar to me except few implementation changes. However, how frequently your device data is changing, that also matters a lot. If you have authentication mechanism, you can configure sync up, at the time, whenever you login to your app. Like in case of confidential data, sync up should happen immediately.
If data is managed well based on authentication and authorization based on user roles or so, you also need to take care of synchronization among them. For example, one user has updated an entity which is not yet sync and another user tries to update the same, then first user will see his changes are not synced or has been lost.
The best way (means having least drawbacks) to do this would be sync up trigger at a particular interval of time OR at every login time. (still as I said, depends on your app).
Hope this would clear some or all of your doubts.
Consuming google play in-app products can easily be done from the client application (http://developer.android.com/google/play/billing/api.html#consume).
However I can't find any information about doing this consume request from a backend server. The Purchase Status API (http://developer.android.com/google/play/billing/gp-purchase-status-api.html) is designed to be used from backend servers, however it doesn't provide any methods to consumes in-app products.
Is there a way to consume google play in-app products from backend server?
It's now possible to at least Acknowledge using the Android Publisher V3 API, see:
https://developers.google.com/android-publisher/getting_started
https://developers.google.com/android-publisher/api-ref/purchases/products/acknowledge
Looks like Consume is still only possible from the client.
I'm trying to implement something that sounds similar to your approach. In our case our target audience is children, hence we're not expecting the consumer to be the person paying, and that the parent might buy several copies, one for each child. Hence the normal model (of one thing per customer) doesn't work.
As licencing (per child) is actually dealt with by our servers, any payments (we're handling them as a consumables), have to be actioned on the app, then the token passed to the server to be verified, then the server updates the licenses, and the next time the child concerned interrogates their licences, they perceive the payment to have been actioned. The app then has to mark them as consumed, even though activation is not something it has direct control of. Instead it seems the only option is to manage a table of all of the purchaseTokens, and mark them internally as consumed, and so the app has to periodically ask if any of the tokens pending for the current (google) user, need consuming, and tick them off when they do. As an extension to this, we have to over complicate the payment process by checking ourselves if the child requesting (or the google user that's paying) should be blocked from proceeding, in case they have payments that might be pending from another child.
It would be so much simpler, if google were to allow the server to mark the consumable as used, but I've yet to find a solution. Lets hope APIv4 has it.