Does Crashlytics miscounts active users on Application Class? - android

If the call Crashlytics.start(this) is on Application's onCreate() method, will it count an active user if something wakes up my application process?
For e.g. if I have a broadcast receiver or alarm, will it count as an active user if those wake up the app?
Thanks

I'd say that it does not count, but my answer is purely based on logic and common sense.
Crashlytics' recommended approach is to initialize the SDK in your Application class, so that crash logs (and every other type of info) can be collected as soon as possible in your app's lifecycle. When they introduced the Answers panel, my guess is that they figured out their way of determining what an active user is, based on a series of parameters and actions that indicates that the user is actually operating the app (which is, by the way, differs in every Analytics SDK provider, e.g. Google Analytics).
In short, I don't think that the Crashlytics.start() method immediately counts for an active user, because that would be just nonsense. But there's a quick way of determining that:
Create a testbed application that is fired up when you send a specific broadcast message
Initialize the SDK in the Application's onCreate() method
Using adb, send the broadcast message and meanwhile keep an eye on the Answers page of Crashlytics
Wait for some time (it may take some time to register the hit): is the user being tracked as active?
You can try to reach Crashlytics support for this, but I'm not sure they are going to give away this information.
EDIT
Adding some evidence I've found here:
A session begins when the app enters the foreground and ends once the app is backgrounded for 30 seconds or longer.
This leads to believe (as I wrote above) that their way of detecting an active user does not rely purely on the SDK initialization.

I guess that it should, unless it has a more complicated logic of some "actual activity" instead of just opening the app. Application.onCreate() is being called on the beginning of any Activity, Service or Broadcast of your app.
This is what is written in android documentation:
Called when the application is starting, before any activity, service,
or receiver objects (excluding content providers) have been created.
Implementations should be as quick as possible (for example using lazy
initialization of state) since the time spent in this function
directly impacts the performance of starting the first activity,
service, or receiver in a process. If you override this method, be
sure to call super.onCreate().
But keep in mind that if the app is already running the Application.onCreate will not re-run as it is already created.

Related

Android: Firebase realtime database updated when app destroyed

I'm new to firebase realtime database, and have a basic question I cannot seem to find the answer to.
I need my Android app to keep track of changes in the database, so I understand I need to use addValueEventListener, with the onDataChange method. However will the method onDataChange, be called even if the app is destroyed? I need to be able to access the changes of the information in the database even if the app isn't running in the background, (for example the user force quits the app). This is because when the values reach a certain point, I want to show a pop up notification, so I need to able to read the values even when the app isn't running.
If the onDataChange is called even when the app is in the background, will this drain battery use since the phone is always listening for changes.
Sorry for the basic question, but I couldn't find the info.
Thanks!
...when the app is dead, is the EventListener still listeneing, and will onDataChange be called?
Event listeners are only active while the context they run in is active. For listeners you attach in an activity, that means they're active while the app is running. Even then Android might kill the listeners (or more accurately: the socket they use for communicating with the server) if the user isn't actively using the app.
If you want the listener to stay active longer, you can indeed consider managing the listeners in a background service. But even there, Android might close the listener to preserve battery life. That is the one thing to always keep in mind: if your use-case interferes with the user's preference (and most users are likely strongly prefer longer battery life over any specific app feature), it's unlikely to continue working in the long run.
A better approach is to combine listeners with Firebase Cloud Messaging for sending messages. FCM messages are more likely (though still not guaranteed) to be delivered when the user is not actively using the app, and you can use them to run some code of your app when they arrive. You'll want to use FCM's data messages for this, which is how most app deliver background updates.
You can also use an FCM data message to just wake up your own code, then have that code attach a listener, and get its updates. This type of behavior is known as sending a tickle, since all the data message does is waking the application code up.

Android app lifetime: maybe it infinite?

