将活动 SDK与您的应用程序集成

适用于iOS和Android的活动 SDK是移动应用程序渠道模块的组件之一。

注意

要获取活动 SDK(以前称为Neolane SDK),请联系Adobe客户关怀

SDK的目标是促进将移动应用程序集成到Adobe Campaign平台。

要了解有关支持的不同Android和iOS版本的更多信息,请参阅兼容性矩阵

正在加载活动 SDK

  • 在Android中:必须 将neolane_sdk-release. aarfile链接到项目。

    以下权限授予对Adobe Campaign服务器的访问权限:

    Neolane.getInstance().setIntegrationKey("your Adobe mobile app integration key");
    Neolane.getInstance().setMarketingHost("https://yourMarketingHost:yourMarketingPort/");
    Neolane.getInstance().setTrackingHost("https://yourTrackingHost:yourTrackingPort/");
    

    以下权限允许您恢复电话的唯一ID:

    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    

    从SDK的1.0.24版,此权限仅用于Android 6.0以前的版本。

    从SDK的1.0.26版,不再使用此权限。

  • 在iOS中:必 须将libNeolaneSDK.Neolane_SDK. h文件链接到项目。从SDK的1.0.24版中,将激活选项​ENABLE_BITCODE

    注意

    对于SDK的1.0.25版,可在​Neolane_SDK.h​文件中找到这四个架构。

声明集成设置

要将活动 SDK集成到移动应用程序中,功能管理员必须向开发人员提供以下信息:

  • 集成密钥:使Adobe Campaign平台能够识别移动应用程序。

    注意

    此集成密钥输入到Adobe Campaign控制台中,该控制台位于专用于移动应用程序的服务的​Information​选项卡中。 请参阅在Adobe Campaign中配置移动应用程序。

  • 跟踪URL:匹配Adobe Campaign跟踪服务器的地址。

  • 营销URL:以启用订阅集合。

  • 在Android中:

    Neolane.getInstance().setIntegrationKey("your Adobe mobile app integration key");
    Neolane.getInstance().setMarketingHost("https://yourMarketingHost:yourMarketingPort/");
    Neolane.getInstance().setTrackingHost("https://yourTrackingHost:yourTrackingPort/"); 
    
  • 在iOS中:

    Neolane_SDK *nl = [Neolane_SDK getInstance];
    [nl setMarketingHost:strMktHost];
    [nl setTrackingHost:strTckHost];
    [nl setIntegrationKey:strIntegrationKey];
    

注册函数

注册功能允许您:

  • 将通知ID或推送ID(iOS的deviceToken和Android的registrationID)发送到Adobe Campaign。

  • 恢复合并关键项或userKey(例如,电子邮件或帐户号)

  • 在Android中:

    void registerInNeolane(String registrationId, String userKey, Context context)
    {
     try{
      Neolane.getInstance().registerDevice(registrationToken, userKey, null, context);
     } catch (NeolaneException e){
      //...
     } catch (IOException e){
      //...
     }
    }
    

    如果您使用FCM(Firebase Cloud Messaging),我们建议您在调用​onTokenRefresh​函数时使用​registerDevice​函数,以通知Adobe Campaign用户移动设备令牌中的更改。

    public class NeoTripFirebaseInstanceIDService extends FirebaseInstanceIdService {
      @Override
      public void onTokenRefresh() {
        String registrationToken = FirebaseInstanceId.getInstance().getToken();
        NeolaneAsyncRunner neolaneAs = new NeolaneAsyncRunner(Neolane.getInstance());
        ...
        ...
        // Neolane Registration
        neolaneAs.registerDevice(registrationToken, userKey, additionnalParam, this, new NeolaneAsyncRunner.RequestListener() {
        public void onComplete(String e, Object state) { ... }
        public void onNeolaneException(NeolaneException e, Object state) { ... }
        public void onIOException(IOException e, Object state) { ... }
        });
        ...
        ...
      }
    }
    
  • 在iOS中:

    // Callback called on successful registration to the APNs
    - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
    {
        // Pass the token to Adobe Campaign
        Neolane_SDK *nl = [Neolane_SDK getInstance];
        [nl registerDevice:tokenString:self.userKey:dic];
    }
    

