本文档介绍了移动数据分析(Mobile Analytics)Android SDK的使用方式。
Mobile Analytics Android SDK开发指南
1. 前言
本文档介绍了移动数据分析(Mobile Analytics)Android SDK的使用方式。
Mobile Analytics Android SDK是阿里云面向移动开发者提供的Android平台下的数据统计与监控服务。通过该SDK,开发者可以在自己的APP中便捷地进行数据埋点,监控日常的业务数据与网络性能数据,并通过阿里云控制台界面观察对应的数据报表展现。另外,用户后续可以通过设定自定义的数据解析规则实现定制化的数据图表展现。
您可以通过获取alicloud-android-demo工程源码获得移动数据分析服务的使用例程。
2. 安装Mobile Analytics Android SDK
2.1 注意
使用1.1.5
及之前版本请在【Crash分析】板块查看crash信息。
使用1.1.6
版本及之后的版本,请在【新版Crash分析】板块查看crash信息。
推荐使用1.1.6
及之后的版本,crash数据更加准确,丢包率更小。
1.1.6
之后的版本如果用手动设置channel
的方式,请在manService.getMANAnalytics().init
方法之前调用,具体请看下方初始化代码。通过AndroidMainfest.xml
设置的话不影响。
2.2 手动集成SDK
2.2.1 SDK目录结构
OneSDK
|-- libs
|-- |-- jniLibs
| | |-- armeabi
| | | |-- libMotu.so -crash捕获的so包
| | |-- armeabi-v7a
| | | |-- libMotu.so
| | |-- x86
| | | |-- libMotu.so
| |-- alicloud-android-sdk-man-1.1.6.jar -移动数据分析主功能包
| |-- alicloud-android-ut-5.4.0.jar -UT基础包
| |-- utdid4all-1.1.5.3_proguard.jar -设备Id生成包
2.2.2 SDK集成
手动拷贝
OneSDK
目录下的jniLibs
到以下目录:src - > main
在
build.gradle
配置中添加如下配置项:
android {
...
defaultConfig {
...
ndk {
moduleName "jniLibs"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
}
}
2.3 Maven依赖
build.gradle中添加Maven仓库地址:
allprojects {
repositories {
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}
gradle添加依赖:
dependencies {
compile 'com.aliyun.ams:alicloud-android-man:1.2.0'
}
(开发时可以如上所述指定完整的版本号,也可以指定模糊版本号,gradle自动拉取满足条件的最新版本SDK,如compile 'com.aliyun.ams:alicloud-android-man:1.+'
)
2.4 EMAS产品统一接入
要求SDK版本>=1.2.2版本,使用统一接入方式后,将无需在AndroidManifest中指定appKey/appSecret
,并且初始化时,可直接使用manService.getMANAnalytics().init(this, getApplicationContext());
即可。具体请参考:Emas统一接入文档(Android)
3. 应用程序初始化
在您使用Mobile Analytics Android SDK进行数据统计与监控前,您需要对SDK的上下文进行一些初始化配置,如权限声明、传递应用上下文、访问控制等。其中权限声明在AndroidManifest.xml文件中进行。
3.1 权限声明及配置AppKey,AppSecret
以下是Mobile Analytics Android SDK所需要的Android权限及配置AppKey,AppSecret,请把这些权限配置到您的AndroidManifest.xml文件,否则,SDK将无法正常工作。
...
<!-- 若您使用上述2.3中"统一接入的方式,则无需在AndroidManifest中配置appKey/appSecret" -->
<meta-data android:name="com.alibaba.app.appkey" android:value="YourAppKey"></meta-data>
<meta-data android:name="com.alibaba.app.appsecret" android:value="YourAppSecret"></meta-data>
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.GET_TASKS"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.READ_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
3.2 初始化及参数设置示例
在Application的实现类中,添加初始化SDK的代码。
Mobile Analytics Android SDK初始化部分的接口如下:
public class YourApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
/* 【注意】建议您在Application中初始化MAN,以保证正常获取MANService*/
// 获取MAN服务
MANService manService = MANServiceProvider.getService();
// 打开调试日志,线上版本建议关闭
// manService.getMANAnalytics().turnOnDebug();
// 若需要关闭 SDK 的自动异常捕获功能可进行如下操作(如需关闭crash report,建议在init方法调用前关闭crash)
manService.getMANAnalytics().turnOffCrashReporter();
// 设置渠道(用以标记该app的分发渠道名称),如果不关心可以不设置即不调用该接口,渠道设置将影响控制台【渠道分析】栏目的报表展现。如果文档3.3章节更能满足您渠道配置的需求,就不要调用此方法,按照3.3进行配置即可;1.1.6版本及之后的版本,请在init方法之前调用此方法设置channel.
manService.getMANAnalytics().setChannel("某渠道");
// MAN初始化方法之一,从AndroidManifest.xml中获取appKey和appSecret初始化,若您采用上述 2.3中"统一接入的方式",则使用当前init方法即可。
manService.getMANAnalytics().init(this, getApplicationContext());
// MAN另一初始化方法,手动指定appKey和appSecret
// 若您采用上述2.3中"统一接入的方式",则无需使用当前init方法。
// String appKey = "******";
// String appSecret = "******";
// manService.getMANAnalytics().init(this, getApplicationContext(), appKey, appSecret);
// 通过此接口关闭页面自动打点功能,详见文档4.2
manService.getMANAnalytics().turnOffAutoPageTrack();
// 若AndroidManifest.xml 中的 android:versionName 不能满足需求,可在此指定
// 若在上述两个地方均没有设置appversion,上报的字段默认为null
manService.getMANAnalytics().setAppVersion("3.1.1");
}
}
3.3 合规解决方案
为应对安卓端合规问题,可以将SDK初始化时机后移,不在onCreate中调用
但是需要注意
必须先调用初始化,才能调用埋点接口,否则会crash。 相关crash日志:java.lang.RuntimeException: getDefaultTracker error,must call setRequestAuthentication method first。
把初始化后移到隐私框之后会影响到SDK对应用生命周期的监控,影响1010等关键事件和pv相关逻辑需要应用将SDK未监控到的应用生命周期补全.应用可以在用户点击法律条款同意的时候将, 调用方法UTMCAppStatusMonitor.getInstance().onActivityStarted(null);来补全漏掉的生命周期监控。
3.4 配置渠道信息
您可以在AndroidManifest.xml中配置您的渠道信息,您只需要将<YOUR CHANNEL ID>
替换您的渠道信息即可。
【注意】SDK执行初始化时会自动获取AndroidManifest.xml中的字段,并填充渠道字段;初始化完成后。若同时调用了setChannel
方法,则以setChannel
方法中的参数为准。
<application ...
<meta-data
android:name="ALIYUN_MAN_CHANNEL"
android:value="<YOUR CHANNEL ID>" >
</meta-data>
</application>
3.5 SDK调试说明
在控制台中观察到的【今日实时】、【系统质量】-【实时Crash信息】、【新版crash分析】、【系统质量】-【性能分析】部分均为实时数据,调试时可参考该数据,验证环境配置及初始化是否正确。数据统计的准确性依赖APP的常规生命轨迹,比如应用启动次数依赖于用户正常退出应用触发的上报策略。
4. 业务数据统计
4.1 会员账号信息埋点
4.1.1 用户注册埋点
在用户注册成功之后,可使用userRegister 完成用户注册埋点。
MANService manService = MANServiceProvider.getService();
// 注册用户埋点
manService.getMANAnalytics().userRegister("usernick");
4.1.2 用户登录及注销埋点
用户登录埋点:
MANService manService = MANServiceProvider.getService();
// 用户登录埋点
manService.getMANAnalytics().updateUserAccount("usernick", "userid");
用户注销埋点:
// 用户注销埋点
manService.getMANAnalytics().updateUserAccount("", "");
如果不进行 4.1 会员账号信息埋点,此时不能在今日实时里看到【登录会员】和【新注册会员】的统计信息,而设备相关的统计【活跃用户】和【新增用户】可以看到。
完成上述埋点后,您就可以在阿里云控制台看到相应统计信息,例如下图所示为用户周活跃度。
4.2 页面埋点
说明:Mobile Analytics SDK默认会自动采集Android 4.0及以上系统的Activity 页面,如果不需要自动采集可使用下面方法关闭自动页面打点。打开页面自动埋点时,默认页面名称为class.getSimpleName()并去除Activity
后缀。
// 关闭自动打点
MANService manService = MANServiceProvider.getService();
manService.getMANAnalytics().turnOffAutoPageTrack();
为了满足Android 4.0以下系统的页面采集需求,您可按照如下的说明进行手动埋点。
【注意】:如果App中没有进行页面埋点,活跃用户
参数不能正常统计。
4.2.1 手动Activity页面埋点
在Activity 的onResume 以及onPause 中分别加入pageAppear和pageDisAppear代码,建议下述代码可以在一个基类中做,让其它所有的activity类都继承这个基类,就完成了所有子类页面埋点。
代码示例如下:
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
MANService manService = MANServiceProvider.getService();
manService.getMANPageHitHelper().pageAppear(this);
}
@Override
protected void onPause() {
super.onPause();
MANService manService = MANServiceProvider.getService();
manService.getMANPageHitHelper().pageDisAppear(this);
}
}
页面埋点将影响控制台【页面路径分析】、【关键漏斗】、【页面留存】等指标的报表展现。
4.2.2 给Activity页面增加属性统计
场景例子:
我们要开发一个购物app,在购物的app的宝贝展示页面,我们可能想要知道,此页面都展示了哪些商品?可以简单理解为,我们可以对采集的页面(GoodsDetails 页面)记录上增加一个宝贝属性就可以,如item_id=xxxxxx。
代码示例如下:
// 这句话要在一个页面的onPause 之前任何位置调用都可以
Map<String, String> lMap = new HashMap<String, String>();
lMap.put("item_id", "xxxxxx");
MANService manService = MANServiceProvider.getService();
manService.getMANPageHitHelper().updatePageProperties(lMap);
结果Log:
11-06 16:10:32.088: I/cache_log(10879): UT:...||2001||-||-||3191||item_id=xxxxxx
这里:2001 是页面事件的ID,3191 是页面展示的时长,item_id=xxxxxx 就是属性。
4.2.3 页面基础埋点使用
上述是针对Activity级别的页面埋点,只需简单地调用pageAppear和pageDispear即可完成埋点对相应的数据上报,上报数据包括:页面名称、来源页面名称、页面停留时间和额外属性设置等。如果需要对非Activity页面,如Fragment进行埋点,或者需要灵活把控页面埋点上报信息,如修改上报页面信息、对页面停留时长做特殊处理等,可以使用页面基础埋点的方式。通过该方式上报埋点数据同样将影响控制台【页面路径分析】、【关键漏斗】、【页面留存】等指标的报表展现。使用方式如下:
获取基础页面打点对象:
// 传入参数为页面名称
MANPageHitBuilder pageHitBuilder = new MANPageHitBuilder(String pageName);
设置来源页面名称(注:referPageName需要在pageName的集合中):
pageHitBuilder.setReferPage(String referPageName);
设置页面停留时间:
pageHitBuilder.setDurationOnPage(long duration);
设置页面属性:
pageHitBuilder.setProperty(String key, String value);
pageHitBuilder.setProperties(Map<String, String> properties);
构造页面埋点log数据:
pageHitBuilder.build();
数据上报:
MANServiceProvider.getService().getMANAnalytics().getDefaultTracker().send(pageHitBuilder.build());
5 自定义事件埋点
自定义事件埋点可用于满足用户的定制化需求。
自定义事件可包含以下几个部分内容:
1.事件名称(event_label),只能为字母、数字和下划线组成
2.事件从开始到完成消耗的时长
3.事件所携带的属性
4.事件对应的页面
例子:
// 事件名称:play_music
MANCustomHitBuilder hitBuilder = new MANHitBuilders.MANCustomHitBuilder("playmusic");
// 可使用如下接口设置时长:3分钟
hitBuilder.setDurationOnEvent(3 * 60 * 1000);
// 设置关联的页面名称:聆听
hitBuilder.setEventPage("Listen");
// 设置属性:类型摇滚
hitBuilder.setProperty("type", "rock");
// 设置属性:歌曲标题
hitBuilder.setProperty("title", "wonderful tonight");
// 发送自定义事件打点
MANService manService = MANServiceProvider.getService();
manService.getMANAnalytics().getDefaultTracker().send(hitBuilder.build());
自定义事件扩展参数在控制台【自定义事件】-【详细数据】-【参数分析】中可查看,但查看之前请在【参数分析】-【自定义事件参数管理】中添加要在控制台显示的参数。如果您需要对自定义事件进行实时监控,请参考【5.3 自定义性能事件】章节。
6. 如何实时验证数据是否正常上报
您当前可以通过以下两种方式进行验证:
打开移动数据分析log,查看logcat是否会出现如
UT:{"t":1464532680574,"ret":"","success":"success"}
的日志;注意:SDK的日志上报会有缓存和聚合,因此上报时机会比API调用时机滞后一些,可耐心等待30-60s或将应用切到后台查看。
登录控制台查看
活跃用户
等实时报表;注意:活跃用户的统计依赖页面埋点,移动数据分析后台会将零星的页面埋点处理为噪点,进行过滤,因此请确保您有足量的页面埋点事件上报(>5),另外控制台的实时报表大概会有5min的延迟。
7. H5数据的上报
H5页面采集并没有单独的SDK,依赖native进行上传,通过JSBridge通知给native,然后调用MAN的相应方法,进行数据的上报。可运行demo请参考:alicloud-android-demo
7.1 代码示例
JavaScript代码:
// 这里通过在JS alert消息,然后在native端进行捕获通信
alert( "jsbridge://custom" );
Java
重写WebChromeClient
的onAlert
方法,对于约定好的scheme,进行拦截,然后根据相应内容执行不同的方法,从而达到调用native埋点的目的。
WebView webView = (WebView) findViewById(R.id.h5DemoWebview);
webView.setWebChromeClient(new WebChromeClient(){
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
// 这里只要自己约定好方式就行,uri、json、xml等等。
Uri uri = Uri.parse(message);
if ( uri.getScheme().equals( "jsbridge" ) ) {
if ( uri.getHost().equals( "custom" ) ) {
// 事件名称:play_music
MANHitBuilders.MANCustomHitBuilder hitBuilder = new MANHitBuilders.MANCustomHitBuilder("playmusic");
// 可使用如下接口设置时长:3分钟
hitBuilder.setDurationOnEvent(3 * 60 * 1000);
// 设置关联的页面名称:聆听
hitBuilder.setEventPage("Listen");
// 设置属性:类型摇滚
hitBuilder.setProperty("type", "rock");
// 设置属性:歌曲标题
hitBuilder.setProperty("title", "wonderful tonight");
// 发送自定义事件打点
MANService manService = MANServiceProvider.getService();
manService.getMANAnalytics().getDefaultTracker().send(hitBuilder.build());
}
return true;
}
return super.onJsAlert(view, url, message, result);
}
});
8. 混淆配置
-keep class com.alibaba.sdk.android.**{*;}
-keep class com.ut.**{*;}
-keep class com.ta.**{*;}