I'm developing an app designed to transform an android phone into a remote device running without user action. At the time the app is made by an Activity that sets AlarmManager to execute a service (class inside project) every X minutes.
All this works OK, but occasionally after 5-6 DAYS continuosly running the application crashes (currently I don't know why, because i can't get the phone now). It isn't a connection problem (I know) and the phone is still running (plugged into AC). The only thing that i can suppose is that the application is down.
I don't think that this is due to a bug, because the prew debugging doesn't give me any errors.
So I must suppose that android has killed the activity (system needs more memory?) and as the image explain there is no way to back it up.
But I have a doubt: in my application the activity doesn't matter, because all the work is done by the service. The service itself is called by an Alarm Manager and in the time between two calls the service is terminated by StopSelf().
In my case the system may kill my alarm manager service schedule?
What can I do to have the service start up by Alarm Manager forever?
(ATTENTION: currently there is yet a WAKE LOCK but this consider only the execution of the service! I hope that you have understand that the service is called each x minutes by alarm manager and than terminated...i want to perform this operations for an indefinite time)
[I haven't posted the source code because is too long]
Lork,
After wrestling with a similar issues myself, I may have some pointers for you. I assume that you are using your Android device as a sort of remote ‘embedded controller’, which performs its functions with minimum user interaction. I believe that you are 95% there and just need to make some slight architectural changes. As you have not provided code, I’ll just explain in abstract terms rather than give code examples.
CommonsWare is correct that you need to use AlarmManager, but I suspect you already knew that.
A couple of background comments first, just to make sure that everything is understandable.
Alarms created by AlarmManager exist at the system level, that is they can exist beyond the lifecycle of the activity and application that created them. If you set an alarm but don’t want it to go off if your app changes state (for example after it has been destroyed), then you can cancel it using alarmManager.cancel(pendingIntent) – just create the intents and alarm manager with the same parameters and Android will match the alarm).
Similarly, BroadcastReceivers are registered at the system level (at least if they are declared in manifest.xml) and can exist beyond the lifecycle of the activity and application that created them. Again if you want to ensure that a BroadcastReceiver does not fire in response to an event occurring after your app has changed state (for example after it has been destroyed), you need to explicitly unregister in it code. If it was registered programmatically then use context.unregisterReceiver(broadcastReceiver); if it was registered statically in the Manifest its not so easy – you will have to retrieve the receiver using PackageManager and ComponentName (see: Android - how to unregister a receiver created in the manifest? ) - and remember that you will need to re-enable the receiver if you need it again.
You say you have already set up your alarm. Make sure you specify ELAPSED_REALTIME_WAKEUP or RTC_WAKUP for the alarm Type to ensure that it runs even when the phone is in ‘sleep’ mode.
You also say you have already created the associated BroadcastReceiver to handle to alarm event. The BroadcastReceiver should do a minimum of work, so you should handle any processing in a separate thread or by launching a Service. You opted to launch a Service and terminate it using stopSelf() when it has finished, so that it doesn’t use up system resources. So far so good.
This is fine when the app is running, however as you require something that runs reliably for an indefinite period, you need to ensure that you manage the 'exception' situations where it has paused, the device is ‘sleeping’, the app has crashed/terminated, or the device has rebooted (and any other exception scenarios you may think of). Here are the issues I have identified that you need to address:
First: WakeLock is only guaranteed for the duration of the onReceive() method of the BroadcastReceiver. After it has terminated, the device could go back to ‘sleep’ even if your Service has not started or even completed, so you need to create a WakeLock, pass it to the Service and release it before you stop the Service. (Note: for your application, you require a PARTIAL_WAKE_LOCK). Be very careful using WakeLocks – make sure you only hold a WakeLock for the minimum required time and ensure you release it, as it’s use can lead to excessive battery drain). See http://www.netmite.com/android/mydroid/development/pdk/docs/power_management.html for an example of using WakeLocks.
Second: If you reset your alarm in code (rather than defining an automatically repeating one), do this in the OnReceive() method of the BroadcastReceiver or as the first thing in the Service you have launched – this will ensure that the alarm repeats, irrespective of the state of the application or device.
Third: Make sure that any Contexts you use are going to be non-null values. You can dynamically fetch the context in the Service using getApplicationContext(). Otherwise this can be achieved by EXPLICITLY passing the Context from your application to the alarm and make sure it is passed all the way through the BroadcastReceiver, and associated threads and Services. If you have statically stored Context in your application so you can retrieve it anywhere, then this will return a null value if the application has terminated. If you use the Context (for example to retrieve a resource, access a database etc), and it is null, it will cause a null pointer exception and the Service or BroadcastReceiver will crash. I believe this is the most likely reason for your Broadcast receivers not to be working when your app has terminated.
Fourth: You may wish to make references to ResourceIDs (e.g. R.drawable.icon) in your Service or BroadcastReceiver fully qualified (. R.drawable.icon) or generated from the passed Context. I haven’t yet found this to be necessary, but I suspect it may be prudent.
Fifth: Implement a separate BroadcastReceiver to handle a device reboot scenario (ON_BOOT_COMPLETE event). You could get this receiver to re-launch the app if appropriate or it could launch a service to check that your app is supposed to be active, set up any required parameters and set up the relevant alarms, then terminate it using stopSelf(), or just set the alarm again and let that receiver handle it all. Remember to ensure the service has a WakeLock for its duration and to release the WakeLock when it is complete. If you don’t just relaunch the app, or a Service (declared as part of your application) then you should also statically store the correct Context as a class attribute in your BroadcastReceiver, if you need it, so that it is available to access resources.
A couple of other things you may wish to consider:
As your set up is remote, I would seriously consider storing any persistent data in SQLite database tables. This will ensure that data is recoverable between application terminations and device reboots, without having to regenerate it.
If your application communicates with a server service, consider using push notifications for server initiated communication, rather than have the app periodically poll. Push Notifications can also be used to ‘wake up and launch services and apps’, so could be used as part of a remote mechanism to query the status of the device and your application. This approach is also more power efficient and timely.
Post information to LogCat at key points in your code for debugging. If the application terminates, then adb stops tracking the source code running for the receiver and service, but LogCat continues to function, so can be used to check the path through the code and variable values.
Other people may have better ways to address these issues or some other pointers (I would certainly be very happy to see other input), but I hope these ideas are helpful and good luck!
The point behind using AlarmManager with a service is to start up a service that will run briefly, then the service goes away (e.g., an IntentService). If you are going to try to have an everlasting service, you do not need AlarmManager, and your service will be shut down by Android after some period of time.
If you rewrite your app to not need an everlasting service, but rather use AlarmManager as it was intended, you should have better survivability.
I believe that what Lork wants to achieve is similar to something I am also wrestling with.
He wants the alarm manager to trigger a broadcast receiver that will handle the alarm, even when the application it is part of, has been terminated (for example by the Android OS).
For example: The application sets an alarm, with a type of ELAPSED_REALTIME_WAKEUP or RTC_WAKUP and has a Broadcast Receiver to handle it when it fires, via an Intent which references the application context and the Broadcast receiver class. The receiver is declared as a in the application manifest.
Under normal circumstances, when the application is running or paused, when the alarm goes off, the Broadcast Receiver is triggered, waking up the device and resuming the application as necessary, and the alarm in handled.
However, if the application has been killed (for example by the OS), then the alarm will still go off (as it is still registered) but the Broadcast Receiver will not be triggered and LogCat shows a null pointer exception, (I assume because the reference to the application is no longer in memory). This will occur, even if the Context has been passed.
Am I (and I assume Lork) missing an easy strategy here? Or is it not possible? Can a broadcast receiver exist on its own and trigger the app if necessary?
One, imperfect strategy I have been toying with, is to move all the app data access into a Content Provider, and have a separate low profile app which just implements the broadcast receiver – triggering a service to do the work and accessing the application data it requires via the Content Provider. This would still be subject to being terminated by the OS, but would be less likely.