跟踪函数

  • 在Android中:

    跟踪功能允许您跟踪通知激活(打开)和通知显示(屏幕截图)。

    要跟踪通知显示(通过调用SDK的​notifyReceive​函数完成),请遵循以下实现。 请注意,如果您使用FCM(Firebase Cloud Messaging),当Android系统调用​onMessageReceived​函数时,我们建议您使用​notifyReceive​函数。

    package com.android.YourApplication;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.util.Log;
    
    import com.google.firebase.messaging.FirebaseMessagingService;
    import com.google.firebase.messaging.RemoteMessage;
    
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    
    public class YourApplicationFirebaseMessagingService extends FirebaseMessagingService {
      private static final String TAG = "MyFirebaseMsgService";
    
      @Override
      public void onMessageReceived(RemoteMessage message) {
        Log.d(TAG, "Receive message from: " + message.getFrom());
        Map<String,String> payloadData = message.getData();
        final Bundle extras = new Bundle();
        final Iterator<Entry<String, String>> iter = payloadData.entrySet().iterator();
        while(iter.hasNext())
        {
          final Entry<String, String>  entry =iter.next();
          extras.putString(entry.getKey(), entry.getValue());
        }
    
        SharedPreferences settings = this.getSharedPreferences(YourApplicationActivity.APPLICATION_PREF_NAME, Context.MODE_PRIVATE);
        String mesg = payloadData.get("_msg");
        String title = payloadData.get("title");
        String url = payloadData.get("url");
        String messageId = payloadData.get("_mId");
        String deliveryId = payloadData.get("_dId");
        YourApplicationActivity.handleNotification(this, mesg, title, url, messageId, deliveryId, extras);
      }
    }
    
    public static void handleNotification(Context context, String message, String title, String url, String messageId, String deliveryId, Bundle extras){
        if( message == null ) message = "No Content";
        if( title == null )   title = "No title";
        if( url == null )     url = "https://www.tripadvisor.fr";
        int iconId = R.drawable.notif_neotrip;
    
      // notify Neolane that a notification just arrived
      SharedPreferences settings = context.getSharedPreferences(NeoTripActivity.APPLICATION_PREF_NAME, Context.MODE_PRIVATE);
      Neolane.getInstance().setIntegrationKey(settings.getString(NeoTripActivity.APPUUID_NAME, NeoTripActivity.DFT_APPUUID));
      Neolane.getInstance().setMarketingHost(settings.getString(NeoTripActivity.SOAPRT_NAME, NeoTripActivity.DFT_SOAPRT));
      Neolane.getInstance().setTrackingHost(settings.getString(NeoTripActivity.TRACKRT_NAME, NeoTripActivity.DFT_TRACKRT));
    
      NeolaneAsyncRunner nas = new NeolaneAsyncRunner(Neolane.getInstance());
      nas.notifyReceive(Integer.valueOf(messageId), deliveryId, new NeolaneAsyncRunner.RequestListener() {
        public void onNeolaneException(NeolaneException arg0, Object arg1) {}
        public void onIOException(IOException arg0, Object arg1) {}
        public void onComplete(String arg0, Object arg1){}
      });
      if (yourApplication.isActivityVisible())
        {
          Log.i("INFO", "The application has the focus" );
          ...
        }
        else
        {
          // notification creation :
          NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
          Notification notification;
    
          // Activity to start :
          Intent notifIntent = new Intent(context.getApplicationContext(), NotificationActivity.class);
          notifIntent.putExtra("notificationText", message);
          notifIntent.putExtra(NotificationActivity.NOTIFICATION_URL_KEYNAME, url);
          notifIntent.putExtra("_dId", deliveryId);
          notifIntent.putExtra("_mId", messageId);
          notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          PendingIntent contentIntent = PendingIntent.getActivity(context, 1, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
          notification = new Notification.Builder(context)
                  .setContentTitle(title)
                  .setContentText(message)
                  .setSmallIcon(iconId)
                  .setContentIntent(contentIntent)
                  .build();
    
          // launch the notification :
          notification.flags |= Notification.FLAG_AUTO_CANCEL;
          notificationManager.notify(Integer.valueOf(messageId), notification);
        }
    }
    

    下面是跟踪通知打开的一个实现示例(通过调用SDK的​notifyOpening​函数执行)。 NotificationActivity​类与上一个示例中用于创建​notifIntent​对象的类相对应。

    public class NotificationActivity extends Activity {
    public void onCreate(Bundle savedBundle) {
      [...]
      Bundle extra = getIntent().getExtras();
      if (extra != null) {
        // reinit the acc sdk
        SharedPreferences settings = getSharedPreferences(NeoTripActivity.APPLICATION_PREF_NAME, Context.MODE_PRIVATE);
        Neolane.getInstance().setIntegrationKey(settings.getString(NeoTripActivity.APPUUID_NAME, NeoTripActivity.DFT_APPUUID));
        Neolane.getInstance().setMarketingHost(settings.getString(NeoTripActivity.SOAPRT_NAME, NeoTripActivity.DFT_SOAPRT));               
        Neolane.getInstance().setTrackingHost(settings.getString(NeoTripActivity.TRACKRT_NAME, NeoTripActivity.DFT_TRACKRT));
    
        // Get the messageId and the deliveryId to do the tracking
        String deliveryId = extra.getString("_dId");
        String messageId = extra.getString("_mId");
        if (deliveryId != null && messageId != null) {
          try {
            Neolane.getInstance().notifyOpening(Integer.valueOf(messageId), Integer.valueOf(deliveryId));
          } catch (NeolaneException e) {
            // ...
          } catch (IOException e) {
            // ...
          }
        }
      }
     }
    }
    
  • 在iOS中:

    跟踪功能允许您跟踪通知激活(打开)的时间。

    (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)launchOptions
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
    if( launchOptions ) { // Retrieve notification parameters here ... // Track application opening Neolane_SDK
    *nl = [Neolane_SDK getInstance]; [nl track:launchOptions:NL_TRACK_CLICK]; } 
    ...  
    completionHandler(UIBackgroundFetchResultNoData);
    }
    
    注意

    从版本7.0开始,在实现​application:didReceiveRemoteNotification:fetchCompletionHandler​函数后,操作系统只调用此函数。 因此,不调用​application:didReceiveRemoteNotification​函数。

