草庐IT

如何正确跟踪广告转化数据,优化广告投放效果?

HMS Core 2023-03-28 原文

为什么要做转化跟踪

广告界有一句老话,我知道我的广告费有一半是浪费掉的,但是不知道是怎么浪费掉的。所以对广告主来说广告跟踪非常重要,当你花了一大笔预算去做广告投放,带来的效果如何?如何根据每次广告投放的数据,去调整优化投放策略,这些都要靠广告跟踪来获得。

但现实情况是,广告平台与广告主侧的数据存在天然的割裂。广告平台能采集到安装事件,但应用内如付费、激活等转化事件平台采集不到,无法分析真实的转化率。广告主能轻易收集到实际转化的情况,但无法和广告任务相关联,影响对后续投放的优化。而通过转化跟踪,可以将广告主侧的转化事件与广告平台侧的投放任务相关联,从而为投放效果分析做数据支撑。

什么是转化跟踪

转化跟踪是将广告主最关注的转化行为(OAID、时间戳、转化行为、行为参数)通过API、SDK等方式上报给广告平台的产品。基于转化跟踪,广告主可以详细跟踪广告效果,监测不同平台、不同形式的广告带来的流量与对应转化效果,为不断优化广告投放提供准确的数据依据。

为了更好地帮助广告主在华为设备上进行应用推广,华为广告服务(HUAWEI Ads Kit)也提供转化跟踪能力,方便广告主进行广告转化渠道跟踪和转化效果分析。

华为广告服务转化跟踪参数能力工作原理

1. 广告主App集成广告服务获取转化跟踪参数能力并上架华为应用市场(AppGallery)。
2. 广告主在华为广告平台(Ad Network)投放App下载类广告,并设置转化跟踪参数。3. 媒体App(Media App)请求并展示广告主投放的广告。
4. 用户在媒体App上点击广告主投放的广告,用户可以选择并下载安装广告主App。
5. 华为应用市场(AppGallery)将转化跟踪参数写入广告服务。
6. 用户在端侧激活广告主App时,App从广告服务获取转化跟踪参数。
7. 广告主App上报激活事件给三方监测平台(Third-party tracking platform),平台可使用转化跟踪参数分析App转化效果。

开发步骤

一、集成转化跟踪参数开放能力(SDK方式)
SDK方式指广告主通过华为广告服务提供的SDK接入开放能力,获得App转化跟踪参数

集成SDK

1. 配置HUAWEI Ads SDK的Maven仓地址
打开Android Studio项目级"build.gradle"文件,在"allprojects > repositories"里面配置SDK的Maven仓地址。

allprojects { 
        repositories { 
                google() 
                jcenter() 
                maven { url 'https://developer.huawei.com/repo/' } 
        } 
}

2. 配置依赖
打开子工程"app"下的"build.gradle"文件,在dependencies新增SDK的依赖,并将{version}替换为实际的HUAWEI Ads SDK版本号,请参见版本更新说明

dependencies { 
        implementation 'com.huawei.hms:ads-installreferrer:{version}' 
}

3. 同步修改的文件

4. PK前需要配置不要混淆HUAWEI Ads SDK,避免功能异常。
打开Android工程应用级根目录下的"app/proguard-rules.pro"混淆配置文件,添加如下两行代码,加入排除HUAWEI Ads SDK的混淆配置。

allprojects { 
        repositories { 
                google() 
                jcenter() 
                maven { url 'https://developer.huawei.com/repo/' } 
        } 
}

创建转化跟踪参数状态监听器
1. 实现InstallReferrerStateListener监听器接口的两个方法onInstallReferrerSetupFinished和onInstallReferrerServiceDisconnected,代码示例如下:

