私は、(とりわけ) プッシュ通知を送信するためのサービスである Urban Airship の ANE を作成しています。ここで提供されているヘルプを介して: Adobe AIR 拡張機能からメイン アプリケーションの onCreate メソッドにフックするアプリケーションが閉じている場合でも、テキストとリッチの両方のプッシュ通知を受け取ることができました。ただし、 https://github.com/urbanairship/ua-extensionsで Urban Airship が提供する GimbalAdapter を使用して Gimbal SDK を使用すると問題が発生します。
GimbalAdapter は、Gimbal SDK を起動し、Urban Airship に Gimbal の訪問を送信するための単なるラッパー クラスです。問題は、これらの訪問がジンバルによって報告されていないことです (または、ビーコンに反応するジンバルにアーバン エアシップが反応していません)。生のビーコン イベントを記録するためだけに GimbalAdapter に BeaconEventListener を追加したのも奇妙ですが、それらも表示されません。
これが私のジンバルアダプターです:
/*
* 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");
}
}
これは、メイン アプリケーションの Application クラスを変更することが許可されていない Adobe AIR などの場合に、UrbanAirship によって使用される AutoPilot クラスです。
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();
}
}
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
Gimbal サービスが正常に開始されているようです。次に、5 秒ごとに「ジンバルVisitCloseJob」を取得し始めます。これは、近くのジンバル s21 ビーコンがオンまたはオフのときに発生します。
ただし、GimbalAdapter のビーコン イベント リスナーも場所イベント リスナーも起動しているため、Urban Airship は、このビーコンによってトリガーされるように設定された自動メッセージを配信していません。