无提示通知跟踪

iOS允许您发送静默通知、通知或数据,这些通知或数据将直接发送到移动应用程序而不显示。 Adobe Campaign允许您跟踪它们。

要跟踪您的无提示通知,请按照以下示例操作:

// AppDelegate.m
...
...
#import "AppDelegate.h"
#import "Neolane_SDK.h"
...
...
// Callback called when the application is already launched (whether the application is running foreground or background)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)launchOptions fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
 NSLog(@"IN didReceiveRemoteNotification:fetchCompletionHandler");
 if (launchOptions) NSLog(@"IN launchOptions: %@", [launchOptions description]);
 NSLog(@"Application state: %ld", (long)application.applicationState);

 // Silent Notification (specific case, can use NL_TRACK_RECEIVE as the user doesn't have click/open the notification)
 if ([launchOptions[@"aps"][@"content-available"] intValue] == 1 )
       {
  NSLog(@"Silent Push Notification");
  ...  
  ...
  //Call receive tracking
        Neolane_SDK *nl = [Neolane_SDK getInstance];
  [nl track:launchOptions:NL_TRACK_RECEIVE];

  completionHandler(UIBackgroundFetchResultNoData); //Do not show notification
  return;
 }  
 ...
 ...
        completionHandler(UIBackgroundFetchResultNoData);
}

RegisterDeviceStatus委托

注意

请注意,iOS专有此功能。

在iOS中,委托协议允许您获得​registerDevice​调用的结果,并可用于了解注册期间是否发生错误。

registerDeviceStatus​原型为:

- (void) registerDeviceStatus: (ACCRegisterDeviceStatus) status:(NSString *) errorReason;

状态”允许您了解注册是否成功或是否出错。

ErrorReason 为您提供有关所发生错误的更多信息。有关可用错误及其说明的详细信息,请参阅下表。

状态
说明
ErrorReason
ACCRegisterDeviceStatusSuccess
注册成功

ACCRegisterDeviceStatusFailureMarketingServerHostnameEmpty
ACC营销服务器主机名为空或未设置。