/** 
* 创建监听 
*/ 
private InstallReferrerStateListener installReferrerStateListener = new InstallReferrerStateListener() { 
 @Override 
 public void onInstallReferrerSetupFinished(int responseCode) { 
     switch (responseCode) { 
         case InstallReferrerClient.InstallReferrerResponse.OK: 
             Log.i(TAG, "connect ads kit ok"); 
             get(); 
             break; 
         case InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED: 
             // 服务不支持,请下载并安装最新版本的HMS Core(APK) 
             Log.i(TAG, "FEATURE_NOT_SUPPORTED"); 
             break; 
         case InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE: 
             // 服务不可用,请将HMS Core(APK)版本升级到2.6.5及以上 
             Log.i(TAG, "SERVICE_UNAVAILABLE"); 
             break; 
         default: 
             Log.i(TAG, "responseCode: " + responseCode); 
             break; 
     } 
 } 
 
 @Override 
 public void onInstallReferrerServiceDisconnected() { 
     Log.i(TAG, "onInstallReferrerServiceDisconnected"); 
 } 
};

2. 在连接成功的回调中调用getInstallReferrer方法获取转化跟踪参数。

/** 
* 获取转化跟踪参数 
*/ 
private void get() { 
 if (null != mReferrerClient) { 
     try { 
         // 获取referrerDetails实例,不要在主线程中调用此方法 
         ReferrerDetails referrerDetails = mReferrerClient.getInstallReferrer(); 
         if (null != referrerDetails && null != mCallback) { 
             // 更新数据 
             mCallback.onSuccess(referrerDetails.getInstallReferrer(), 
                     referrerDetails.getReferrerClickTimestampMillisecond(), 
                     referrerDetails.getInstallBeginTimestampMillisecond()); 
         } 
     } catch (RemoteException e) { 
         Log.i(TAG, "getInstallReferrer RemoteException: " + e.getMessage()); 
     } catch (IOException e) { 
         Log.i(TAG, "getInstallReferrer IOException: " + e.getMessage()); 
     } finally { 
         disconnect(); 
     } 
 } 
}

创建InstallReferrerClient实例
通过builder配置和创建一个InstallReferrerClient实例。
1. 调用InstallReferrerClient.newBuilder创建一个Builder实例。
2. 调用build创建InstallReferrerClient实例。

mReferrerClient = InstallReferrerClient.newBuilder(mContext).build();

连接转化跟踪参数服务
建立与转化跟踪参数服务的连接。
1. 设置startConnection的监听器为已创建的InstallReferrerStateListener监听器。
2. 在子线程中调用startConnection方法连接服务。

mReferrerClient.startConnection(installReferrerStateListener);

二、集成转化跟踪参数开放能力(AIDL方式)

除了接入SDK以外,广告主也可以直接调用华为广告服务的AIDL接口获取华为设备上的转化跟踪参数,两种方法获取同一设备的转化跟踪参数是相同的。

新增AIDL接口文件
在工程"app/src/main/aidl/com/huawei/android/hms/ppskit/"路径中新增一个"IPPSChannelInfoService.aidl"接口文件,包名为"com.huawei.android.hms.ppskit",然后将下面内容拷贝到该接口文件中。

// IPPSRemoteService.aidl 
 package com.huawei.android.hms.ppskit; 
 /* 
  * 注意:不要修改AIDL文件的方法顺序 
  */ 
 interface IPPSChannelInfoService { 
 
     String getChannelInfo(); 
 }

创建一个类,实现ServiceConnection接口

1. 实现ServiceConnection的onServiceConnected方法。
2. 调用IPPSChannelInfoService.Stub.asInterface方法获取IPPSChannelInfoService。
3. 调用getChannelInfo方法获取转化跟踪参数。

private final class InstallReferrerServiceConnection implements ServiceConnection { 
 
     private InstallReferrerServiceConnection() { 
     } 
 
     @Override 
     public void onServiceConnected(ComponentName componentName, IBinder iBinder) { 
         Log.i(TAG, "onServiceConnected"); 
         mService = IPPSChannelInfoService.Stub.asInterface(iBinder); 
         if (null != mService) { 
             try { 
                 // 获取渠道信息(Json格式) 
                 String channelJson = mService.getChannelInfo(); 
                 Log.i(TAG, "channelJson: " + channelJson); 
                 // 解析 
                 JSONObject jsonObject = new JSONObject(channelJson); 
                 // 获取转化跟踪参数 
                 String installReferrer = jsonObject.optString("channelInfo"); 
                 long clickTimestamp = jsonObject.optLong("clickTimestamp", 0); 
                 long installTimestamp = jsonObject.optLong("installTimestamp", 0); 
                 if (null != mCallback) { 
                     // 更新数据 
                     mCallback.onSuccess(installReferrer, clickTimestamp, installTimestamp); 
                 } else { 
                     mCallback.onFail("install referrer is empty"); 
                 } 
             } catch (RemoteException e) { 
                 Log.e(TAG, "getChannelInfo RemoteException"); 
                 mCallback.onFail(e.getMessage()); 
             } catch (Exception e) { 
                 Log.e(TAG, "getChannelInfo Exception"); 
                 mCallback.onFail(e.getMessage()); 
             } finally { 
                 unbindService(); 
             } 
         } 
     } 
 
