HockeyApp for Android (SDK)

Version 5.2.0

HockeyApp is deprecating support for TLS 1.0 and 1.1 as part of our continual efforts to improve security for our customers. Support for TLS 1.0 and 1.1 will be discontinued on September 1st and clients will be obligated to connect to HockeyApp with TLS version 1.2 or greater.

To Enable TLS 1.2 for Android 4.x devices update the HockeySDK to this version.

This article describes how to integrate HockeyApp into your Android apps. The client allows testers to update your app to another beta version right from within the application. It will notify the tester if a new update is available. It also allows sending feedback and crash reports right from within the application. If a crash has happened, it will ask the tester on the next resume of the main activity whether he wants to send information about the crash to the server. The latter feature works for both beta apps and apps for Google Play.

In addition to HockeySDK, we also offer a native Android app for Android to download & install new apps and manage invites.

Introduction

HockeySDK-Android implements support for using HockeyApp in your Android application.

The following features are currently supported:

Crash Reports: If your app crashes, a crash log is written to the device's storage. If the user starts the app again, they will be asked to submit the crash report to HockeyApp. This works for both beta and live apps, i.e. those submitted to Google Play or other app stores. Crash logs contain viable information for you to help resolve the issue. Furthermore, you as a developer can add additional information to the report as well.

Update alpha/beta apps: The app will check with HockeyApp if a new version for your alpha/beta build is available. If yes, it will show a dialog to users and let them see the release notes, the version history and start the installation process right away. You can even force the installation of certain updates.

Feedback: Besides crash reports, collecting feedback from your users from within your app is a great option to help with improving your app. You act on and answer feedback directly from the HockeyApp backend.

Authenticate: To help you stay in control of closed tester groups you can identify and authenticate users against your registered testers with the HockeyApp backend. The authentication feature supports several ways of authentication.

1. Requirements

We assume that you already have an Android project in Android Studio or another Android IDE.

The SDK runs on devices with API Level 16 or later (Android 4.1 and up).

2. Setup

We recommend integration of our compiled library into your project using Android Studio and Gradle.
For other ways to setup the SDK, see advanced setup.
A sample integration can be found in this GitHub repository.

Note: For initial setup it is assumed that you want to use all of HockeyApp's features such as Crash Reporting, update distribution, and feedback. This means your app also needs all the basic permissions. If you only want to use a subset of features and thus only need to ask for a subset of permissions, please see the permissions section of the advanced setup section.

2.1 Obtain an app identifier

Please see the "How to create a new app" tutorial. This will provide you with an HockeyApp-specific App Identifier to be used to initialize the SDK.

2.2 Get the SDK

Add the SDK to your app module's dependencies in Android Studio by adding the following line to your dependencies { ... } configuration:

implementation 'net.hockeyapp.android:HockeySDK:5.2.0'

2.3 Integrate HockeySDK

Open your module's build.gradle file.

Add the following manifest placeholder to your configuration (typically the defaultConfig):

manifestPlaceholders = [HOCKEYAPP_APP_ID: "$APP_ID"]

The param $APP_ID must be replaced by your HockeyApp App Identifier. The app identifier can be found on the app's page in the "Overview" section of the HockeyApp backend.

Save your build.gradle file and make sure to trigger a Gradle sync.

Open your AndroidManifest.xml file and add a meta-data-tag for the HockeySDK.

Now that you've integrated the SDK with your project it's time to make use of its features.

If your app uses the permission WRITE_EXTERNAL_STORAGE permission

HockeySDK 5.0.0 and later limit the permission to access external storage to API levels lower than 18. This can cause issues in case your app requires this permission, override/replace the limitation that HockeySDK does as described in the paragraph about permissions.

2.4 Add Crash Reporting

This will add Crash Reporting capabilities to your app. Advanced ways to configure Crash Reporting are covered in advanced setup.

When the activity is resumed, the crash manager is triggered and checks if a new crash was created before. If there a crash log is present, it presents a dialog to ask the user whether they want to send the crash log to HockeyApp. On app launch the crash manager registers a new exception handler to recognize app crashes.

2.5 Add User Metrics

HockeyApp automatically provides you with nice, intelligible, and informative metrics about how your app is used and by whom.

