The New Relic Mobile SDK is intended to live within the foreground of a mobile application lifecycle. This is to ensure the agent has the smallest possible footprint, while tracking and reporting information about your app when the user is directly interacting with it.
But let’s face it - data can happen when your mobile app isn’t in the foreground. There might be information originating from background and long running services, and I’m here to help report that information.
I’ll provide a few code snippet examples specific to Android, but the basic concepts covered can be applied to other platforms. If you have examples of this functionality in other platforms, please share by commenting below!
Persistent Data Storage
In my example, I’d like to track if a user received a push notification, and report any possible exceptions thrown in the service.
We’ll place relevant event data using the SharedPreferences API, and report it once the app has launched.
public class MessageReceiver {
@Override
public boolean onMessageReceived(Context context, Bundle bundle, Message message) {
SharedPreferences sharedPreferences = getSharedPreferences("PushNotificationService", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("MessageReceived", message);
editor.apply();
try {
//Push notification logic
} catch (Exception e) {
editor.putString("ExceptionThrown", e.getMessage());
editor.apply();
e.printStackTrace();
}
return false;
}
}
Now let’s retrieve any data from that service, and report it as a custom event. We’ll process this as soon as the device has returned to the foreground, and the agent is started.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NewRelic.withApplicationToken("<App_Token>").start(this.getApplication());
SharedPreferences sharedPreferences = getSharedPreferences("PushNotificationService", Context.MODE_PRIVATE);
Map<String, Object> attributes = (Map<String, Object>) sharedPreferences.getAll();
if (attributes.size() > 0) {
boolean addedToPool = NewRelic.recordCustomEvent("PushNotificationService", attributes);
Log.d(TAG, "NR Event added to pool: " + addedToPool);
sharedPreferences.edit().clear().apply();
}
}
Insights API
Now I’d like to track when users of my pedometer service have reached 10,000 steps within a day. I don’t want to rely on the user to launch the app to report this data, so let’s leverage the Insights REST API.
try {
String url = "https://insights-collector.newrelic.com/v1/accounts/<Account_Id>/events";
JSONObject jsonBody = new JSONObject();
jsonBody.put("eventType", "PedometerTracking");
jsonBody.put("stepCount", stepCount);
jsonBody.put("sessionId", NewRelic.currentSessionId());
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(MediaType.parse("application/json"), jsonBody.toString());
Request request = new Request.Builder()
.url(url)
.addHeader("X-Insert-Key", "<Insights_insert_key>")
.post(body)
.build();
Response response = client.newCall(request).execute();
} catch (JSONException | IOException e) {
e.printStackTrace();
}
In this example I’m using OkHttp3 to send a POST request to the Insights API with event data packaged within a JSON object.
If you have other use cases or solutions for other platforms - please share below!