     @Override 
     public void onServiceDisconnected(ComponentName componentName) { 
         Log.i(TAG, "onServiceDisconnected"); 
         mService = null; 
     } 
 }

连接转化跟踪参数的AIDL服务
1. 创建一个InstallReferrerServiceConnection实例。
2. 创建一个Intent,Action是"com.huawei.android.hms.CHANNEL_SERVICE"。
3. 设置Intent的包名为"com.huawei.hwid"。
4. 调用bindService连接转化跟踪参数的AIDL服务

private boolean bindService() { 
     Log.i(TAG, "bindService"); 
     if (null == mContext) { 
         Log.e(TAG, "context is null"); 
         return false; 
     } 
     mServiceConnection = new InstallReferrerServiceConnection(); 
     Intent intent = new Intent(Constants.SERVICE_ACTION); 
     intent.setPackage(Constants.SERVICE_PACKAGE_NAME); 
     // 绑定服务 
     boolean result = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); 
     Log.i(TAG, "bindService result: " + result); 
     return result; 
 }

断开转化跟踪参数的AIDL服务
使用完AIDL接口后,应该主动断开服务连接。

private void unbindService() { 
     Log.i(TAG, "unbindService"); 
     if (null == mContext) {     
         Log.e(TAG, "context is null");     
         return; 
     } 
     if (null != mServiceConnection) { 
         // 解绑服务 
         mContext.unbindService(mServiceConnection); 
         mService = null; 
         mContext = null; 
         mCallback = null; 
     } 
 }

三、接入单机测试
完成上述获取转化跟踪参数业务代码的补全后,就可以进行编译,完成编译后,生成APK安装并运行。提供了相关Demo, 可以在端侧生成转化跟踪参数,供测试使用。

修改App用于测试转化跟踪参数。
SDK方式:在创建InstallReferrerClient时设置为测试模式,调用setTest(true),示例代码如下所示:

mReferrerClient = InstallReferrerClient.newBuilder(mContext).setTest(true).build(); 
mReferrerClient.startConnection(installReferrerStateListener);

AIDL方式:在测试时设置绑定的AIDL服务的包名为"com.huawei.pps.hms.test",示例代码如下所示:

mServiceConnection = new InstallReferrerServiceConnection(); 
Intent intent = new Intent(Constants.SERVICE_ACTION); 
intent.setPackage(Constants.TEST_SERVICE_PACKAGE_NAME); 
boolean result = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); 
Log.i(TAG, "bindService result: " + result);

将工程编译生成APK文件,并将APK文件安装到设备。运行App,显示如下页面。

点击"写入测试转化跟踪参数",界面将跳转到如下图所示页面,输入的App包名(参见"AndroidManifest.xml")和转化跟踪参数,并保存。

四、产品联调

得到转化跟踪参数后,需要登录华为广告平台将广告跟踪参数和推广任务联系起来
1. 广告主App集成转化跟踪参数后,上架华为应用市场。
2. 在华为广告投放平台创建推广任务时,设置转化跟踪参数,如下图所示:

3. 读取转化跟踪参数。广告主App被激活时,将会读取转化跟踪参数,并上报信息到开发者制定分析平台。

欲了解更多详情

访问华为广告服务官网
获取华为广告服务开发指导文档
华为广告服务开源仓库地址:GitHubGitee
华为HMS Core官方论坛 
解决集成问题请到Stack Overflow

关注我们,第一时间了解HMS Core最新技术~

有关如何正确跟踪广告转化数据,优化广告投放效果?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