I am eager to know how ActivityRecognition which is in GooglePlay Services works?
I think activities are recognized by accelerometer data.Is it right?.Please give me the details how it goes?
I was looking for this answer also and your post was one of the top results on Google. I did a little more digging and found this https://developer.android.com/reference/com/google/android/gms/location/ActivityRecognitionApi.html which says:
The activities are detected by periodically waking up the device and reading short bursts of sensor data. It only makes use of low power sensors in order to keep the power usage to a minimum. For example, it can detect if the user is currently on foot, in a car, on a bicycle or still.
It doesn't explicitly say which sensors it uses, but we can safely assume that accelerometer is one of them. Since it says sensors (plural) it evidently uses others. But since it says low power you don't have to worry about it using GPS or anything like that. However, it does say that it wakes the device up which would bring it out of its super power saving mode. So, even though it is low power you still may not want it running every 5 seconds all day long. The documentation further down says:
A common use case is that an application wants to monitor activities in the background and perform an action when a specific activity is detected. To do this without needing a service that is always on in the background consuming resources, detected activities are delivered via an intent. The application specifies a PendingIntent callback (typically an IntentService) which will be called when activities are detected. See the documentation of PendingIntent for more details.
Related
I want to display health-service data such as step, pace, etc in AmbientMode.
But HealthServices(using ExerciseClient https://developer.android.com/training/wearables/health-services/active) seems to go into Sleep state when entering ambient mode.
I tried using AmbientUpdate with AlarmManager, but HealthServices did not wake up. Please let me know if you have a good way to solve this problem.
I want to change the data of the screen in the middle in AmbientMode.
Please help me.
Please add the relevant code that shows how you are setting up the connection to HealthServices. It will make it easier for people to help you. In the meantime, here are some suggestions for you to look into:
ExerciseClient will only send you data when you have an active workout with a listener set. It sounds like you do get updates in interactive mode so I'm going to assume that this part is working for you. Make sure that you don't accidentally end your workout e.g. in onPause or some other life cycle method/function that is called when the app loses focus (this happens when the device enters ambient mode).
Make sure that you have a Foreground service set up as outlined in the spec, and that you have the required permissions. Otherwise, you might run into issues when the device enters ambient mode and your app is sent to the background.
Use a continuously-running ForegroundService in conjunction with ExerciseClient to ensure correct operation for the entire workout.
Using a ForegroundService is essential when requesting location data. Your manifest file must specify foregroundServiceType="location and specify the appropriate permissions.
Note: If your app experiences AUTO_ENDED_PERMISSION_LOST errors, this is likely caused by a missing ForegroundService with appropriate location permissions.
Worth noting is that when the device is in ambient mode you will get data less frequently. HealthServices will do more batching of data in order to minimize the impact on battery life. The frequency and batch size varies based on the type of metric you are requesting. Make sure that you allow enough time for data to come through, and that you are parsing the batched data points correctly.
Make sure that you give enough time for the ExerciseClient to flush all data points when you end your workout or you might lose data.
Finally, if you're not actually tracking a workout, you might be better off using the PassiveMonitoringClient.
To receive data updates in the background, use the PassiveMonitoringClient. Your app must have a BroadcastReceiver declared in its AndroidManifest.xml. When you register to receive updates from Health Services, they will be delivered to this receiver.
I'm developing a set of complications that I would like have regardless of the other installed apps and watch faces. Yes, at some point I am reinventing the wheel, but at the same time I am using this as a learning project. This will also ensure that I always have all the complications I use, available and that they all have the same format and style, instead of relying on 3rd party apps to provide them separately.
The set will have complications for Heart rate, gps coordinates, hours, minutes, seconds, dd/MM date, dd/MM/yy date, battery, etc.
When I started programing all this I found several problematic pieces (most likely because this is the first time I develop complications, or an app for android wear for that matter) and hence this question.
Note that some of this behavior might be specific to the Huawei Watch 2 LTE.
1) Upgrade interval push / pull.
I understand complications as data providers, whose only responsibility is to provide the data to whatever watch face is calling them. This means that we are not certain (and we rely on the watch face developer) to know about the complication and request updates accordingly. This turns some complications completely useless if not updated in time (for example display the Seconds). Could also leave to complications displaying old data (for example old GPS coordinates, old heart rate bpm).
So ok, I decided to implement ProviderUpdateRequester with the AlarmManager to push data to the watch face. The problem again, is with complications that should happen faster, like seconds, as Android will block pending intents if they are schedule too often. So in order to get around that, I decided to use Android handlers within the same service instance, which turn out to be not a good idea because of the next topic.
2) Complication lifecycle
By debugging, I found out that the instance of the ComplicationProviderService object that is executing onComplicationActivated, onComplicationUpdate, onComplicationDeactivated can be different. This means that this is not a sticky service (single instance) that will be always running, but every update creates a new instance of the service. This is problematic because of heavy initialization complications: for example GPS, or Heart Rate monitor that need to listen for new values and it might take a while to retrieve the first value. And also, for those complications that can't rely on AlarmManager, and/or need to keep some sort of state between updates executions.
3) Display aware service
To get around the previous point , let's say you have static variables on your complication service , which are initialized onComplicationActivated and disabled at onComplicationDeactivated. For example, this could be getting a reference for the LocationProvider and starting listening for location updates. This will ensure that each invocation to onComplicationUpdate will not have to perform the heavy/cold initialization and will have access to the most up-to-date data.
However, this also means that your logic will executed regardless if onComplicationUpdate is called or not.
When in ambient mode (or screen off) the watch face can decide not to update the complication by not calling onComplicationUpdate, but it's not aware of our static logic, nor the ComplicationProviderService has a callback invocation for when the screen goes into ambient mode or turns on/off. This is a problem, because in our example, if the screen is off, we are still going to be listening for GPS coordinates, and most likely draining the battery.
Sure, we can deal with this by using a combination of BroadcastReceiver (Intent.ACTION_SCREEN_ON/OFF) and DisplayManager.DisplayListener, but then again, not sure if i'm taking the correct path here, because this will mean that we are now creating services that need to be statically aware of the state of the display.
4) Detect screen on/off
The BroadcastReceiver for Intent.ACTION_SCREEN_ON/OFF works as expected when ambient mode is disabled, but it doesn't it's enabled. When ambient mode is enabled, Intent.ACTION_SCREEN_OFF is dispatched when going into ambient mode, but Intent.ACTION_SCREEN_ON is not dispatched when coming out of ambient mode. While a bit more complex, this can be accomplished by using DisplayManager.DisplayListener to get updates on the onDisplayChanged callback.
TL;RD
1) How do you ensure watch faces display your complications in a timely manner to always have correct and most up-to-date information?
2) How do you deal heavy/cold initialization of a ComplicationProviderService if everytime onComplicationUpdate is called the service instance is different?
3) Is making a long running service display-aware something crazy to do?
4) Technically the screen is still on when in ambient mode, so why is Intent.ACTION_SCREEN_OFF being broadcasted? Why isn't Intent.ACTION_SCREEN_ON/OFF symetrical when ambient mode is enabled?
5) Maybe complications shouldn't be use for exposing realtime information?
Thanks a lot
A couple of things to unpack:
Complications are not meant to be updated frequently (think minutes, not seconds) - this is to preserve battery.
ProviderUpdateRequester is designed more for (on average infrequent) irregular updates like messages coming through a chat app.
Time dependent complications - there are not an "update" as such but Wear provide ways for developers to count up / down from certain time and for displaying date related field (world clock, day of the month) without the provider sending the system updates all the time. For this last one, please refer to docs for ComplicationText.TimeDifferenceBuilder
and ComplicationText.TimeFormatBuilder.
For your use case, a more appropriate thing maybe to consider an always-on app. User uses it for a certain time period for a specific purpose so they explicitly agree to use to use more battery to track things like GPS or heart rate. For example, a lot of running apps on Wear do this.
I hope this helps.
I'm using accelerometer and gyroscope in my Android app. I want to profile my app for its power consumption. Lets say the app, read these two sensors every 100 millisecond, add all its three axis (x,y,z), and store them in a file.
Now I am not sure if these two sensor are always on or not ? If yes, then most of the power consumption will come from how I use or process these sensors' values in my app. So I have the following questions.
Are these two sensors always on or active ? (If so, any reference).
What does then the register and deregister does ? If they are always on,
then it won't make any difference to deregister them, at least in
terms of power consumption.
Background or reasoning behind these questions:
Gyroscope consumes more power than accelerometer (based on my analysis, its 4-6 times higher). Now if these sensors are always on then I can use them both in my app because my app is not the reason for the power consumption caused by the active status of these sensors. My app will be responsible for the power consumption due to the way I use these sensor values, and how often I read them. However, if these are disabled or off (consuming no power at all), then I have to make a careful decision if I want to use them or not because when I register them, then I am also increasing the power consumption due to their active status in addition to the processing their values.
Mostly as addition to the answer from Andriy Omelchenko with some more links:
1.
This is broadly and "manufacturer independent" documented in Androids Architecture Documentation in the Sensors Section. Specifically that Accelerometer and Gyroscope are handled as non-wakup sensors which report events continuously but may not wake up the SoC.
So yes, you can assume these 2 sensors are always on.
2.
Furthermore the documentation states: If an Application needs the data in background, it needs to hold a Wakelock - probably the Partial Wakelock which will keep the system from going into low power/sleep mode - such that events are processed and delivered without being dropped. Obviously this will drain the battery faster.
You could imply that registering/unregistering may have a low effect on power as long as you don't keep a Wakelock.
But in general you shouldn't assume it is useless to register/deregister sensors for power optimization - except one-shot sensors. Not only because of the power used for processing and delivery of events to apps and the possibility of keeping the system from its sleep. It is a Framework recommendation and these are normally not without cause like the use of register with report delay to make use of batching if possible. The impact may change with different hardware or other factors.
It could also be a funny bug source if - for example - you assume that data is provided depending on the Wakelock: The documentation only states that for non-wake-up sensors the driver is not allowed to hold a Wakelock and the sensor shouldn't wake the SoC. Meaning your app could be processing events in the background or not depending on device, system, installed apps and so on.
From Official site: "Always make sure to disable sensors you don't need, especially when your activity is paused. Failing to do so can drain the battery in just a few hours. Note that the system will not disable sensors automatically when the screen turns off."
"Are these two sensors always on or active?" - seems this question has no general answer because it depends on hardware. Actually accelerometer and gyroscope has low power consumption, but they support by OS may consume more battery.
"What does then the register and deregister does ?" - eliminates power consumption for data processing from them.
The accelerometer and gyroscope are not always on. That would be crazy - absolutely anything that draws power in a mobile device is put into a low power mode where-ever possible (no application is currently requesting it). Hence the need to register / deregister.
There isn't a strict specification to require this from hardware manufacturers, because this is a common sense optimization to increase battery life.
I have 2 android applications A and B, and both of them are reading gps values based on different parameters. Considering both the apps are running on the device, which of the folllowing approaches would be better?
Both A and B are to be different apps, each one with a component to read from GPS.
To develop a third application with a remote service component to transmit GPS data to both A and B
Would battery usage be minimized by going for the second approach or will the GPS component read once and serve all processes, as in the OS?
Please help
There is a very good explanation given in the Android Developers Website about Location Strategies. I would suggest you to take a look at the code examples on the page.
In both of your approaches i believe second approach is quite better because Turning on/off GPS is a quite expensive operation in terms of battery usage.
GPS’s battery draining behavior is most noticeable during the initial acquisition of the satellite’s navigation message. Acquiring each satellite takes 12 to 30 seconds, but if the full almanac is needed, this can take up to 12 minutes. During all of this, your phone is unable to enter a deep sleep. A-GPS (Assisted GPS) partially solves this, by sending the navigational message to your mobile device over your cellular data network or even Wi-Fi. As the bandwidth of either of these greatly dwarves the 50bps of the GPS satellites, the time spent powering the GPS antenna or avoiding deep sleep is greatly reduced.
Referred from this.
I think the most battery-efficient way would be to poll the GPS location with app A normally, and in app B, use LocationRequests and use setPriority() with PRIORITY_NO_POWER. As mentioned in the docs, PRIORITY_NO_POWER will make app B get updates only when another app gets GPS updates (in this case, app A!!). I haven't tried it, but it should work. It definitely saves you the hassle of an extra app :)
Some more info on Google Play Location Services here and here.
is it the same as OS gPS component will run once to serve all
One GPS serves all.
There is no half GPS saving half the power.
But there are other location providers like cell tower and Wifi locationing which uses less power.
But if you need GPS it is absolutley no difference how many apps uses the GPS service.
If GPS is enabled it uses full power.
For the sake of compatibility and function I would suggest having a third process or program which reads and outputs GPS data, as multiple processes polling data from GPS is less efficient.
It would also be faster to have those two apps read the output of a single GPS tracking app and not needing individual components in each app to do so.
For the sake of power the GPS will use the same level of power regardless, though if it's polled more often due to two applications using it then it may use more - though the amount is likely to be minimal unless there are constant requests for location.
Though this may not be the question it would be most power efficient to have the third application poll GPS at specific intervals and the applications may read from its output rather than search location every time.
Second approach seems to be more appropriate but not sure about battery drainage.It depends upon how you implement it.
Also I would suggest try to use passive providers.Refer following link help it works :)
http://fypandroid.wordpress.com/2011/04/11/298/
I am quite new to Android programming and I wonder what the best approach would be to keep information updated while the screen is off.
The specific situation is as follows:
- I use a service that extends Service and implements SensorEventListener.
- I use the accelerometer to check if the user is sitting or standing (onSensorChanged).
- If the user have been sitting for a specified time the device vibrates and beeps.
The problem is:
- The service don't update at a frequency that makes the alarm go of i time. Sometimes is is late by a couple of minutes, sometimes it just updates as I turn the device-screen on.
- The update frequency seems to vary between devices.
My question is:
- What would be the best approach to solve the problem? Maybe a service isn't the best solution.
My intention is to keep the service running a long time in the background.
Also, I do not want to use a Wake lock because of the battery (which is an important factor in the situation).
// Victor
I mentioned this problem in this blog. I had faced this problem like you. I just found a workaround which I write but it does not work every device. Device's policy for sensors depends on manufacturer and manufacturer limits sensors on cheap phones. ( I don't know why but i guess it is about battery usage)
If you want to use sensors you should use wakelock.(If there is a solution with not using wakelocks, i want to try it)