移動(dòng)數(shù)據(jù)分析
本文檔介紹了移動(dòng)數(shù)據(jù)分析(Mobile Analytics)Android SDK的使用方式。
Mobile Analytics Android SDK開發(fā)指南
1. 前言
本文檔介紹了移動(dòng)數(shù)據(jù)分析(Mobile Analytics)Android SDK的使用方式。
Mobile Analytics Android SDK是阿里云面向移動(dòng)開發(fā)者提供的Android平臺(tái)下的數(shù)據(jù)統(tǒng)計(jì)與監(jiān)控服務(wù)。通過該SDK,開發(fā)者可以在自己的APP中便捷地進(jìn)行數(shù)據(jù)埋點(diǎn),監(jiān)控日常的業(yè)務(wù)數(shù)據(jù)與網(wǎng)絡(luò)性能數(shù)據(jù),并通過阿里云控制臺(tái)界面觀察對(duì)應(yīng)的數(shù)據(jù)報(bào)表展現(xiàn)。另外,用戶后續(xù)可以通過設(shè)定自定義的數(shù)據(jù)解析規(guī)則實(shí)現(xiàn)定制化的數(shù)據(jù)圖表展現(xiàn)。
您可以通過獲取alicloud-android-demo工程源碼獲得移動(dòng)數(shù)據(jù)分析服務(wù)的使用例程。
2. 安裝Mobile Analytics Android SDK
2.1 注意
使用1.1.5
及之前版本請(qǐng)?jiān)?b>【Crash分析】板塊查看crash信息。
使用1.1.6
版本及之后的版本,請(qǐng)?jiān)?b>【新版Crash分析】板塊查看crash信息。
推薦使用1.1.6
及之后的版本,crash數(shù)據(jù)更加準(zhǔn)確,丟包率更小。
1.1.6
之后的版本如果用手動(dòng)設(shè)置channel
的方式,請(qǐng)?jiān)?code data-tag="code" class="code">manService.getMANAnalytics().init方法之前調(diào)用,具體請(qǐng)看下方初始化代碼。通過AndroidMainfest.xml
設(shè)置的話不影響。
2.2 手動(dòng)集成SDK
2.2.1 SDK目錄結(jié)構(gòu)
OneSDK
|-- libs
|-- |-- jniLibs
| | |-- armeabi
| | | |-- libMotu.so -crash捕獲的so包
| | |-- armeabi-v7a
| | | |-- libMotu.so
| | |-- x86
| | | |-- libMotu.so
| |-- alicloud-android-sdk-man-1.1.6.jar -移動(dòng)數(shù)據(jù)分析主功能包
| |-- alicloud-android-ut-5.4.0.jar -UT基礎(chǔ)包
| |-- utdid4all-1.1.5.3_proguard.jar -設(shè)備Id生成包
2.2.2 SDK集成
手動(dòng)拷貝
OneSDK
目錄下的jniLibs
到以下目錄:src - > main
在
build.gradle
配置中添加如下配置項(xiàng):
android {
...
defaultConfig {
...
ndk {
moduleName "jniLibs"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
}
}
2.3 Maven依賴
build.gradle中添加Maven倉(cāng)庫(kù)地址:
allprojects {
repositories {
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}
gradle添加依賴:
dependencies {
compile 'com.aliyun.ams:alicloud-android-man:1.2.0'
}
(開發(fā)時(shí)可以如上所述指定完整的版本號(hào),也可以指定模糊版本號(hào),gradle自動(dòng)拉取滿足條件的最新版本SDK,如compile 'com.aliyun.ams:alicloud-android-man:1.+'
)
2.4 EMAS產(chǎn)品統(tǒng)一接入
要求SDK版本>=1.2.2版本,使用統(tǒng)一接入方式后,將無需在AndroidManifest中指定appKey/appSecret
,并且初始化時(shí),可直接使用manService.getMANAnalytics().init(this, getApplicationContext());
即可。具體請(qǐng)參考:Emas統(tǒng)一接入文檔(Android)
3. 應(yīng)用程序初始化
在您使用Mobile Analytics Android SDK進(jìn)行數(shù)據(jù)統(tǒng)計(jì)與監(jiān)控前,您需要對(duì)SDK的上下文進(jìn)行一些初始化配置,如權(quán)限聲明、傳遞應(yīng)用上下文、訪問控制等。其中權(quán)限聲明在AndroidManifest.xml文件中進(jìn)行。
3.1 權(quán)限聲明及配置AppKey,AppSecret
以下是Mobile Analytics Android SDK所需要的Android權(quán)限及配置AppKey,AppSecret,請(qǐng)把這些權(quán)限配置到您的AndroidManifest.xml文件,否則,SDK將無法正常工作。
...
<!-- 若您使用上述2.3中"統(tǒng)一接入的方式,則無需在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 初始化及參數(shù)設(shè)置示例
在Application的實(shí)現(xiàn)類中,添加初始化SDK的代碼。
Mobile Analytics Android SDK初始化部分的接口如下:
public class YourApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
/* 【注意】建議您在Application中初始化MAN,以保證正常獲取MANService*/
// 獲取MAN服務(wù)
MANService manService = MANServiceProvider.getService();
// 打開調(diào)試日志,線上版本建議關(guān)閉
// manService.getMANAnalytics().turnOnDebug();
// 若需要關(guān)閉 SDK 的自動(dòng)異常捕獲功能可進(jìn)行如下操作(如需關(guān)閉crash report,建議在init方法調(diào)用前關(guān)閉crash)
manService.getMANAnalytics().turnOffCrashReporter();
// 設(shè)置渠道(用以標(biāo)記該app的分發(fā)渠道名稱),如果不關(guān)心可以不設(shè)置即不調(diào)用該接口,渠道設(shè)置將影響控制臺(tái)【渠道分析】欄目的報(bào)表展現(xiàn)。如果文檔3.3章節(jié)更能滿足您渠道配置的需求,就不要調(diào)用此方法,按照3.3進(jìn)行配置即可;1.1.6版本及之后的版本,請(qǐng)?jiān)趇nit方法之前調(diào)用此方法設(shè)置channel.
manService.getMANAnalytics().setChannel("某渠道");
// MAN初始化方法之一,從AndroidManifest.xml中獲取appKey和appSecret初始化,若您采用上述 2.3中"統(tǒng)一接入的方式",則使用當(dāng)前init方法即可。
manService.getMANAnalytics().init(this, getApplicationContext());
// MAN另一初始化方法,手動(dòng)指定appKey和appSecret
// 若您采用上述2.3中"統(tǒng)一接入的方式",則無需使用當(dāng)前init方法。
// String appKey = "******";
// String appSecret = "******";
// manService.getMANAnalytics().init(this, getApplicationContext(), appKey, appSecret);
// 通過此接口關(guān)閉頁(yè)面自動(dòng)打點(diǎn)功能,詳見文檔4.2
manService.getMANAnalytics().turnOffAutoPageTrack();
// 若AndroidManifest.xml 中的 android:versionName 不能滿足需求,可在此指定
// 若在上述兩個(gè)地方均沒有設(shè)置appversion,上報(bào)的字段默認(rèn)為null
manService.getMANAnalytics().setAppVersion("3.1.1");
}
}
3.3 合規(guī)解決方案
為應(yīng)對(duì)安卓端合規(guī)問題,可以將SDK初始化時(shí)機(jī)后移,不在onCreate中調(diào)用
但是需要注意
必須先調(diào)用初始化,才能調(diào)用埋點(diǎn)接口,否則會(huì)crash。 相關(guān)crash日志:java.lang.RuntimeException: getDefaultTracker error,must call setRequestAuthentication method first。
把初始化后移到隱私框之后會(huì)影響到SDK對(duì)應(yīng)用生命周期的監(jiān)控,影響1010等關(guān)鍵事件和pv相關(guān)邏輯需要應(yīng)用將SDK未監(jiān)控到的應(yīng)用生命周期補(bǔ)全.應(yīng)用可以在用戶點(diǎn)擊法律條款同意的時(shí)候?qū)? 調(diào)用方法UTMCAppStatusMonitor.getInstance().onActivityStarted(null);來補(bǔ)全漏掉的生命周期監(jiān)控。
3.4 配置渠道信息
您可以在AndroidManifest.xml中配置您的渠道信息,您只需要將<YOUR CHANNEL ID>
替換您的渠道信息即可。
【注意】SDK執(zhí)行初始化時(shí)會(huì)自動(dòng)獲取AndroidManifest.xml中的字段,并填充渠道字段;初始化完成后。若同時(shí)調(diào)用了setChannel
方法,則以setChannel
方法中的參數(shù)為準(zhǔn)。
<application ...
<meta-data
android:name="ALIYUN_MAN_CHANNEL"
android:value="<YOUR CHANNEL ID>" >
</meta-data>
</application>
3.5 SDK調(diào)試說明
在控制臺(tái)中觀察到的【今日實(shí)時(shí)】、【系統(tǒng)質(zhì)量】-【實(shí)時(shí)Crash信息】、【新版crash分析】、【系統(tǒng)質(zhì)量】-【性能分析】部分均為實(shí)時(shí)數(shù)據(jù),調(diào)試時(shí)可參考該數(shù)據(jù),驗(yàn)證環(huán)境配置及初始化是否正確。數(shù)據(jù)統(tǒng)計(jì)的準(zhǔn)確性依賴APP的常規(guī)生命軌跡,比如應(yīng)用啟動(dòng)次數(shù)依賴于用戶正常退出應(yīng)用觸發(fā)的上報(bào)策略。
4. 業(yè)務(wù)數(shù)據(jù)統(tǒng)計(jì)
4.1 會(huì)員賬號(hào)信息埋點(diǎn)
4.1.1 用戶注冊(cè)埋點(diǎn)
在用戶注冊(cè)成功之后,可使用userRegister 完成用戶注冊(cè)埋點(diǎn)。
MANService manService = MANServiceProvider.getService();
// 注冊(cè)用戶埋點(diǎn)
manService.getMANAnalytics().userRegister("usernick");
4.1.2 用戶登錄及注銷埋點(diǎn)
用戶登錄埋點(diǎn):
MANService manService = MANServiceProvider.getService();
// 用戶登錄埋點(diǎn)
manService.getMANAnalytics().updateUserAccount("usernick", "userid");
用戶注銷埋點(diǎn):
// 用戶注銷埋點(diǎn)
manService.getMANAnalytics().updateUserAccount("", "");
如果不進(jìn)行 4.1 會(huì)員賬號(hào)信息埋點(diǎn),此時(shí)不能在今日實(shí)時(shí)里看到【登錄會(huì)員】和【新注冊(cè)會(huì)員】的統(tǒng)計(jì)信息,而設(shè)備相關(guān)的統(tǒng)計(jì)【活躍用戶】和【新增用戶】可以看到。
完成上述埋點(diǎn)后,您就可以在阿里云控制臺(tái)看到相應(yīng)統(tǒng)計(jì)信息,例如下圖所示為用戶周活躍度。
4.2 頁(yè)面埋點(diǎn)
說明:Mobile Analytics SDK默認(rèn)會(huì)自動(dòng)采集Android 4.0及以上系統(tǒng)的Activity 頁(yè)面,如果不需要自動(dòng)采集可使用下面方法關(guān)閉自動(dòng)頁(yè)面打點(diǎn)。打開頁(yè)面自動(dòng)埋點(diǎn)時(shí),默認(rèn)頁(yè)面名稱為class.getSimpleName()并去除Activity
后綴。
// 關(guān)閉自動(dòng)打點(diǎn)
MANService manService = MANServiceProvider.getService();
manService.getMANAnalytics().turnOffAutoPageTrack();
為了滿足Android 4.0以下系統(tǒng)的頁(yè)面采集需求,您可按照如下的說明進(jìn)行手動(dòng)埋點(diǎn)。
【注意】:如果App中沒有進(jìn)行頁(yè)面埋點(diǎn),活躍用戶
參數(shù)不能正常統(tǒng)計(jì)。
4.2.1 手動(dòng)Activity頁(yè)面埋點(diǎn)
在Activity 的onResume 以及onPause 中分別加入pageAppear和pageDisAppear代碼,建議下述代碼可以在一個(gè)基類中做,讓其它所有的activity類都繼承這個(gè)基類,就完成了所有子類頁(yè)面埋點(diǎn)。
代碼示例如下:
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);
}
}
頁(yè)面埋點(diǎn)將影響控制臺(tái)【頁(yè)面路徑分析】、【關(guān)鍵漏斗】、【頁(yè)面留存】等指標(biāo)的報(bào)表展現(xiàn)。
4.2.2 給Activity頁(yè)面增加屬性統(tǒng)計(jì)
場(chǎng)景例子:
我們要開發(fā)一個(gè)購(gòu)物app,在購(gòu)物的app的寶貝展示頁(yè)面,我們可能想要知道,此頁(yè)面都展示了哪些商品?可以簡(jiǎn)單理解為,我們可以對(duì)采集的頁(yè)面(GoodsDetails 頁(yè)面)記錄上增加一個(gè)寶貝屬性就可以,如item_id=xxxxxx。
代碼示例如下:
// 這句話要在一個(gè)頁(yè)面的onPause 之前任何位置調(diào)用都可以
Map<String, String> lMap = new HashMap<String, String>();
lMap.put("item_id", "xxxxxx");
MANService manService = MANServiceProvider.getService();
manService.getMANPageHitHelper().updatePageProperties(lMap);
結(jié)果Log:
11-06 16:10:32.088: I/cache_log(10879): UT:...||2001||-||-||3191||item_id=xxxxxx
這里:2001 是頁(yè)面事件的ID,3191 是頁(yè)面展示的時(shí)長(zhǎng),item_id=xxxxxx 就是屬性。
4.2.3 頁(yè)面基礎(chǔ)埋點(diǎn)使用
上述是針對(duì)Activity級(jí)別的頁(yè)面埋點(diǎn),只需簡(jiǎn)單地調(diào)用pageAppear和pageDispear即可完成埋點(diǎn)對(duì)相應(yīng)的數(shù)據(jù)上報(bào),上報(bào)數(shù)據(jù)包括:頁(yè)面名稱、來源頁(yè)面名稱、頁(yè)面停留時(shí)間和額外屬性設(shè)置等。如果需要對(duì)非Activity頁(yè)面,如Fragment進(jìn)行埋點(diǎn),或者需要靈活把控頁(yè)面埋點(diǎn)上報(bào)信息,如修改上報(bào)頁(yè)面信息、對(duì)頁(yè)面停留時(shí)長(zhǎng)做特殊處理等,可以使用頁(yè)面基礎(chǔ)埋點(diǎn)的方式。通過該方式上報(bào)埋點(diǎn)數(shù)據(jù)同樣將影響控制臺(tái)【頁(yè)面路徑分析】、【關(guān)鍵漏斗】、【頁(yè)面留存】等指標(biāo)的報(bào)表展現(xiàn)。使用方式如下:
獲取基礎(chǔ)頁(yè)面打點(diǎn)對(duì)象:
// 傳入?yún)?shù)為頁(yè)面名稱
MANPageHitBuilder pageHitBuilder = new MANPageHitBuilder(String pageName);
設(shè)置來源頁(yè)面名稱(注:referPageName需要在pageName的集合中):
pageHitBuilder.setReferPage(String referPageName);
設(shè)置頁(yè)面停留時(shí)間:
pageHitBuilder.setDurationOnPage(long duration);
設(shè)置頁(yè)面屬性:
pageHitBuilder.setProperty(String key, String value);
pageHitBuilder.setProperties(Map<String, String> properties);
構(gòu)造頁(yè)面埋點(diǎn)log數(shù)據(jù):
pageHitBuilder.build();
數(shù)據(jù)上報(bào):
MANServiceProvider.getService().getMANAnalytics().getDefaultTracker().send(pageHitBuilder.build());
5 自定義事件埋點(diǎn)
自定義事件埋點(diǎn)可用于滿足用戶的定制化需求。
自定義事件可包含以下幾個(gè)部分內(nèi)容:
1.事件名稱(event_label),只能為字母、數(shù)字和下劃線組成
2.事件從開始到完成消耗的時(shí)長(zhǎng)
3.事件所攜帶的屬性
4.事件對(duì)應(yīng)的頁(yè)面
例子:
// 事件名稱:play_music
MANCustomHitBuilder hitBuilder = new MANHitBuilders.MANCustomHitBuilder("playmusic");
// 可使用如下接口設(shè)置時(shí)長(zhǎng):3分鐘
hitBuilder.setDurationOnEvent(3 * 60 * 1000);
// 設(shè)置關(guān)聯(lián)的頁(yè)面名稱:聆聽
hitBuilder.setEventPage("Listen");
// 設(shè)置屬性:類型搖滾
hitBuilder.setProperty("type", "rock");
// 設(shè)置屬性:歌曲標(biāo)題
hitBuilder.setProperty("title", "wonderful tonight");
// 發(fā)送自定義事件打點(diǎn)
MANService manService = MANServiceProvider.getService();
manService.getMANAnalytics().getDefaultTracker().send(hitBuilder.build());
自定義事件擴(kuò)展參數(shù)在控制臺(tái)【自定義事件】-【詳細(xì)數(shù)據(jù)】-【參數(shù)分析】中可查看,但查看之前請(qǐng)?jiān)凇緟?shù)分析】-【自定義事件參數(shù)管理】中添加要在控制臺(tái)顯示的參數(shù)。如果您需要對(duì)自定義事件進(jìn)行實(shí)時(shí)監(jiān)控,請(qǐng)參考【5.3 自定義性能事件】章節(jié)。
6. 如何實(shí)時(shí)驗(yàn)證數(shù)據(jù)是否正常上報(bào)
您當(dāng)前可以通過以下兩種方式進(jìn)行驗(yàn)證:
打開移動(dòng)數(shù)據(jù)分析log,查看logcat是否會(huì)出現(xiàn)如
UT:{"t":1464532680574,"ret":"","success":"success"}
的日志;注意:SDK的日志上報(bào)會(huì)有緩存和聚合,因此上報(bào)時(shí)機(jī)會(huì)比API調(diào)用時(shí)機(jī)滯后一些,可耐心等待30-60s或?qū)?yīng)用切到后臺(tái)查看。
登錄控制臺(tái)查看
活躍用戶
等實(shí)時(shí)報(bào)表;注意:活躍用戶的統(tǒng)計(jì)依賴頁(yè)面埋點(diǎn),移動(dòng)數(shù)據(jù)分析后臺(tái)會(huì)將零星的頁(yè)面埋點(diǎn)處理為噪點(diǎn),進(jìn)行過濾,因此請(qǐng)確保您有足量的頁(yè)面埋點(diǎn)事件上報(bào)(>5),另外控制臺(tái)的實(shí)時(shí)報(bào)表大概會(huì)有5min的延遲。
7. H5數(shù)據(jù)的上報(bào)
H5頁(yè)面采集并沒有單獨(dú)的SDK,依賴native進(jìn)行上傳,通過JSBridge通知給native,然后調(diào)用MAN的相應(yīng)方法,進(jìn)行數(shù)據(jù)的上報(bào)。可運(yùn)行demo請(qǐng)參考:alicloud-android-demo
7.1 代碼示例
JavaScript代碼:
// 這里通過在JS alert消息,然后在native端進(jìn)行捕獲通信
alert( "jsbridge://custom" );
Java
重寫WebChromeClient
的onAlert
方法,對(duì)于約定好的scheme,進(jìn)行攔截,然后根據(jù)相應(yīng)內(nèi)容執(zhí)行不同的方法,從而達(dá)到調(diào)用native埋點(diǎn)的目的。
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");
// 可使用如下接口設(shè)置時(shí)長(zhǎng):3分鐘
hitBuilder.setDurationOnEvent(3 * 60 * 1000);
// 設(shè)置關(guān)聯(lián)的頁(yè)面名稱:聆聽
hitBuilder.setEventPage("Listen");
// 設(shè)置屬性:類型搖滾
hitBuilder.setProperty("type", "rock");
// 設(shè)置屬性:歌曲標(biāo)題
hitBuilder.setProperty("title", "wonderful tonight");
// 發(fā)送自定義事件打點(diǎn)
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.**{*;}