ACCRegisterDeviceStatusFailureIntegrationKeyEmpty
集成密钥为空或未设置。

ACCRegisterDeviceStatusFailureConnectionIssue
ACC
的连接问题
更多信息(使用操作系统当前语言)
ACCRegisterDeviceStatusFailureUnknownUUID
提供的UUID(集成键)未知。

ACCRegisterDeviceStatusFailureUnexpectedError
ACC服务器返回了意外错误。
返回到ACC的错误消息

Neolane_SDKDelegate 协议和 ​registerDeviceStatusdelegate定义如下:

//  Neolane_SDK.h
//  Neolane SDK
..
.. 
// Register Device Status Enum
typedef NS_ENUM(NSUInteger, ACCRegisterDeviceStatus) {
 ACCRegisterDeviceStatusSuccess,                               // Resistration Succeed
 ACCRegisterDeviceStatusFailureMarketingServerHostnameEmpty,   // The ACC marketing server hostname is Empty or not set
 ACCRegisterDeviceStatusFailureIntegrationKeyEmpty,            // The integration key is empty or not set
 ACCRegisterDeviceStatusFailureConnectionIssue,                // Connection issue with ACC, more information in errorReason
 ACCRegisterDeviceStatusFailureUnknownUUID,                    // The provided UUID (integration key) is unknown
 ACCRegisterDeviceStatusFailureUnexpectedError                 // Unexpected error returned by ACC server, more information in errorReason
};
// define the protocol for the registerDeviceStatus delegate
@protocol Neolane_SDKDelegate <NSObject>
@optional
- (void) registerDeviceStatus: (ACCRegisterDeviceStatus) status :(NSString *) errorReason;
@end
@interface Neolane_SDK: NSObject {
} 
...
...
// registerDeviceStatus delegate
@property (nonatomic, weak) id <Neolane_SDKDelegate> delegate;
...
...
@end

要实现​registerDeviceStatus​委托,请执行以下步骤:

  1. 在SDK初始化过程中实施​setDelegate

    // AppDelegate.m
    ...
    ... 
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    ...
    ...
     // Get the stored settings
    
     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     NSString *strMktHost = [defaults objectForKey:@"mktHost"];
     NSString *strTckHost = [defaults objectForKey:@"tckHost"];
     NSString *strIntegrationKey = [defaults objectForKey:@"integrationKey"];
     userKey = [defaults objectForKey:@"userKey"];
    
     // Configure Neolane SDK on first launch
     Neolane_SDK *nl = [Neolane_SDK getInstance];
     [nl setMarketingHost:strMktHost];
     [nl setTrackingHost:strTckHost];
     [nl setIntegrationKey:strIntegrationKey];
     [nl setDelegate:self];    // HERE
    ...
    ...
    }
    
  2. 在类的​@interface​中添加协议。

    //  AppDelegate.h
    
    #import <UIKit/UIKit.h>
    #import <CoreLocation/CoreLocation.h>
    #import "Neolane_SDK.h"
    
    @class LandingPageViewController;
    
    @interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate, Neolane_SDKDelegate> {
        CLLocationManager *locationManager;
        NSString *userKey;
        NSString *mktServerUrl;
        NSString *tckServerUrl;
        NSString *homeURL;
        NSString *strLandingPageUrl;
        NSTimer *timer;
    }
    
  3. 在​AppDelegate​中实施委托。

    //  AppDelegate.m
    
    #import "AppDelegate.h"
    #import "Neolane_SDK.h"
    #import "LandingPageViewController.h"
    #import "RootViewController.h"
    ...
    ...
    - (void) registerDeviceStatus: (ACCRegisterDeviceStatus) status :(NSString *) errorReason
    {
        NSLog(@"registerStatus: %lu",status);
    
        if ( errorReason != nil )
            NSLog(@"errorReason: %@",errorReason);
    
        if( status == ACCRegisterDeviceStatusSuccess )
        {
            // Registration successful
            ...
            ...
        }
        else { // An error occurred
            NSString *message;
            switch ( status ){
                case ACCRegisterDeviceStatusFailureUnknownUUID:
                    message = @"Unkown IntegrationKey (UUID)";
                    break;
                case ACCRegisterDeviceStatusFailureMarketingServerHostnameEmpty:
                    message = @"Marketing URL not set or Empty";
                    break;
                case ACCRegisterDeviceStatusFailureIntegrationKeyEmpty:
                    message = @"Integration Key not set or empty";
                    break;
                case ACCRegisterDeviceStatusFailureConnectionIssue:
                    message = [NSString stringWithFormat:@"%@ %@",@"Connection issue:",errorReason];
                    break;
                case ACCRegisterDeviceStatusFailureUnexpectedError:
                default:
                    message = [NSString stringWithFormat:@"%@ %@",@"Unexpected Error",errorReason];
                    break;
            }
     ...
     ...
        }
    }
    @end
    

