I am creating an ANE for Urban Airship, a service for sending push notifications (among other things). Via the help provided here: Hooking into main application's onCreate method from Adobe AIR extension I've been able to get push notifications, both textual and rich, working even when the application is closed. However, now I am having an issue using the Gimbal SDK using the GimbalAdapter provided by Urban Airship at https://github.com/urbanairship/ua-extensions.
The GimbalAdapter is just a wrapper class for starting up the Gimbal SDK and sending a Gimbal visit to Urban Airship. The trouble, it seems, is that these visits are not getting reported by Gimbal (or Urban Airship is not reacting to Gimbal reacting to the beacons). It is also odd that I've added a BeaconEventListener to the GimbalAdapter to just log raw beacon events, but I'm not seeing those either.
Here's my GimbalAdapter:
/*
* Copyright 2015 Urban Airship and Contributors
*/
import android.util.Log;
import com.gimbal.android.BeaconEventListener;
import com.gimbal.android.BeaconManager;
import com.gimbal.android.BeaconSighting;
import com.gimbal.android.CommunicationManager;
import com.gimbal.android.PlaceEventListener;
import com.gimbal.android.PlaceManager;
import com.gimbal.android.Place;
import com.gimbal.android.Visit;
import com.urbanairship.UAirship;
import com.urbanairship.location.RegionEvent;
import com.urbanairship.util.DateUtils;
/**
* GimbalAdapter interfaces Gimbal SDK functionality with Urban Airship services.
*/
public class GimbalAdapter {
/**
* GimbalAdapter logging tag.
*/
private static final String TAG = "GimbalAdapter ";
/**
* GimbalAdapter shared instance.
*/
private static GimbalAdapter instance = new GimbalAdapter();
/**
* Analytics event source.
*/
private static final String SOURCE = "Gimbal";
/**
* Boolean representing the started state of the GimbalAdapter.
*/
private boolean isStarted = false;
private BeaconEventListener beaconEventListener = new BeaconEventListener() {
@Override
public void onBeaconSighting(BeaconSighting beaconSighting)
{
Log.d(TAG, "Beacon spotted! " + beaconSighting.getBeacon().getName() + " " + beaconSighting.getBeacon().getIdentifier());
}
};
/**
* Listener for Gimbal place events. Creates an analytics event
* corresponding to boundary event type.
*/
private PlaceEventListener placeEventListener = new PlaceEventListener() {
@Override
public void onVisitStart(Visit visit) {
Log.i(TAG, "Entered place: " + visit.getPlace().getName() + "Entrance date: " +
DateUtils.createIso8601TimeStamp(visit.getArrivalTimeInMillis()));
RegionEvent enter = new RegionEvent(visit.getPlace().getIdentifier(), SOURCE, RegionEvent.BOUNDARY_EVENT_ENTER);
UAirship.shared().getAnalytics().addEvent(enter);
}
@Override
public void onVisitEnd(Visit visit) {
Log.i(TAG, "Exited place: " + visit.getPlace().getName() + "Entrance date: " +
DateUtils.createIso8601TimeStamp(visit.getArrivalTimeInMillis()) + "Exit date:" +
DateUtils.createIso8601TimeStamp(visit.getDepartureTimeInMillis()));
RegionEvent exit = new RegionEvent(visit.getPlace().getIdentifier(), SOURCE, RegionEvent.BOUNDARY_EVENT_EXIT);
UAirship.shared().getAnalytics().addEvent(exit);
}
};
/**
* Hidden to support the singleton pattern.
*/
GimbalAdapter() {}
/**
* GimbalAdapter shared instance.
*/
public synchronized static GimbalAdapter shared() {
return instance;
}
/**
* Starts tracking places.
*/
public void start() {
if (isStarted)
{
Log.d("GimbalAdapter", "Gimbal Adapter was already started and will not start again.");
return;
}
Log.d("GimbalAdapter", "Gimbal Adapter is starting");
isStarted = true;
BeaconManager manager = new BeaconManager();
manager.addListener(beaconEventListener);
manager.startListening();
Log.d(TAG, "beaconEventListener has been added");
PlaceManager.getInstance().addListener(placeEventListener);
PlaceManager.getInstance().startMonitoring();
Log.d("GimbalAdapter", "placeEventListener has been added.");
Log.i(TAG, "Adapter Started");
}
/**
* Stops tracking places.
*/
public void stop() {
if (!isStarted) {
return;
}
isStarted = false;
PlaceManager.getInstance().stopMonitoring();
PlaceManager.getInstance().removeListener(placeEventListener);
Log.i(TAG, "Adapter Stopped");
}
}
Here's my AutoPilot class, which is used by UrbanAirship in cases such as Adobe AIR where we are not allowed to modify the main application's Application class.
import android.app.Application;
import android.content.Context;
import android.os.Looper;
import android.util.Log;
import com.gimbal.android.Gimbal;
import com.gimbal.internal.service.GimbalService;
import com.gimbal.logging.GimbalLogConfig;
import com.gimbal.logging.GimbalLogLevel;
import com.urbanairship.AirshipConfigOptions;
import com.urbanairship.Autopilot;
import com.urbanairship.UAirship;
public class AirAutoPilot extends Autopilot
{
@Override
public AirshipConfigOptions createAirshipConfigOptions(Context context)
{
Log.d("AirAutoPilot", "Creating Airship Config Options");
AirshipConfigOptions options = new AirshipConfigOptions();
options.developmentAppKey = "xxx";
options.developmentAppSecret = "xxx";
options.inProduction = false;
options.gcmSender = "000";
return options;
}
@Override
public void onAirshipReady(UAirship airship)
{
Log.d("AirAutoPilot", "Urban Airship is ready after takeoff");
airship.getPushManager().setUserNotificationsEnabled(true);
Log.d("AirAutoPilot", "User notifications have been enabled");
if(Looper.myLooper() == null)
{
Log.d("AirAutoPilot", "Looper was null, preparing Looper");
Looper.prepare();
}
else
{
Log.d("AirAutoPilot", "Looper was already prepared.");
}
Log.d("AirAutoPilot", "Setting Gimbal log level to GimbalLogLevel.DEBUG");
GimbalLogConfig.setLogLevel(GimbalLogLevel.DEBUG);
Log.d("AirAutoPilot", "Configuring Gimbal adapter - set key with context");
Gimbal.setApiKey((Application) UAirship.getApplicationContext(), "xxx");
Log.d("AirAutoPilot", "Starting Gimbal Adapter...");
GimbalAdapter.shared().start();
}
}
Here are the applicable lines from LogCat:
12-02 14:10:30.803 21175-21175/? I/air.com.example.myapp: **ATTEMPTING URBAN AIRSHIP**
12-02 14:10:30.804 21175-21175/? D/UrbanAirshipExtension: Extension has been initialized
12-02 14:10:30.804 21175-21175/? D/UrbanAirshipExtension: Creating Urban Airship Context
12-02 14:10:30.806 21175-21175/? D/TakeoffFunction: Attempting Urban Airship TAKEOFF
12-02 14:10:30.808 21175-21175/? D/AirAutoPilot: Creating Airship Config Options
12-02 14:10:30.811 21175-21295/? I/MyApp-debug - UALib: Airship taking off!
12-02 14:10:30.811 21175-21295/? I/MyApp-debug - UALib: Airship log level: 3
12-02 14:10:31.062 21175-21295/? I/MyApp-debug - UALib: Airship ready!
12-02 14:10:31.062 21175-21295/? D/AirAutoPilot: Urban Airship is ready after takeoff
12-02 14:10:31.063 21175-21295/? D/AirAutoPilot: Setting Gimbal log level to GimbalLogLevel.DEBUG
12-02 14:10:31.064 21175-21295/? D/AirAutoPilot: Configuring Gimbal adapter - set key with context
12-02 14:10:31.324 21175-21295/? I/G.b: [Thread-2101 ] Gimbal Service starting - air.com.example.myapp
12-02 14:10:31.377 21175-21295/? D/AirAutoPilot: Starting Gimbal Adapter...
12-02 14:10:31.379 21175-21295/? D/GimbalAdapter: Gimbal Adapter is starting
12-02 14:10:31.380 21175-21295/? D/GimbalAdapter: beaconEventListener has been added
12-02 14:10:31.387 21175-21295/? D/GimbalAdapter: placeEventListener has been added.
12-02 14:10:31.391 21175-21295/? I/GimbalAdapter: Adapter Started
12-02 14:16:13.251 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:18.343 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:23.435 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:28.523 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:33.613 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:38.686 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:43.774 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:48.859 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:53.942 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:16:59.025 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:17:04.101 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
12-02 14:17:09.186 21175-21175/? D/G.b: [main ] Started: gimbalVisitCloseJob
It would seem that the Gimbal service is being started successfully. Then I start getting those "gimbalVisitCloseJob" every 5 seconds. This takes place when the nearby Gimbal s21 beacon is on or off.
However, the beacon event listener nor the place event listener in the GimbalAdapter are firing, so Urban Airship is not delivering the automated message that has been set up to be triggered by this beacon.