Sessions: A new session is tracked by the SDK whenever the containing app is restarted (this refers to a 'cold start', i.e. when the app has not already been in memory prior to being launched) or whenever it becomes active again after having been in the background for 20 seconds or more.

Users: The SDK anonymously tracks the users of your app by creating a random UUID that is then securely stored. The UUID is securely stored in the preferences of the client app.

Custom Events: With HockeySDK 4.1.0 and later, you can now track Custom Events in your app, understand user actions and see the aggregates on the HockeyApp portal.

Batching & offline behavior: The SDK batches up to 50 events or waits for 15 seconds and then persists and sends the events, whichever comes first. So for sessions, this might actually mean, we send one single event per batch. If you are sending Custom Events, it can be 1 session event plus X of your Custom Events (up to 50 events per batch total). In case the device is offline, up to 50 batches (of up to 50 events) are stored until the SDK starts to reject and drop new events, logging an error.

To integrate User Metrics with your app, perform the following steps:

Open your app's main activity and add the import statement and one line of code to the activity's onCreate-callback. Add the trackEvent()-call wherever you want to track a Custom Event.

When the activity is created, the update manager checks for new updates in the background. If it finds a new update, an alert dialog is shown and if the user presses Show, they will be taken to the update activity. The reason to only do this once upon creation is that the update check causes network traffic and therefore potential costs for your users.

If your app uses the permission WRITE_EXTERNAL_STORAGE permission:

HockeySDK 5.0.0 and later limit the permission to access external storage to API levels lower than 18. This can cause issues in case your app requires this permission, override/replace the limitation that HockeySDK does as described in the paragraph about permissions.

2.7 Add in-app feedback

This will add the ability for your users to provide feedback from right inside your app. Detailed configuration options are in advanced setup.

You'll typically only want to show the feedback interface upon user interaction, for this example we assume you have a button feedback_button in your view for this.

Add the following lines to your respective activity, handling the touch events and showing the feedback interface:

When the user taps on the feedback button it will launch the HockeySDK's feedback interface, where the user can create a new feedback discussion, add screenshots or other files for reference, and act on their previous feedback conversations.

2.8 Add authentication

You can force authentication of your users through the LoginManager class. This will show a login screen to users if they are not fully authenticated to protect your app.

Retrieve your app secret from the HockeyApp backend. You can find this on the app details page in the backend right next to the "App ID" value. Click "Show" to access it.

Open the activity you want to protect, if you want to protect all of your app this will be your main activity.

Make sure to replace APP_SECRET with the value retrieved in step 1. This will launch the login activity when a user launches your app the first time. To read more about the different modes, have a look in the chapter in our advanced setup section .

NOTE If your activity has android:launchMode=singleTask set in your manifest, this means that it will destroy all activities on the stack once it receives the onNewIntent message, including the UI that HockeySDK-Android uses to block the UI. To make sure your application is blocked properly, call LoginManager.verifyLogin(this, getIntent()); in the onResume()-callback instead of the onCreate()-callback.

3. Changelog

You can access the full changelog in our releases-section. The following paragraphs contain information what you might need to change when upgrading to the different new versions.

3.1 Upgrading from 3.6.x to 3.7.0 or newer

We didn't introduce any breaking changes, except that we have raised the minimum API level to 9.

Also consider switching to our new register-calls and adding your app id to your configuration as described above.

The Strings class for overriding SDK strings has been removed in favor of resource merging. See our section on strings & localizations for more details.

If you integrate the SDK using Gradle, you can remove the previously required activities from your manifest file:

Permissions get automatically merged into your manifest. If your app does not use update distribution you might consider removing the permission WRITE_EXTERNAL_STORAGE - see the advanced permissions section for details.

4. Advanced setup

4.1 Manual library dependency

If you don't want to use Gradle or Maven dependency management you can also download and add the library manually. The easiest way to do this is using Android Studio.

Copy the file libs/HockeySDK-$version.aar to the libs folder of your Android project. ($version is the version of the downloaded SDK, if the version is < 3.7.0 it will be a .jar file instead)

Configure your development tools to use the .aar/.jar file.

In Android Studio, create a new module via File > New > New Module

