I do Pedometer app for android. The principle of operation as follows:
When you first launch the app, runs a service that runs in the foreground mode. Program prompts the user for Google account to login. If everything is fine then created GoogleApiClient object. Then in case of successful connection is created Fitness.SensorsApi in which I ask only in the number of steps of the system. Since I keep a not a lot of data, instead of a database I use SharedPreferences, and write new data there. If application is running, mainActivity connect to SharedPreferences every second to display the new values on the screen. All work is not bad. But sometimes, cease come on the number of steps. This may occur during the day sometimes it happens after the reset counters every day at 00:00 and sometimes a few days to work without problems. Helps only a complete restart the application.
And several times was that the data is not displayed on the screen, but the service has worked and recorded data.
In this case, after application restart I immediately received the data for the entire period (hung screen). The service itself is 100% live, because I send a message in the log every 5 seconds.
If someone is faced with a similar, please help, what could be the reason. Can GoogleApiClient loses connection or something else. How to track down an error? I will be very grateful.
Check this documentation of Google Fit on how to connect your Android app in Google fit. Make sure you properly setup this guide in your project, especially the Step 5 in where you Connect to the fitness service. For more information, check this SO question.
Here is the sample code on how the Sensors API should be accessed from the Fitness entry point.
GoogleApiClient client = new GoogleApiClient.Builder(context)
.addApi(Fitness.SENSORS_API)
...
.build();
client.connect();
PendingResult<Status> pendingResult = Fitness.SensorsApi.add(
client,
new SensorRequest.Builder()
.setDataType(DataType.TYPE_STEP_COUNT_DELTA)
.setSamplingDelay(1, TimeUnit.MINUTES) // sample once per minute
.build(),
myStepCountListener);
For additional information, check this links.
GoogleApiClient
FitnessSensorService
Related
In my app, I want a worker to request my server every 1 minute using ( PeriodicWorkRequest ) whether there are new messages for the user.
The transmission is therefore kept very small and always contains the same json object that contains the important values. This looks like this:
{"1":**7**,"2":**0**,"3":**215**,"4":**0**}
In the WorkManager documentation, a minimum period of 15 minutes is specified for the periodic request. but not every app uses "firebase" and still gets all messages directly.
especially the server query is important when the app is closed. Are there any exceptions or other alternatives?
I've been looking for a lot but haven't found a solution so far and hope someone can help me.
I am in the process of creating a custom Phonegap plugin for Android that monitors location both when the app is in the foreground and when it is backgrounded. Google documentation on using the FusedLocationProviderAPI is remarkably clear. The process I have worked out thus far is as follows
Ensure that the API is available
GoogleApiAvailability api = GoogleApiAvailability.getInstance();
int code = api.isGooglePlayServicesAvailable(ctxt);
return (code == ConnectionResult.SUCCESS);
Define a LocationListener with assigned callbacks to handle the results retured by the requestLocationUpdates method.
Create a LocationRequest
Here is where things become slightly unclear
setInterval - the interval at which the app wants location updates
setFastestInterval - the interval at which it will consume updates if available.
setSmallestDistance & setPriorty - clear enough
setNumUpdates - how this works is not clear to me. Reading between the lines I am assuming that if I use setInterval(60000) and setNumUpdates(1000) the system will keep sending back location updates for the next 6000 minutes or until such time as the app is backgrounded/shutdown or I/the user cancels location updates.
But then this begs the question - what does the app need to do to be a good citizen. I am assuming that would have to be something like this
Record the PendingResult being returned by the requestLocationUpdates call.
Detect when the onPause event occurs
call PendingResultt.cancel() prior to letting the app go to the background
I'd be much obliged if someone could comment on the correctness of this workflow.
A related issue - The documentation for PendingResult states
It is the responsibility of the caller or callback receiver to release any resources associated with the returned result.
It is not clear to me what resources they are talking about here. The LocationListener.onLocationChanged event returns a Location object which I assume will be garbage collected when it goes out of scope. Presumably the PendingResult being returned by requestLocationUpdates should be canceled and then set to null when the app goes to the background. Is there anything else one needs to do by way of releasing resources?
A few hours later
I created two versions of my test app
App 1:Sets up the LocationRequest with setNumUpdates(10000). Pops up toasts on location change in the form App 1:Location is...
App 2:Sets up the LocationRequest with setNumUpdates(1). Pops up toasts on location change in the form App 2`:Location is...
I had the two apps running simultaneously and simulated position changes with the help of a really neat little app called FakeGPS. Both App1 and App2 provided me with an update when I did my first fake location change. However, all subsequent location changes were reported only by App 1.
By inference then setNumUpdates provides a mechanism for polling for updates periodically. What is slightly confusing is that the updates continue even after the app is backgrounded - though I assume that this is largely because it is at the mercy of the OS which will kill it when it deems fit.
However, all of the above is based on empirical testing. I find surprisingly little on the setNumUpdates setting.
To your question, Is update continue even if app is in background:
Ans: What ever be the case setNumUpdates is 1 or x, when your app is in background and is still registered to update, you will get the updates, unless the OS has killed your app, for memory.
The only difference that setNumUpdates does is, as you said correctly, if its set to 1, it will give only one update, unless you has reregistered again.
Link has sufficient definition for setNumUpdates
https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#public-methods
I have read the GCM(Google Cloud Messaging) guide. It is written that on failure of registration client to GCM, we should retry the registration process. Google advices about exponential back-off: "the client app should wait twice the previous amount of time before retrying".
Why should the client app wait twice the previous amount of time before retrying?
Let's think this scenario;
My client downloaded the app.
Client didn't open the app until the night.
Client intended to open the app before sleep.
The app was started and the client used the offline features.
Client didn't have internet connection in this time.
So, my app would try to register the client to GCM all night until the client would have internet, exponential back-off time reached some hours or days.
So, isn't it a bad practice? Why does google advice this? I think, developer should set a maximum(limit) time to exponential back-off time, at least.
GCM Guide:
https://developers.google.com/cloud-messaging/registration
As par link you gave, I found below sub link.
ExponentialBackOff
Please read it to understand the process better.
You try certain times(or till reaches max interval between two requests), and it needs to stop there. Then it will be in cycle again when user uses the app or you gets Internet_state_change event.
Example from the link :-
The default retry_interval is .5 seconds, default randomization_factor is 0.5, default multiplier is 1.5 and the default max_interval is 1 minute. For 10 tries the sequence will be (values in seconds) and assuming we go over the max_elapsed_time on the 10th try:
I have an application with list of data that I get from server with http request. Now I want to make a notification when new data is available and I assume that it can be achieved with service.
Is that a good practice? Is there any limitations for number of requests made from service?
What I want to achieve is something like gmail application. When I get a new email, notification is shown.
I want my app to be as up to date with data as possible, but I understand that making requests every 5 seconds might be too much.
I am open to all alternatives and various ideas how to do that.
Not sure if you really need to pull data every 5 seconds. Of course, it is too much. You have two options:
Use GCM as #duynt suggested in comment. Follow Try cloud messaging for Android if you've never used it. This way you don't need to worry managing your service locally but whenever there is a latest data available, you will get notification so you can place request to get that and update in notification.
GCM needs An application server that you must implement in your environment. This application server sends data to a client app via the chosen GCM connection server, using the appropriate XMPP or HTTP protocol. Take a quick look About GCM connection server.
For any reason if you would like to pull data from your local Android Service component, you can still do that. But 5 seconds frequency is really high. As majority of the times the device is in sleep mode, you have to wake up the device then send request to pull data. Waking up device every 5 seconds means a battery drain along with consuming data.
If you still want to proceed with local service option by increasing the frequency, make sure you follow How to use http in sleep mode and implement it that way otherwise it wont work in deep sleep mode.
You have to make a decision now.
I've written a small test application which works as a simple chat room using Nearby.MESSAGES_API.
When I subscribe I find that I receive a number of older Messages in my MessageListener (in onFound). If I disconnect and then reconnect (eg. switch to another application) I find that all the messages come through again. Is this meant to happen?
I have changed the application to include UUIDs in my messages and keep a stash of them to check whether I have received the message, but that may not be a good idea from a memory point of view (although I could put them in a database).
I don't understand how the "session" side of Nearby Messages works.
In Google Play Services 7.8 the "sessions" are internally divided into ten minute buckets. You're not the first person to be confused by this, we're looking at options to do this differently in the future. No promises, but we recognize it's an issue.
(I work on the Nearby API)
The issue was that publishAndSubscribe is called when onConnected is called. The issue with this is that onStart attempts to reconnect so publishAndSubscribe needn't be called again.