How Can an Android Application Detect Whether Any of its Activities are Active?

We have an Android app that periodically polls for data and updates the display. The polling is performed by a background thread. Unfortunately, this background thread constantly runs, even when our app is offscreen or when the device is locked, which leads to unnecessary network activity and CPU/battery usage.
So, I would like to change the app such that it will suspend its polling activities in these cases:
When none of the application's activities are in the foreground.
When the device is locked.
What is the easiest way to detect whether the app is in either of these states?
Note: The app has several activities, so I don't think it is as simple as just keeping track of the activity lifecycle events. I would have to add code to each activity to keep track of whether any of my activities are in the foreground. If that's what I need to do, I'll do it, but I'm hoping there is a simpler way.
These are some questions which are related, but which don't seem to provide a good answer:
Android: How to detect if current stack of activities (task) moves to background?
How to be notified about entering suspend mode?
Simple check for Android application backgrounding
What is the easiest way to detect whether the app is in either of these states?
For the are-we-in-the-foreground issue, increment a reference count in a static data member in onStart() of each activity, and decrement it in onStop(). If onStop() sees 0, stop the polling. If onStart() sees that you're not polling, start polling.
For the is-the-screen-locked issue, don't worry about it. The device will fall asleep once the screen times out and your polling thread will not be running. Besides, I think your activity will be stopped in this case anyway.
BTW, this is one case where onStop() is the right answer, not onPause(), so the lifecycle handoff between your activities is handled properly.
If that's what I need to do, I'll do it, but I'm hoping there is a simpler way.
That's as simple as it gets.
My intuition says that says that you're thinking about this wrong. You're right to think that you need to curtail your polling when not necessary, but how about just not polling at all? You could use a push paradigm instead (see long polling or Android Cloud To Device Messaging). If your doing this polling to keep resources in sync, you might also want to checkout the android SyncAdapter.

