SDK API (Android)
1. 權限設定說明
SDK 共需要四個權限:
權限 | 用途 |
---|---|
INTERNET | 必須權限,允許應用傳送統計數據,SDK 傳送埋點數據需要此權限 |
ACCESS_NETWORK_STATE | 必須權限,允許應用檢測網路狀態,SDK 會根據網路狀態選擇是否傳送數據 |
READ_PHONE_STATE | 可選權限,允許應用取得裝置 IMEI,採用 APP 內推廣和採集 $carrier 屬性時會用到此權限 |
ACCESS_WIFI_STATE | 可選權限,允許應用取得 MAC 網址,採用 APP 內推廣時會用到此權限 |
SDK 為簡化整合步驟,預設在 AndroidManifest.xml 中註冊了以上四個權限。如果想要去除 SDK 註冊的權限,可以使用 tools:node="remove" 設定。關於 ools:node="remove" 的詳細說明可參考Google官方文件,設定程式碼參考:
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />
2. 開啟螢幕方向的自動採集
v1.10.1 及以後的版本可以透過 enableTrackScreenOrientation() 方法開啟螢幕方向屬性的收集,螢幕方向資訊記錄在事件的 $screen_orientation 屬性中。
SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
//利用初始化的 SAConfigOptions 物件開啟螢幕方向屬性的收集
saConfigOptions.enableTrackScreenOrientation(true);
SensorsDataAPI.startWithConfiguration(this, saConfigOptions);
3. 開啟位置資訊自動採集
v1.10.1 及以後的版本可以透過 setGPSLocation() 方法,把第三方定位取得到的經緯度資訊設定給 SDK,設定之後經緯度資訊記錄在事件的 $longitude、$latitude 屬性中。
//設定經緯度
SensorsDataAPI.sharedInstance().setGPSLocation(latitude,longitude);
4. 事件時長
可以透過計時器統計事件的持續時間。首先,在事件開始時呼叫(v1.10.6 及以後版本支援) trackTimerStart("Event") ,該方法並不會真正傳送事件;在事件結束時,呼叫 trackTimerEnd("Event", properties),SDK 會觸發 "Event" 事件,並自動將事件持續時間記錄在事件屬性 "$event_duration" 中。例如記錄用戶瀏覽商品頁面的時間:
// 進入商品頁面
// 呼叫 trackTimerStart("ViewProduct") 標記事件啟動時間
SensorsDataAPI.sharedInstance().trackTimerStart("ViewProduct");
// ... 用戶瀏覽商品
// 離開商品頁
try {
// 在屬性中記錄商品 ID
JSONObject properties = new JSONObject();
properties.put("product_id", PRODUCT_ID);
// 呼叫 track,記錄 ViewProduct 事件,並在屬性 event_duration 中記錄用戶瀏覽商品的時間
SensorsDataAPI.sharedInstance().trackTimerEnd("ViewProduct", properties);
} catch (JSONException e) {
e.printStackTrace();
}
多次呼叫 trackTimerStart("Event") 時,事件 "Event" 的開始時間以最後一次呼叫時為準。
從 v3.1.5 版本開始,統計事件時長支援暫停和恢復,透過呼叫 trackTimerPause(String eventName) 和 trackTimerResume(String eventName) 來分別實作暫停和恢復。
4.1. 同名事件交叉的時長統計
預設情況下,時長的統計以事件名作為標識,相同的事件名會自動匹配 start-end,如果兩個同名事件在時間上有交叉部分,會造成錯誤匹配。為了解決此問題,從 v3.2.11 版本開始 SDK 支援同名事件交叉的時長統計,開發者需要保存 trackTimerStart() 的回傳值,以便後續針對性地進行暫停、恢復或停止。
// 開始第一個事件計時
String timer1 = SensorsDataAPI.sharedInstance().trackTimerStart("testTimer");
// 開始第二個事件計時
String timer2 = SensorsDataAPI.sharedInstance().trackTimerStart("testTimer");
//如果需要暫停第一個事件計時
SensorsDataAPI.sharedInstance().trackTimerPause(timer1);
//如果需要恢復第一個事件計時
SensorsDataAPI.sharedInstance().trackTimerResume(timer1);
// 結束第一個事件計時
SensorsDataAPI.sharedInstance().trackTimerEnd(timer1);
// 結束第二個事件計時
SensorsDataAPI.sharedInstance().trackTimerEnd(timer2);
5. 取得預設屬性
v1.8.17 及以後的版本可以呼叫 getPresetProperties() 方法取得預設屬性。
伺服器端埋點需要 App 端的一些預設屬性時,可以透過此方法取得 App 端的預設屬性,再傳給伺服器端。
//取得預設屬性
JSONObject presetProperties=SensorsDataAPI.sharedInstance().getPresetProperties();
6. 設定動態公共屬性
Android SDK v2.0.1 及以後的版本可以透過 registerDynamicSuperProperties() 方法設定動態公共屬性,設定之後 SDK 會自動取得 getDynamicSuperProperties() 中的屬性增加到觸發的事件中。
// 初始化 SDK 後,設定動態公共屬性
SensorsDataAPI.sharedInstance().registerDynamicSuperProperties(new SensorsDataDynamicSuperProperties() {
@Override
public JSONObject getDynamicSuperProperties() {
try {
// 比如 isLogin() 是用於取得用戶當前的登入狀態,SDK 會自動取得 getDynamicSuperProperties 中的屬性增加到觸發的事件中。
boolean bool = isLogin();
return new JSONObject().put("isLogin",bool);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
呼叫 registerDynamicSuperProperties() 方法設定的動態公共屬性,不能用 unregisterSuperProperty() 方法刪除
7. 取得用戶 ID
神策中每個事件都會關聯到一個ID 上,用於標識該事件所對應的用戶或裝置資訊,我們稱之為distinct_id,此值在未呼叫 SDK 中 login() 方法前,取得的是預設的 SDK 分配的匿名ID(v1.10.5 及以後的版本預設使用 AndroidId 作為匿名ID),呼叫 login() 方法後取得的是 login() 方法中傳入的值。
您可以透過 getDistinctId() 方法取得該ID:
//取得當前用戶的distinctId
String distinctId=SensorsDataAPI.sharedInstance().getDistinctId();
您也可以透過 getAnonymousId() 方法 取得神策分析 SDK 分配的匿名 ID:
//取得當前用戶的匿名id
String AnonymousId=SensorsDataAPI.sharedInstance().getAnonymousId();
8. 用戶屬性設定
8.1. 記錄初次設定的用戶屬性
對於只在首次設定時有效的屬性,我們可以使用 profileSetOnce() 記錄這些屬性。與 profileSet() 方法不同的是,如果被設定的用戶屬性已存在,則這條記錄會被忽略而不會覆蓋已有數據,如果屬性不存在則會自動建立。因此,profileSetOnce() 適用於為用戶設定首次啟動時間、首次註冊時間等屬性。例如:
try {
JSONObject properties = new JSONObject();
properties.Put("AdSource", "XXX Store");
// 設定用戶管道為,"developer@sensorsdata.cn" 的 "AdSource" 屬性值為 "XXX Store"
SensorsDataAPI.SharedInstance().ProfileSetOnce(properties);
JSONObject newProperties = new JSONObject();
newProperties.Put("AdSource", "Email");
// 再次設定用戶管道,設定無效,"developer@sensorsdata.cn" 的 "AdSource" 屬性值仍然是 "XXX Store"
SensorsDataAPI.SharedInstance().ProfileSetOnce(newProperties);
} catch (JSONException e) {
e.PrintStackTrace();
}
8.2. 數值型別的屬性
對於數值型的用戶屬性,可以使用 profileIncrement() 對屬性值進行累加。常用於記錄用戶付費次數、付費額度、積分等屬性。例如:
// 將用戶遊戲次數屬性增加一次
SensorsDataAPI.sharedInstance().profileIncrement("GamePlayed", 1);
// 增加用戶付費次數和積分
Map<String, Number> properties = new HashMap<String, Number>();
properties.put("UserPaid", 1);
properties.put("PointEarned", 12.5);
SensorsDataAPI.sharedInstance().profileIncrement(properties);
8.3. 列表型別的屬性
對於用戶喜愛的電影、用戶評價過的餐廳等屬性,可以記錄列表型屬性,例如:
Set<String> movies = new HashSet<String>();
movies.add("Sicario");
movies.add("Love Letter");
// 設定用戶觀影列表屬性,設定後屬性 "Movies" 為: ["Sicario", "Love Letter"]
SensorsDataAPI.sharedInstance().profileAppend("Movies", movies);
// 再次設定該屬性,屬性 "Movies" 為: ["Sicario", "Love Letter", "Dead Poets Society"]
SensorsDataAPI.sharedInstance().profileAppend("Movies", "Dead Poets Society");
需要注意的是,列表型屬性中的元素必須為 String 型別,且元素的值會自動去重。關於列表型限制請見數據格式。
9. 開啟點擊分析功能
版本要求
- 神策分析 1.13+
- 此功能依賴於全埋點中點擊事件採集的開啟
- 使用此功能前,確保您的 App 中設定了當前專案的 Scheme,詳細操作可參考 設定 Scheme
v1.9.0+ 版本的 SDK 支援 App 點擊分析功能,SDK 初始化前呼叫 SAConfigOptions 實例的 enableHeatMap() 方法,並且參數傳入 true 即可開啟 SDK 的點擊分析功能:
saConfigOptions.enableHeatMap(true);
開啟 App 點擊分析後,該功能預設對所有頁面上的點擊生效,如果您只是想部分頁面進行熱力圖,可以透過 addHeatMapActivity() 或 addHeatMapActivities() 方法設定:
//開啟某個 Activity 的點擊圖
SensorsDataAPI.sharedInstance().addHeatMapActivity(Class<?> activity);
//開啟多個 Activity 的點擊圖
SensorsDataAPI.sharedInstance().addHeatMapActivities(List<Class<?>> activitiesList);
10. 埋點數據的加密功能
為了加強埋點數據的安全性,神策分析支援對埋點數據進行加密,並以密文的形式對數據進行儲存和傳送。
本功能需要伺服器端的配合,可以聯繫神策客戶成功/專案經理協助開通伺服器端解密功能。預設使用 RSA 類型的私鑰,可指定使用 EC 類型私鑰。
10.1. SDK 端開啟加密
對於 4.2.0+ 版本 SDK,初始化前進行如下設定,即可開啟 SDK 的加密功能:
// 開啟加密
configOptions.enableEncrypt(true);
對於 v4.4.0+ 版本的 SDK 開始支持 EC 算法加密。在使用 enableEncrypt() 開啟加密的基礎上增加如下依賴,即可切換到 EC 算法加密:
dependencies {
// 增加 EC 演算法函式庫依賴
implementation 'com.sensorsdata.provider:SensorsAnalyticsProvider:0.0.1'
}
注意
SensorsAnalyticsProvider 封裝了支持 Android 系統的 v1.58.0.0 版本的 EC 演算法函式庫(您也可以從 GitHub 上整合此庫),該庫大小為 5MB 左右。同時該倉庫中包含眾多方法,對於大型專案,可能會遇到方法數超過 64K 的問題,需要參照 Android 官方設定文件開啟 multiDexEnabled 設定項。
10.2. 加密私鑰的驗證
使用此功能前,確保您的 App 中設定了當前專案的 Scheme,詳細操作可參考 設定 Scheme
在神策分析平台中,進入私鑰管理功能,進入路徑:「更多」 → 「基本設定」 → 「數據接入」 → 「私鑰管理」
點擊「私鑰管理」按鈕進入私鑰管理頁面
點擊對應私鑰的 QR Code 圖示,用瀏覽器掃描 QR Code 打開 App 進行私鑰驗證。
- 驗證一致,則 App 端提示 "私鑰驗證通過,所選私鑰與 App 端私鑰相同"
- 驗證不一致:則 App 端提示 “私鑰驗證不通過,所選私鑰與 App 端私鑰不相同。所選私鑰版本:v1,App 端私鑰版本:v2”
- 如果本地私鑰為空:則 App 端提示 “私鑰驗證不通過,App 端私鑰為空”
- 如果掃描私鑰為空:則 App 端提示 “私鑰驗證不通過,所選私鑰無效”
11. 開啟除錯模式動態設定功能
在神策 Android SDK (3.0.3+) 中,可以透過掃描網頁 QR Code 的方式,開啟該裝置的「除錯模式」。除錯模式的設定請參考除錯模式動態設定。
12. 啟動事件與退出事件 30 秒 session 說明
神策 SDK 為了應對多處理程序、強制退出等場景,在 v2.0.3 版本加入了30 秒的 session 機制,用戶退出 App 到後台 30 秒的時候,才會觸發退出事件,之後再啟動 App,才會觸發啟動事件,用戶如果在30 秒內打開了App,那麼是沒有對應的退出事件與啟動事件的。
另外,如果在退出 App 到後台 30 秒內,處理程序還沒有被殺掉,那麼此時會觸發退出事件並嘗試上報,如果處理程序被殺掉了,那麼退出事件會在下一次啟動時補發。所以在查看數據時,一般退出事件比啟動事件少。
13. 自定義上報策略
需要更精細地控制神策分析可以透過以下選項設定數據採集功能。
13.1. 數據採集
在每次呼叫 track()、login()、profileSet() 等方法時,神策分析 SDK 會將事件與屬性保存在 App 的儲存空間中,並會檢查如下條件,以判斷是否向伺服器上傳數據:
- 是否是WIFI/2G/3G/4G/5G網路條件
- 是否滿足傳送條件之一:
- 與上次傳送的時間間隔是否大於 flushInterval
- 本地快取 log 數量是否大於 flushBulkSize
- 事件類型為 login() 方法觸發的 $SignUp 事件
預設的 flushBulkSize 為100 條,預設的 flushInterval 為 15 秒。滿足條件後,神策分析 SDK 會將數據 gzip 壓縮後,批量傳送到神策分析。
如果追求數據採集的時效性,可以呼叫 flush() 方法,強制將數據傳送到神策分析,例如:
// 記錄用戶登入事件
SensorsDataAPI.sharedInstance().track("UserLogin");
// 強制傳送數據
SensorsDataAPI.sharedInstance().flush();
在App進入後台狀態時,SDK會呼叫 flush() 方法,將快取的數據傳送到神策分析。
13.2. 設定同步數據時的網路策略
預設情况下,在 WIFI/3G/4G/5G 網路條件下,SDK 都會嘗試去同步數據。v1.7.2 及之後的版本支援可以自定義同步數據的網路策略。
透過 setFlushNetworkPolicy() 方法來指定傳送數據的網路策略。例如:
//網路模式選項
//SensorsDataAPI.NetworkType.TYPE_2G 2G網路下傳送數據
//SensorsDataAPI.NetworkType.TYPE_3G 3G網路下傳送數據
//SensorsDataAPI.NetworkType.TYPE_4G 4G網路下傳送數據
//SensorsDataAPI.NetworkType.TYPE_5G 5G網路下傳送數據
//SensorsDataAPI.NetworkType.TYPE_WIFI WIFI網路下傳送數據
//SensorsDataAPI.NetworkType.TYPE_ALL 2G/3G/4G/5G/WIFI網路下傳送數據
//SensorsDataAPI.NetworkType.TYPE_NONE 所有網路下都不傳送數據
//指定只在 3G/4G/WIFI 條件下傳送數據。
SensorsDataAPI.sharedInstance().setFlushNetworkPolicy(SensorsDataAPI.NetworkType.TYPE_3G|SensorsDataAPI.NetworkType.TYPE_4G|SensorsDataAPI.NetworkType.TYPE_WIFI);
13.3. 設定本地快取上限值
SDK 本地數據庫預設快取數據的上限值為 32MB。 v1.7.4 及以後的版本支援透過 setMaxCacheSize() 方法來設定快取數據的上限值。參數單位 byte。
SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
//在初始化時,利用 SAConfigOptions 設定本地數據快取上限值為16MB
saConfigOptions.setMaxCacheSize(16 * 1024 * 1024);
v3.1.0 及之前的版本,設定快取方式:
//設定本地數據快取上限值為16MB
SensorsDataAPI.sharedInstance().setMaxCacheSize(16 * 1024 * 1024);
當儲存數量達到上限時,會依次丟掉舊數據,保留最新的數據
13.4. 修改 SDK 設定參數
修改 app/src/main/AndroidManifest.xml,在 <application> 標籤中,增加 <meta-data> 項,可以修改 SDK 的預設參數,支援的選項如下:
- com.sensorsdata.analytics.android.FlushInterval - 設定 SDK 的 flushInterval,單位毫秒,預設值為 15 秒;
- com.sensorsdata.analytics.android.FlushBulkSize - 設定 SDK 的 flushBulkSize,預設值為 100;
- com.sensorsdata.analytics.android.ResourcePackageName - 設定 App 的 Package Name,預設值為 Application 物件的 Package Name,當 App 的 R.* class 的 Package Name 與 Application 不同時,需要手動填入該設定;
例如,設定神策分析 SDK 的 flushInterval 為 30 秒,flushBulkSize 為 50 條,關閉 Toast 提示:
<application>
<meta-data
android:name="com.sensorsdata.analytics.android.FlushInterval"
android:value="30000" />
<meta-data
android:name="com.sensorsdata.analytics.android.FlushBulkSize"
android:value="50" />
<meta-data
android:name="com.sensorsdata.analytics.android.ShowDebugInfoView"
android:value="false" />
</application>
也可以利用程式碼,修改 FlushInterval 和 FlushBulkSize:
SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
//在初始化時,利用 SAConfigOptions 設定相關參數
// 每快取 50 條 log 傳送一次
saConfigOptions.setFlushBulkSize(50);
// 設定每 30 秒傳送一次
saConfigOptions.setFlushInterval(30000);
v3.1.0 及之前的版本,設定相關參數:
// 每快取 50 條 log 傳送一次
SensorsDataAPI.sharedInstance().setFlushBulkSize(50);
// 設定每 30 秒傳送一次
SensorsDataAPI.sharedInstance().setFlushInterval(30000);
//打開自動追蹤
SensorsDataAPI.sharedInstance().enableAutoTrack();
14. 清空本地快取事件
v3.1.5 及之後的版本可以透過 deleteAll() 方法,刪除 App 本地儲存的所有事件。
如果不是特殊要求,請不要呼叫此方法。
//刪除 App 本地儲存的所有事件
SensorsDataAPI.sharedInstance().deleteAll();
15. 設定自簽憑證
v3.1.2 及以後的版本可以透過 setSSLSocketFactory() 方法設定自簽憑證,設定自簽憑證後,SDK 內所有的 HTTPS 請求會進行此介面設定的憑證校驗。以 DER 格式的憑證為例:
try {
//構建 SSLSocketFactory 實體
SSLSocketFactory sslSocketFactory ;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// 其中 R.raw.ca 是您這邊自簽憑證的公鑰
InputStream in = getResources().openRawResource(R.raw.ca);
Certificate ca = cf.generateCertificate(in);
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(null, null);
keystore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keystore);
// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
sslSocketFactory = sslContext.getSocketFactory();
//將實體傳入神策
SensorsDataAPI.sharedInstance().setSSLSocketFactory(sslSocketFactory);
} catch (Exception e) {
e.printStackTrace();
}
關於 SSL 的更多内容可以参考Google使用文件。
16. 追蹤並進行管道匹配和回傳
從 Android v4.1.0 開始 SDK 支援 track 方法觸發的自定義事件增加管道屬性的邏輯。
16.1. 使用方法:
在初始化 SDK 的時候呼叫 SAConfigOptions.enableAutoAddChannelCallbackEvent(true) 方法來開啟功能,此功能預設是關閉的。範例如下:
private void initSensorsDataAPI() {
SAConfigOptions configOptions = new SAConfigOptions(SA_SERVER_URL);
configOptions.setAutoTrackEventType(SensorsAnalyticsAutoTrackEventType.APP_START |
SensorsAnalyticsAutoTrackEventType.APP_END |
SensorsAnalyticsAutoTrackEventType.APP_VIEW_SCREEN |
SensorsAnalyticsAutoTrackEventType.APP_CLICK)
.enableTrackAppCrash()
.enableAutoAddChannelCallbackEvent(true) //開啟新管道功能
SensorsDataAPI.startWithConfigOptions(this, configOptions);
}
16.2. 效果:
可以使用 SensorsDataAPI.shareInstance().track(eventName) 來對特定的事件進行管道追溯。
- 當次安裝、首次觸發回傳事件,記錄事件並進行管道匹配和回傳。
- 當次安裝、再次觸發回傳事件,記錄事件並進行管道匹配,匹配結果不進行回傳。
- 移除重裝、首次觸發回傳事件,記錄事件並進行管道匹配和回傳。
p.s. 上述規則適用於同名事件,不同事件之間不相互影響。
17. 入庫前修改事件資訊
v3.2.10 及以後版本,SDK 可以透過 setTrackEventCallBack() 方法過濾埋點的事件數據。
SensorsDataAPI.sharedInstance().setTrackEventCallBack(new SensorsDataTrackEventCallBack() {
/**
* 事件回呼介面
*
* @param eventName 事件名稱
* @param eventProperties 要修改的事件屬性
* @return true 表示事件將入庫, false 表示事件將被拋棄
*/
@Override
public boolean onTrackEvent(String eventName, JSONObject eventProperties) {
// 移除 BuyProduct 事件的 productID 屬性
if(eventName.equals("BuyProduct")){
eventProperties.remove("productID");
}
//
return true;
}
});
18. 開啟 Crash 資訊的自動採集
v1.8.12 及以後的版本支援 Crash 資訊收集,App Crash 時,會觸發 AppCrashed 事件,堆疊資訊記錄在 app_crashed_reason 屬性中。
SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
//利用初始化的 SAConfigOptions 物件開啟 crash 資訊採集
saConfigOptions.enableTrackAppCrash();
SensorsDataAPI.startWithConfiguration(this, saConfigOptions);
v3.1.0 及之前的版本,開啟 Crash 採集:
//開啟 crash 資訊收集
SensorsDataAPI.sharedInstance().trackAppCrash();
19. 自定義匿名 ID
預設情況下,SDK 會產生匿名 ID 並可以保證該 ID 的唯一性,如果需要替換神策預設分配的匿名 ID ,可以在初始化 SDK 之後立即呼叫 identify(“用戶自定義匿名 ID ”) 方法進行替換。
//設定自定義匿名 ID,在初始化 SDK 之後立即呼叫
SensorsDataAPI.sharedInstance().identify(“用戶自定義匿名 ID ”);
20. 關於 MultiDex
如果使用了 MultiDex ,請確保神策 Android SDK 的程式碼都指定到主 DEX 中。可以透過在 multiDexKeepProguard 裡增加如下設定:
-keep class com.sensorsdata.analytics.android.** { *; }
21. 取得應用程式簽名
在本地使用 keytool -list -v -keystore 【簽名路徑】