变量

通过这些变量,您可以在收到通知后定义手机应用程序行为。 这些变量必须在移动应用程序代码和Adobe Campaign控制台中,在专用移动应用程序服务的​Variables​选项卡中定义(请参阅在Adobe Campaign中配置移动应用程序)。 下面是一个代码示例,它允许移动应用程序收集通知中任何添加的变量。 在我们的示例中,我们使用“VAR”变量。

  • 在Android中:

    public void onReceive(Context context, Intent intent) {
         ...
        String event = intent.getStringExtra("VAR");
         ...
    }
    
  • 在iOS中:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        ....
        if( launchOptions )
        {
            // When application is not already launched, the notification data if any are stored in the key 'UIApplicationLaunchOptionsRemoteNotificationKey'
            NSDictionary *localLaunchOptions = [launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"];
            if( localLaunchOptions )
            {
             ...
             [localLaunchOptions objectForKey:@"VAR"];
            ...
            }
       }
    }
    
    // Callback called when the application is already launched (whether the application is running foreground or background)
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)launchOptions
    {
        if( launchOptions )
        {
         ...
            [launchOptions objectForKey:@"VAR"];
        }
    }
    
注意

Adobe建议选择短变量名称,因为iOS和Android的通知大小限制为4kB。

通知服务扩展

适用于iOS

必须在通知服务扩展级别下载媒体。

#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    NSDictionary *userInfo = nil;
    NSString *url = nil;

    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];

    userInfo = request.content.userInfo;
    if ( userInfo != nil )
    {
        url = userInfo[@"mediaUrl"];  // Get the url of the media to download (Adobe Campaign additional variable)
    }
    ...
    // Perform the download to local storage

通知内容扩展

适用于iOS

在此级别上,您需要:

  • 将您的内容扩展与Adobe Campaign发送的类别关联:

    如果希望移动应用程序显示图像,您可以在Adobe Campaign中将类别值设置为“image”,在移动应用程序中将​UNNotificationExtensionCategory​参数设置为“image”创建通知扩展。 在设备上接收推送通知时,将根据定义的类别值调用扩展。

  • 定义通知布局

    您需要使用相关构件定义布局。 对于图像,该Widget名为​UIImageView

  • 显示媒体

    您需要添加代码以将媒体数据馈送到Widget。 以下是图像的代码示例:

    #import "NotificationViewController.h"
    #import <UserNotifications/UserNotifications.h>
    #import <UserNotificationsUI/UserNotificationsUI.h>
    
    @interface NotificationViewController () <UNNotificationContentExtension>
    
    @property (strong, nonatomic) IBOutlet UIImageView *imageView;
    @property (strong, nonatomic) IBOutlet UILabel *notifContent;
    @property (strong, nonatomic) IBOutlet UILabel *label;
    
    @end
    
    @implementation NotificationViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any required interface initialization here.
    }
    
    - (void)didReceiveNotification:(UNNotification *)notification {
        self.label.text = notification.request.content.title;
        self.notifContent.text = notification.request.content.body;
        UNNotificationAttachment *attachment = [notification.request.content.attachments objectAtIndex:0];
        if ([attachment.URL startAccessingSecurityScopedResource])
        {
          NSData * imageData = [[NSData alloc] initWithContentsOfURL:attachment.URL];
          self.imageView.image =[UIImage imageWithData: imageData];
          [attachment.URL stopAccessingSecurityScopedResource];
        }
    }
    @end
    

On this page

Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now