Android Check Application Status

I have a question about Android application status. I want to know that am I able to check whether application is alive or dead, visible or on background. I need to make a decision according to application status in my broadcast receiver.
Thanks in advance..
You determine if your "application" is "alive" by seeing if the data you loaded in your "start up process" exists. If it does, use it. If it does not, run the "start up process".
Basically, when your receive broadcast your application is guaranteed to run. That's because broadcast can not be received without application process started first. And if there were no components active (like activities) when broadcast is sent, then application process is started for the sole purpose of processing this broadcast.
As for the other part, detecting if any Activity is currently active and/or visible - I haven't seen any API calls for this. There are might be some workaround (like manually keeping the counter in a singleton), but as far as I know there is no direct support for this. Though I might be wrong.
Within Android, it is standard practise to track 'changes' to the various states. You can read more about this here. Within the specific lifecycle related methods, you can perform specific actions as deemed appropriate.

How to be notified when an activity is launched

I want to implement something that does/check some things every time an activity (or application) is lunched and goes in the foreground.
Something similar to those Application Protection solutions that you use to protect any installed applications on your phone and they intercept when an application is lunched and prompt you with a password, PIN, etc.. (example : http://www.appbrain.com/app/app-protector-pro/com.carrotapp.protectpronew)
I believe that this is the mechanism I need and those protection applications use, they have a running service and somehow (this is what I'm interested) the are notified when an application is lunched . I believe that the service from these application just poll every second what is running, this would be a big battery usage, they have somehow to be notified when this happens.
So my question is how this can be achieved?
You can use a BroadcastReceiever to be notified when a package is ADDED, REMOVED, RESTARTED, and so on. And there is the category LAUNCHER there, but I don't think there is any way to just be notified when every application or Activity starts (that seems excessive anyway, which is probably why there isn't such a way), though you might be able to parse the log as Alex suggests.
For reference, see this question: Registering my broadcast receiver to run when an app is launched?

Categories

Resources