Select Import .JAR/.AAR Package and click Next.

In the next menu select the .aar/.jar file you just copied to the libs folder. You can rename the module to whatever you want, but we in general recommend leaving it as is. If you don't rename the module, it will match the name of the .aar/.jar file, in this case HockeySDK-5.2.0. This way you'll quickly know which version of the SDK you are using in the future.

Make sure Android Studio added the necessary code to integrate the HockeySDK:

Head over to your app's build.gradle to verify the dependency was added correctly. It should look like this:

Once you have verified that everything necessary has been added, proceed with SDK integration.

4.2 Crash Reporting

The following options show only some of the many possibilities to interact and fine-tune the Crash Reporting feature. For more please check the full documentation of the classes net.hockeyapp.android.CrashManager and net.hockeyapp.android.CrashManagerListener in our documentation.

To configure a custom CrashManagerListener use the following register() method when configuring the manager:

4.2.1 Auto-send Crash Reports

Crashes are usually sent the next time the app starts. If your custom crash manager listener returns true for shouldAutoUploadCrashes(), crashes will be sent without any user interaction, otherwise a dialog will appear allowing the user to decide whether they want to send the report or not.

4.2.2 Attach additional meta data

Starting with HockeyApp 3.6.0, you can add additional meta data (e.g. user-provided information) to a Crash Report.
To achieve this call CrashManager.handleUserInput() and provide an instance of net.hockeyapp.android.objects.CrashMetaData.

4.3 Update distribution

You can customize the behavior of the in-app update process in several ways. The main class to look at is net.hockeyapp.android.UpdateManagerListener in our documentation.

To configure a custom UpdateManagerListener use the following register() method when configuring the manager:

4.3.1 Providing your own user interface for the update process

The UpdateManager will select a suitable activity or fragment depending on the availability of the feature. You can also supply your own by overriding the respective methods getUpdateActivityClass() and getUpdateFragmentClass() in your UpdateManagerListener subclass.

4.4 In-app feedback

As stated in the setup guide you'll typically want to show the feedback interface from an onClick, onMenuItemSelected, or onOptionsItemSelected listener method.

4.4.1 Capturing a screenshot for feedback

You can configure a notification to show to the user. When they select the notification the SDK will create a screenshot from the app in its current state and create a new feedback draft from it.

Open the activity from which you want to enable the screenshot.

Add this to your onCreate() method or an onClick() listener:

Java:

FeedbackManager.setActivityForScreenshot(YourActivity.this);

Kotlin:

FeedbackManager.setActivityForScreenshot(this@YourActivity)

4.5 Authentication

HockeySDK-Android currently supports 4 different authentication modes. The following code snippets usually make most sense in your main activity's onCreate()-callback.

NOTE If your activity has android:launchMode=singleTask set in your manifest, this means that it will destroy all activities on the stack once it receives the onNewIntent message, including the UI that HockeySDK-Android uses to block the UI. To make sure your application is blocked properly, call LoginManager.verifyLogin(this, getIntent()); in the onResume()-callback instead of the onCreate()-callback.

4.5.1 Anonymous

This is equal to the default HockeySDK behavior if you don't use LoginManager.
So if you want to switch between authentication modes for whatever reason,

NOTE Both authentication modes don't restrict updates once the user has authenticated themselves, so as long as the user has a HockeyApp account, they will continue to receive updates even if they are no longer associated with your app.
Restricting a version to user's won't have any effect if you have chosen this authentication mode.

4.5.3 Verify the user's authentication status and restrict updates

If you want to restrict updates for individual versions or want the HockeySDK to check the your tester is still associated with your app, use LoginManager.LOGIN_MODE_VALIDATE.

If you chose this validation mode, the user will no longer be able to use the app if they have been removed from the app.

LOGIN_MODE_VALIDATE also affects in-app updates. If you have chosen this authentication mode, you can restrict versions to individual testers.

It also requires to user to have an internet connection to avoid users who want to circumvent your restriction by going into airplane mode.

4.6 Strings & localization

HockeySDK for Android comes with several localizations of all user interface strings. If you want to add further localizations or override certain strings to suit your app's user interface, you can simply override them and resource merging takes care of the rest.

4.7 Permissions

