We know it’s not business as usual right now, and we’re here to help. Check out our latest COVID resources.

We tailor each demo to your specific business needs. See it for yourself and contact us today!

Thanks for reaching out! While you wait for confirmation from an Apptentive team member, you may find these free resources to be of interest:

Guide

View resource

Guide

The Five Stages of Reducing Mobile Customer Churn

Retention is a top priority for mobile marketers. Our new five-step framework is here to help you improve your existing strategy.

Download Now

Guide

View resource

Guide

2020 Mobile App Engagement Benchmark Report

Apptentive’s annual mobile app engagement benchmark report serves as a baseline to help app publishers across categories understand their app’s engagement strengths and areas for improvement.

Download Now

We tailor each demo to your specific business needs. See it for yourself and contact us today!

Thanks for reaching out! While you wait for confirmation from an Apptentive team member, you may find these free resources to be of interest:

Guide

View resource

Guide

The Five Stages of Reducing Mobile Customer Churn

Retention is a top priority for mobile marketers. Our new five-step framework is here to help you improve your existing strategy.

Download Now

Guide

View resource

Guide

2020 Mobile App Engagement Benchmark Report

Apptentive’s annual mobile app engagement benchmark report serves as a baseline to help app publishers across categories understand their app’s engagement strengths and areas for improvement.

Download Now

Mobile Marketing

Detecting Android App Starts and Stops

Sky Kelsey  //  September 4, 2012  //  4 min read

tl;dr

Tracking app starts, stops, and uses on Android is a pain because the Android SDK doesn’t provide hooks into the application lifecycle. We’ve fixed that. We created a class you can use to accomplish this. You can get it off github at apptentive/ApplicationSessionActivity. Integration is an easy 3 steps.

An Android Shortcoming

As most Android developers have, or will come to realize, there are many desired features that the Android SDK simply does not provide to the developer. The stumbling block we recently came across was how to track Application uses.

The use case seems obvious: You want to run some code when the user starts or stops using your app. The Android SDK doesn’t provide an easy way to do that. A developer can tell when the application is launched from a dead stop by hooking into the main Activity’s onCreate() method. They can also tell when an Activity is put into the background by hooking into the onStop() method. But for apps with multiple Activities, you can’t distinguish an Activity stopping because the app is going into the background, or simply because another Activity within the app is taking focus.

Devising a Solution

I first tried to look at the Application class, to see if it had any useful methods for tracking the application lifecycle. Unfortunately, it doesn’t.

Then, I ran across the ignition framework, which provides a method for detecting when an application is going to the background. It does this by checking the package name of the Activity that is about to start, and comparing it to the package name defined in the application’s AndroidManifest.xml. If they differ, then the app is in fact going to the background.

I soon realized that this was a flawed approach. If the app is integrating a third party SDK, such as Apptentive, then not all of the Activities included in the app are guaranteed to have the same package name. So I made a tweak, which compares the starting Activity name to the list of Activities defined in the manifest. If they match, then the app is not going to the background, else it is. Called from an Activity’s onStop() method, I can now tell if the Activity is giving way to another Activity defined in the app, or the app is stopping.

How we know when the app goes to the background

[sourcecode language=”java”]
private static boolean isApplicationBroughtToBackground(final Activity activity) {
ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
List tasks = null;
try {
tasks = activityManager.getRunningTasks(1);
} catch (SecurityException e) {
Log.e(TAG, "Missing required permission: \"android.permission.GET_TASKS\".", e);
return false;
}
if (tasks != null && !tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
try {
PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
for (ActivityInfo activityInfo : pi.activities) {
if(topActivity.getClassName().equals(activityInfo.name)) {
return false;
}
}
} catch( PackageManager.NameNotFoundException e) {
Log.e(TAG, "Package name not found: " + activity.getPackageName());
return false; // Never happens.
}
}
return true;
}
[/sourcecode]

Introducing ApplicationSessionActivity

However, that only solved part of the problem.

    • An Android application can have an arbitrary number of Activities defined in it. I therefore need to check whether the app is going to background from each Activity.
    • I need to keep track of when the app is in the background so that I know a new use occurs when an Activity starts.
    • I need to know whether the Activity we are leaving is the main Activity or one of the child Activities.

It turned out that this was a little verbose in code, so I decided to create a new class, ApplicationSessionActivity, that developers can use to accomplish this goal. The integration is very simple:

1. Add the GET_TASKS permission to your AndroidManifest.xml.

[sourcecode language=”xml” highlight=”7″]
<!–?xml version="1.0" encoding="utf-8"?–>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.apptentive.android.example"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<application android:label="Session Example">
<activity android:name=".MainExampleActivityApplication"
android:label="Session Example">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".ChildExampleActivityApplication"/>
</application>
</manifest>
[/sourcecode]

2. Make all of your Activities inherit from SessionLifecycleActivity.

[sourcecode language=”java” highlight=”1,3″]
import com.apptentive.android.sessionlifecycle.SessionLifecycleActivity;

public class MainExampleActivity extends SessionLifecycleActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
[/sourcecode]

3. Create listeners to get session start and stop notifications.

[sourcecode language=”java” highlight=”6,7,8,9,10,11,13,14,15,16,17,18″]
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Pass a listener in so we can be notified of session starts.
setOnSessionStartedListener(new SessionStartedListener() {
public void onSessionStarted() {
Log.e("SessionExample", "Starting session.");
}
});

// Pass a listener in so we can be notified of session stops.
setOnSessionStoppedListener(new SessionStoppedListener() {
public void onSessionStopped() {
Log.e("SessionExample", "Stopping session.");
}
});
}
[/sourcecode]

The listeners will now be called when the app leaves the foreground, or comes back.

The code is available in a public git repo apptentive/ApplicationSessionActivity, and is free to use in your apps. Please let me know if you have any suggestions or feedback, and share with your fellow Android developers if you’ve found this to be useful.

[Note: Keep in mind that you may get weird results if you use an IDE to launch your app. The IDE launches the app differently than touching the app’s icon on your launcher screen. A good practice is to always exit the app (press the back button) after launching from an IDE, and then start it up again and go about your testing.]

Improve Customer Retention for Mobile Apps

Ready to see Apptentive in action?

Request a demo of Apptentive today.

Request a Demo

Sign Up for Our Newsletter

Stay up to date with the latest product management and mobile marketing news.