HockeySDK requires some permissions to be granted for its operation. These are:

android.permission.ACCESS_NETWORK_STATE: Required to verify if network connectivity is available, as a preliminary measure before sending crash reports, checking for updates, and transmitting feedback.

android.permission.WRITE_EXTERNAL_STORAGE: Required for downloading app updates to a location that is reachable by the Android package installer which takes care of update installation. As of SDK version 5.0.0, we are limiting this permission to devices with API level 18 or lower.

HockeyApp registers these permissions with your app's AndroidManifest.xml through manifest merging. By default, all three permissions get added to your app's manifest file.

4.7.1 Removing external storage permission

Note: If you are using HockeySDK-Android 5.0.0 and later, the SDK limits the WRITE_EXTERNAL_STORAGE permission to devices with api level 18 or lower. If you are not supporting those api levels, you don't need to remove the permission.

If your app does not require access to external storage – for example if it doesn't use HockeyApp's update distribution – you might want to remove the WRITE_EXTERNAL_STORAGE-permission since it might not be needed by your app. To perform this, use a remove instruction for manifest merging:

The crucial part in this is the tools:node="remove"-part which will make sure the complete node will get removed from the resulting manifest file.

Note: If you later decide to use update distribution or any of your apps' dependencies requires write access to external storage, you will have to revert this change.

4.7.2 Other dependencies requesting the external storage permission (SDK version 5.0.0 and later)

To be ready for Android O, HockeySDK-Android 5.0.0 and later limit the WRITE_EXTERNAL_STORAGE permission with the maxSdkVersion filter. In some use cases, e.g. where an app contains a dependency that requires this permission, maxSdkVersion makes it impossible for those dependencies to grant or request the permission. The solution for those cases is as follows:

It will cause that other attributes from low priority manifests will be replaced instead of being merged.

4.8 Control output to LogCat

You can control the amount of log messages from HockeySDK that show up in LogCat. By default, we keep the noise as low as possible, only errors will show up. To enable additional logging, i.e. while debugging, add the following line of code:

Java:

HockeyLog.setLogLevel(Log.DEBUG);

Kotlin:

HockeyLog.setLogLevel(Log.DEBUG)

The different log levels match Android's own log levels.

Java:

HockeyLog.setLogLevel(Log.VERBOSE); // show all log statements
HockeyLog.setLogLevel(Log.DEBUG); // show most log statements – useful for debugging
HockeyLog.setLogLevel(Log.INFO); // show informative or higher log messages
HockeyLog.setLogLevel(Log.WARN); // show warnings and errors
HockeyLog.setLogLevel(Log.ERROR); // show only errors – the default log level

Kotlin:

HockeyLog.setLogLevel(Log.VERBOSE) // show all log statements
HockeyLog.setLogLevel(Log.DEBUG) // show most log statements – useful for debugging
HockeyLog.setLogLevel(Log.INFO) // show informative or higher log messages
HockeyLog.setLogLevel(Log.WARN) // show warnings and errors
HockeyLog.setLogLevel(Log.ERROR) // show only errors – the default log level

4.9 ProGuard

However, if you provide a custom user interface fragment for the update distribution module, e.g. by overriding UpdateManagerListener.getUpdateFragmentClass(), you will have to add an exception to your ProGuard configuration since this class is instantiated via reflection. Follow these steps:

5. Documentation

6.Troubleshooting

Check if the APP_ID matches the App ID in HockeyApp.

Check if the applicationId in your build.gradle file matches the Bundle Identifier of the app in HockeyApp. HockeyApp accepts crashes only if both the App ID and the bundle identifier match their corresponding values in your app. Please note that the package value in your AndroidManifest.xml file might differ from the bundle identifier.

If your app crashes and you start it again, does the dialog show up which asks the user to send the crash report? If not, please crash your app again, then connect the debugger and set a break point in CrashManager.java's register method to see why the dialog is not shown.

7.1 Code of Conduct

7.2 Contributor license

You must sign a Contributor License Agreement before submitting your pull request. To complete the Contributor License Agreement (CLA), you will need to submit a request via the form and then electronically sign the CLA when you receive the email containing the link to the document. You need to sign the CLA only once to cover submission to any Microsoft OSS project.