秒针分析SDK部署指南(Flutter版本)

目录

1.准备工作

1.1 版本限制

  • Flutter SDK:>=2.7.0 <3.0.0

  • Xcode 版本: >=12.0

  • *MZAnalyticsIOS*SDK**适用于 iOS 9+

  • *MZAnalyticsAndroid*SDK适用于Android 2.3.3(API Level 10)**及以上的设备。


###1.2 Flutter项目添加依赖

mzanalytics_mybmw 添加至pubspec.yaml引用。

dependencies:
  mzanalytics_mybmw: ^0.7.2

在flutter项目中运行 flutter pub get


1.3 集成准备

1.3.1 为应用申请AppId

在秒针分析系统中创建一款应用,您将获得一串随机的“dc-”开头的站点id,用于唯一标识您的这款应用。

1.3.2 AppId说明

appId为应用追踪的唯一标识,在系统中的站点-->站点信息 内获取。

1.3.3 需在Android 平台上获取OAID时的配置

说明: 仅支持MSA SDK 1.0.25版本(2020年12月4日发布)的OAID获取。
可依据业务需求决定是否配置。若配置,秒针分析SDK可采集OAID;若不配置,则无法获取OAID。请依据移动安全联盟官网推荐的MSA SDK集成方式引入。
移动安全联盟官网链接:www.msa-alliance.cn

1.4 Android SDK 权限配置

以下权限请根据业务需求自行配置:

权限 权限描述 是否可选 不授权的影响
INTERNET 允许程序联网 必选项 SDK无法发送数据
READ_EXTERNAL_STORAGE 允许读取SD卡上存储的数据 必选项 影响SDK读取标识唯一用户的CID
WRITE_EXTERNAL_STORAGE 允许写入信息到SD卡 必选项 影响SDK存储标识唯一用户的CID
ACCESS_NETWORK_STATE 允许检测网络连接状态 可选项 SDK不检测网络状态,直接发送数据
ACCESS_WIFI_STATE 允许读取WiFi状态变化 可选项 影响数据SDK数据发送频率
READ_PHONE_STATE 允许访问手机设备的唯一标识信息 可选项 SDK无法获取设备ID
示例代码:

<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- SD卡读写权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 网络状态相关权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 手机信息相关权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
    

1.5 运行环境配置

1.5.1 获取sdkconfig.xml文件

Android和iOS平台使用sdkconfig.xml文件用于控制设备id的采集和页面浏览的自动监听(默认不采集设备id、不自动监听页面浏览),请依据业务需要自行配置开关状态。
sdkconfig.xml下载链接 stm-collect.cn.miaozhen.com/sdkconfig.xml

1.5.2 配置sdkconfig权限(根据业务需求自行配置)

可在sdkconfig.xml的文件中对idfa(iOS)、imei(Android)、oaid(适用于Android)、adid(Android)、autotrackpage(iOS&Android)、crashDelayTime(iOS&Android)配置开关。

a. 当设置idfa、imei、oaid、adid配置中的isRequired的value为true时,获取以上id;
b. 当设置idfa、imei、oaid、adid配置中的isRequired的value为false时,不获取以上id;
c. 当需要页面自动监听时,请将autotrackpage对应的isRequired的value设置为true,否则设置为false;
d. 当需要页面自动监听,但需过滤特定页面A的自动监听时:先将autotrackpage对应的value值设置为true;再修改manualtrackpage对应的value为其页面标题,设定后,A页面不会被自动监听;
e. 当存在多个页面无需自动监听时,则在value部分输入多个页面标题即可,多个页面标题之间用中文“、”分隔;
注意:在填写无需自定动监听的页面标题时,页面标题中不可含有中文输入法下的“、”,否则会引起过滤不正确的情况。 f. 当需要延长sdk 对crash处理的时间时,修改crashDelayTime对应的value为开发者自定义的时间,默认值为200ms,最大值1000ms。

举例:以下部分是如何在sdkconfig.xml文件中配置是否采集idfa和imei的示例。

 //采集idfa的配置示例
 <argument>
    <key>idfa</key> // 该开关控制的是idfa的采集
    <value>z</value>
    <urlEncode>true</urlEncode>
    <isRequired>true</isRequired> //idfa的 isRequired的value为true,表示sdk会采集idfa
</argument>

//不采集imei的配置示例
<argument>
    <key>imei</key> // 该开关控制的是imei的采集
    <value>0c</value>
    <urlEncode>true</urlEncode>
    <isRequired>false</isRequired> //imei的 isRequired的value为false,表示sdk不会采集imei
</argument>

1.5.3 iOS运行环境配置

打开flutter项目下的iOS工程根目录下的Runner.xcworkspace,将sdkconfig.xml文件拖到工程路径中,并在Destination中勾选Copy items if neededAdd to targets中勾选 Runner,点击Finish即可。

1.5.4 Android运行环境配置

a. 进入到android项目目录`app/src/main中`。       
b. 在`main`目录下新建assets文件夹,将sdkconfig.xml放到assets文件夹中。      
c. (可选项)在`AndroidManifest.xml`文件的application标签中添加channelId(请根据业务需求将xxxxx自行修改为实际使用的分包推广的渠道名称): 
   
     <meta-data
       android:name="com.miaozhen.mzsdk.channelId"
       android:value="xxxxx" />

2. 秒针分析SDK使用

flutter代码中引入头文件

import 'package:mzanalytics_mybmw/mzanalytics_mybmw.dart';

2.1 代码埋点调用示例

2.1.1 初始化SDK (必选埋点)

说明:
a. 为了保证所有采集数据成功发送,建议将sdk初始化方法放在获取设备id、存储、隐私条例同意等权限后尽早执行,若将sdk 初始化方法放在权限授权之前,会影响imei、旧访客id数据的获取;
b. sdk初始化方法仅需要调用一次即可;
c. 请在调用秒针分析sdk的所有方法之前,先调用sdk初始化方法,若将sdk初始化方法放在页面浏览、自定义事件、高级事件等方法之后执行,那么在sdk初始化之前产生的数据会丢失;
d. 实际使用时将appid参数替换为申请的appid (Android和iOS必传appid参数,否则sdk无法初始化)。

接口定义:

Future<void> appid(String appid)

参数说明:

参数 类型 说明 是否必填
appid String 为创建站点时的站点id 必填
示例代码 :   
//站点id为您实际使用的appid; 

MzanalyticsMybmw.appid("2814");

2.1.2 App崩溃采集 (可选埋点)

说明:
a. 为了保证sdk可以将app的崩溃信息采集完全,请将秒针分析sdk的初始化方法放在所有第三方sdk的初始化方法之后;
b. 正确开启app崩溃采集的流程是:先导入头文件,在程序入口处注册监听方法,在秒针分析sdk的初始化方法之后,开启崩溃采集开关,方可正确采集app的崩溃信息。

  // 1. 导入头文件
import 'package:mzanalytics_mybmw/mzanalytics_bugService.dart';
// 2.程序入口处注册监听方法:
void main() =>
    Mzanalytics_bugService.exceptionListener(() => runApp(new MaterialApp(
          title: 'Navigation Basics',
          home: new MyApp(),
        )));

接口定义:

   Future<void> enableExceptionService(bool enabled)   

参数说明:

参数 类型 说明 是否必填
enabled Bool 是否开启崩溃采集的开关 必填
   示例代码 : 
  // 3.打开崩溃采集开关
  MzanalyticsMybmw.enableExceptionService(true);

2.1.3 开发者手动传入App崩溃信息 (可选埋点)

说明:
a. 秒针分析sdk支持开发者通过以下api手动传入崩溃信息;

接口定义:

Future<void> trackException(Map exception)

参数说明:

参数 类型 说明 是否必填
name String 手动传入的崩溃信息名称 必填
reason String 手动传入的崩溃信息名称 必填
stack String 崩溃堆栈信息 必填
customerror String 异常类型,手动 0,自动1 必填
 示例代码 : 

Map exceptionMap = {
        "name": errorname,
        "reason": errorMessage,
        "stack": stack,
        "customerror": "0"
  };

  MzanalyticsMybmw.trackException(exceptionMap);

2.1.4 页面浏览 (可选埋点,与 2.2 开启页面自动监听功能二选一)

说明:
a. 用于监测页面浏览行为,在需要监测的页面启动方法中添加如下代码后,即可采集用户的页面浏览行为;
b. 如需在页面浏览数据上报时,需携带更多的信息,可使用自定义维度和自定义指标。 【具体使用规则见文档: 2.1.11 自定义维度和指标的使用方法

接口定义:

Future<void> trackPageView(Map parameter)

参数说明:

参数 类型 说明 是否必填
dt String 需监测的页面名称 必填
customDimMetrics Map 自定义维度和自定义指标集合名称 可选,业务场景中无需携带自定义维度和自定义指标时,customDimMetrics不传即可

customDimMetrics中需传递的自定义参数说明:

参数 类型 说明 是否必填
cd1~25 String 自定义维度,最多25个 选填
cm1~25 String类型的数值 自定义指标,最多25个 选填
//不传递自定义维度和自定义指标的示例代码:
MzanalyticsMybmw.trackPageView({"dt":"首页"});//页面名称,如首页


//传递自定义维度和自定义指标的示例代码:
MzanalyticsMybmw.trackPageView({
                   "dt": "首页", 
                 "CustomDimMetrics": {
                   "cd1": "ID88888",//自定义维度1的名称,如浏览该页面的用户Id              
                   "cd2": "小明机器人", //自定义维度2的名称,如浏览页面的用户名称
                   "cm1": "1" //自定义指标的数值,如用户个数 1
                 }  
                });

2.1.5 自定义事件 (可选埋点)

说明:
a. 在需要统计与用户交互动作的按钮或其他控件的点击方法中,添加自定义事件埋点; b. 如需在自定义事件数据上报时,需携带更多的信息,可使用自定义维度和自定义指标。【具体使用规则见文档: 2.1.8 自定义维度和指标的使用方法

接口定义:

Future<void>  trackEvent(Map parameter)

参数说明:

参数 类型 说明 是否必填
ec String 事件分类 必填
ea String 事件动作 必填
el String 事件标签 选填
ev String类型的数值 事件价值 选填
customDimMetrics Map 自定义维度和自定义指标集合名称 可选,没有自定义维度和自定义指标时,customDimMetrics不传即可

customDimMetrics中需传递的自定义参数说明:

参数 类型 说明 是否必填
cd1~25 String 自定义维度,最多25个 选填
cm1~25 String类型的数值 自定义指标,最多25个 选填
//不传递自定义维度和自定义指标的示例代码:
MzanalyticsMybmw.trackEvent({
               "ec": "领取奖励",//事件分类名称,如领取奖励
               "ea": "Click",//事件动作名称,如Click
               "el": "任务箱领取奖励", //事件标签,如任务箱领取奖惩
               "ev": "10" //事件价值,如10
             });
             
//传递自定义维度和自定义指标的示例代码:
MzanalyticsMybmw.trackEvent({
               "ec": "领取奖励",
               "ea": "Click",
               "el": "任务箱领取奖励",
               "ev": "10",
             "CustomDimMetrics": { 
               "cd3": "首次登陆任务箱",  //自定义维度名称,如任务箱名称
               "cm2": "2"  //自定义指标数值,如打开的任务箱个数,共2个
             }
            });

2.1.6 高级事件(可选埋点)

说明:
a. 如需统计更多维度、指标的用户交互事件,用户可使用高级事件埋点设定所要统计的维度、指标;

b. 如需在高级事件数据上报时,需携带更多的信息,可使用自定义维度和自定义指标。【具体使用规则见文档中:2.1.8 自定义维度和指标的使用方法

接口定义:

Future<void>  trackSiteCustomEvent(Map parameter) 

参数说明:

参数 类型 说明 是否必填
customEvent Map 包含高级事件id、以及高级事件维度、指标数均以实际在系统中创建的⾼级事件为准 必填
customDimMetrics Map 自定义维度和自定义指标集合名称 可选,没有自定义维度和自定义指标时,customDimMetrics可不传

CustomEvent中需传递的高级事件参数说明:

参数 类型 说明 是否必填
caid String类型的数值 高级事件id 必填,需在秒针分析系统中注册该事件
cal1~20 String 高级事件维度,最多20个 选填
cav1~20 String类型的数值 高级事件指标,最多20个 选填

customDimMetrics中需传递的自定义参数说明:

参数 类型 说明 是否必填
cd1~25 String 自定义维度,最多25个 选填
cm1~25 String类型的数值 自定义指标,最多25个 选填
 //不传递自定义维度和指标的示例代码:
 MzanalyticsMybmw.trackSiteCustomEvent({
                 "CustomEvent": {
                   "caid": "1", //高级事件Id,如 1
                   "cal1": "2020/01/10",  //高级事件维度1,如注册的时间
                   "cal2": "北京",//高级事件维度2,如注册的地点
                   "cav1": "20"  //高级事件指标,如 触发注册事件的用户年龄
                 }
               });


 //传递自定义维度和指标的示例代码:
 MzanalyticsMybmw.trackSiteCustomEvent({
                 "CustomEvent": {
                   "caid": "1",
                   "cal1": "2020/01/10",
                   "cal2": "北京",
                   "cav1": "20"
                 },
                 "CustomDimMetrics": {
                   "cd1": "ID88888",//自定义维度,如触发注册事件的用户Id
                   "cm1": "1"//自定义指标,如触发高级事件的用户数1
                 }
               });

2.1.7 设置CAID (可选埋点,仅iOS端)

说明:可将caid通过以下api传入(由信通院的第三方sdk生成),用于秒针分析的归因计算。

接口定义:
  static Future<void> setCAIDandVersion(Map parameter)

参数说明:

参数 类型 说明 是否必填
currentCAID String 当前版本的caid 值 必填
currentCAIDVersion String 当前caid对应的版本号 必填
lastCAID String 上一个版本的caid 值 必填
lastCAIDVersion String 上一个caid对应的版本号 必填
示例代码:
 
MzanalyticsMybmw.setCAIDandVersion({
                          'currentCAID': 'e2b3d6e424963853821b2188cc5a00',
                          'currentCAIDVersion': '20210622',
                          'lastCAID': 'e2b3d6e424963853821b2188c11111',
                          'lastCAIDVersion': '20210303'
                    });

2.1.8 心跳事件 (可选埋点)

说明:可在用户退出App或页面时埋点该事件,用于统计更准确的App使用时长。

接口定义:

 Future<void> trackPulse()

参数说明: 无

示例代码:

 MzanalyticsMybmw.trackPulse();

2.1.9 获取访客id(可选调用api,不用于sdk统计数据)

说明:访客id是秒针分析标识唯一用户的id,该接口可用于获取秒针分析SDK生成的cid。

接口定义:

  Future<String> getCid() 

参数说明: 无

示例代码:

 MzanalyticsMybmw.getCid();

说明:用于统计已添加秒针分析广告参数后的deeplink链接的监听,若不添加秒针广告参数,普通的deeplink链接吊起app的行为不会被统计。

 接口定义:
 static Future<void> onDeepLinkReceived(String url)     

参数说明:

参数 类型 说明
url String deeplink跳转后收到的url(必填)
 示例代码:      
//deeplink      
  MzanalyticsMybmw.onDeepLinkReceived(url);          

url示例:

mltsite://event/page/view/last?name=ceshi&age=30&mz_ca=2220134&mz_sp=35790   

格式规范:
scheme://host/path?key1=value1&key2=value2&mz_ca=2220134&mz_sp=35790 说明:

    a. 问号?前面请根据实际使用情况自行定义;       
    b. 问号后面key和value连接必须用=,不同key-value拼接必须用&;        
    c. 同时存在mz_ca和mz_sp归为deeplink流量,否则归为普通流量;    
    d. mz_ca合法是7位,mz_sp合法是5位。

2.1.11 自定义维度和指标的使用方法(可选埋点)

在页面浏览、自定义事件、 高级事件数据上报时,需额外携带其他信息时,则可以使用秒针分析提供的自定义维度和自定义指标功能。使用自定义维度和自定义指标需遵循如下规则:

a. 在同一个事件中需携带不同的自定义维度和自定义指标时,各个自定义维度和自定义指标的key不应相同,否则会造成相同key对应的value被覆盖的情况,正确的使用方法是分别使用key为cd1、cd2...cd25来存储不同的维度名称,自定义指标同理。

举例1. 假设在app中存在页面名称为首页的页面,用户可在该页面领取任务奖励。
数据分析需求:当首页被打开后在页面浏览数据上报时,携带打开这个页面的用户账号id、昵称。
正确的方案是:

MzanalyticsMybmw.trackPageView({
                       "dt": "首页", 
                     "CustomDimMetrics": {
                          "cd1":"ID88888", //使用cd1 传入用户Id
                          "cd2": "小明机器人"   //使用cd2 传入用户昵称              
                     }  
                        });

b. 不同事件上报不同的自定义维度和自定义指标时,各个自定义维度和自定义指标的key不应相同,若都使用同一个key,所有同key的自定义维度数据会和不同事件的数据关联在一起,造成运营分析困难。

举例2:假设在app的首页中用户可以在完成特定任务后,点击任务箱领取按钮获得奖励。

数据分析需求:用户既需要监听首页的浏览事件,在页面浏览数据上报时携带用户账号Id、昵称,也需要监听首页领取奖励按钮的点击事件,并同时上报已领取的任务箱名称和任务箱的个数。
正确的方案是:用户账号Id、昵称和任务箱名称采用不同的自定义维度key,自定义指标同理。

//页面埋点部分参考举例1的代码示例,下方仅提供按钮点击事件的埋点代码示例
MzanalyticsMybmw.trackEvent({
                   "ec": "领取奖励",
                   "ea": "Click",
                   "el": "任务箱领取奖励",
                   "ev": "1",
                 "CustomDimMetrics": {
                   "cd3": "完成资料填写任务箱",  //在cd1和cd2已存在时,应采用cd3等
                   "cm2": "2" // 任务箱的个数1
             }
       });

c. 所有的页面浏览、自定义事件、高级事件中都需要携带相同的信息时,可设置全局的自定义维度和自定义指标,该全局设置在单次app的生命周期中生效(参考文档部分:2.2.3 自定义维度和指标的使用方法

2.1.12 开启调试日志

说明:该api是用于输出秒针分析sdk的调试日志,默认关闭。建议在集成调试时打开该开关以测试集成效果,在正式发版时,请注释掉该方法
接口定义:

 static Future<void> logEnabled(bool enabled)

参数说明:

参数 类型 说明
enabled bool 传true打开日志调试开关;默认值为false,关闭日志调试开关(必填)
 示例代码:      
 MzanalyticsMybmw.logEnabled(true);          

2.2 开启页面自动监听功能(可选,可与2.1.2 页面浏览二选一)

需使用navigatorObservers方法来实现页面的自动监听功能。
说明: 必须在 sdkconfig.xml的开关配置文件中,将autotrackpage值设置为true才能启用页面自动监听功能。

2.2.1 注册页面监听

首先需要在启动页的main.dart中的主Widget build(BuildContext context)方法中按如下方式添加观察者对象方法:mz_navigation_history_observer()

示例如下:

@override
  Widget build(BuildContext context) {

    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "首页",
      theme: ThemeData(
        primaryColor: Color(0xff303030),
        scaffoldBackgroundColor: Color(0xffebebeb),
        cardColor: Color(0xff393a3f)
      ),
      routes: routeTable,
      home: LoadingPage(),
      navigatorObservers:[mz_navigation_history_observer()],
       
      
    );
  }

2.2.2 页面跳转示例代码

在App中需要监听跳转页面名称的`Navigator.of`方法中需传入对应的页面名称参数。 
示例方法1:

Navigator.of(_ctx).push(MaterialPageRoute(settings: RouteSettings(name: "首页"), builder: (_ctx) => page));
示例方法2:

Navigator.of(_ctx).pushNamed("首页");

2.2.3 设置全局自定义维度和自定义指标(可选埋点)

调用如下api后,会设置全局的自定义维度和自定义指标,即在每一个上报的页面浏览、自定义事件、高级事件中都会携带已设置的全局自定义维度和指标。
作用域:仅作用于app单次的生命周期内。
优先级说明:若全局自定义维度、自定义指标与代码埋点中传入的维度和指标同key时,代码埋点中的同key的维度和指标优先级更高。即代码埋点中若传入了cd1、cm1,同时已设置全局的cd1、cm1时,代码埋点传入的cd1、cm1会上报,全局的cd1、cm1会被覆盖(不会被上报)。

2.2.3.1 设置全局自定义维度cd
 接口定义:

  Future<void> setCd(String cdKey, String cdValue)

参数说明:

参数 类型 说明 是否必填
cdKey1~25 String 自定义维度key( 取值范围cd1-25 ) 必填
cdValue String 自定义维度value 必填
示例代码:

try {
 MzanalyticsMybmw.setCd("cd1", "ID12930");//携带用户账号ID维度
} on PlatformException {}
2.2.3.2 设置全局自定义指标cm
接口定义:

  Future<void> setCm(String cmKey, String cmValue)

参数说明:

参数 类型 说明 是否必填
cmKey1~25 String 自定义指标key( 取值范围cm1-25 ) 必填
cmValue String类型的数值 自定义指标value 必填
示例代码:

try {
  MzanalyticsMybmw.setCm("cm1", "1001");
} on PlatformException {}
2.2.3.3 删除App缓存中的全局自定义维度cd

说明:调用该接口删除app缓存中的自定义维度cd1~25

接口定义:

  Future<void> deleteCd(String cdKey)    

参数说明:

参数 类型 说明 是否必填
cdkey1~25 String 自定义维度key( 取值范围cd1-25 ) 必填
示例代码:

try {
  MzanalyticsMybmw.deleteCd("cd1");
} on PlatformException {}
2.2.3.4 删除App缓存中的全局自定义维度cm

说明:调用该接口删除app缓存中的自定义指标cm1~25

接口定义:

  Future<void> deleteCm(String cmKey)    

参数说明:

参数 类型 说明 是否必填
cmKey1~25 String 自定义指标key( 取值范围cm1-25 ) 必填
示例代码:

try {
  MzanalyticsMybmw.deleteCm("cm1");
} on PlatformException {}
2.2.3.5 获取全局自定义维度cd和自定义指标cm集合

说明:调用该接口获取app缓存中的全局自定义维度cd和自定义指标cm。

接口定义:

Future<Map> getCdAndCm()    


示例代码:

try {
   Map map = MzanalyticsMybmw.getCdAndCm();
} on PlatformException {}

3. 给开发者的测试建议

建议用安卓官方开发工具Android Studio、iOS官方开发工具Xcode进行集成调试,观察log输出,以保证sdk的正确集成。(若开发者使用了其他调试工具,请自行调试,遇到问题时,可及时联系秒针分析)

Miaozhen analysis SDK deployment guide (Flutter test version)

Content

1. Preparations

1.1 Version restrictions

  • Flutter SDK: >=2.7.0.

  • Xcode version: >=12.0.

  • MZAnalyticsIOSSDK applies to iOS 9+.

  • MZAnalyticsAndroidSDK is applicable to devices with Android 2.3.3 (API Level 10) and above.


###1.2 Flutter project add dependency

Add mzanalytics_mybmw to pubspec.yaml reference.

dependencies:
  mzanalytics_mybmw: ^0.7.2

Run flutter pub get in flutter project


1.3 Integration Preparation

1.3.1 Apply for AppId for the application

Create an application in the Miaozhen analysis system, and you will get a string of random site id starting with "dc-" to uniquely identify your application.

1.3.2 AppId description

AppId is the unique identifier for application tracking, which can be obtained in the site --> site information in the system.

1.3.3 Configuration when obtaining OAID on Android platform

Note: Only support the OAID acquisition of MSA SDK 1.0.25 version (released on December 4, 2020).
You can decide whether to configure or not according to business needs. If configured, Miaozhen Analysis SDK can collect OAID; if not configured, OAID cannot be acquired. Please follow the MSA SDK integration method recommended by the Mobile Security Alliance official website. Mobile Security Alliance official website link: www.msa-alliance.cn

1.4 Android SDK permission configuration

Please configure the following permissions according to business requirements:

Permission Permission description Whether it is optional The impact of non-authorization
INTERNET Allow program networking Required SDK cannot send data
READ_EXTERNAL_STORAGE Allows to read the data stored on the SD card Required Affects the SDK to read the CID of the unique user and the historical data of the sending failure
WRITE_EXTERNAL_STORAGE Allow to write information to SD card Required Affects the CID of the unique user identified by the SDK storage and the data writing that fails to be sent
ACCESS_NETWORK_STATE Allow detection of network connection status Optional SDK does not detect network status, and sends data directly
ACCESS_WIFI_STATE Allow to read WiFi status changes Optional Affect the data sending frequency of the data SDK
READ_PHONE_STATE Allow access to the unique identification information of the mobile device Optional SDK cannot obtain the device ID
Sample code:

<!-- Network permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- SD card read and write permissions -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Network status related permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Mobile phone information related permissions -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
----

1.5 Operating environment configuration

1.5.1 Obtain the sdkconfig.xml file

Android and iOS platforms use the sdkconfig.xml file to control the collection of device IDs and the automatic monitoring of page browsing (the device ID is not collected by default, and the page browsing is not automatically monitored). Please configure the switch status by yourself according to business needs.
sdkconfig.xml download link stm-collect.cn.miaozhen.com/sdkconfig.xml

1.5.2 Configure sdkconfig permissions (configure yourself according to business needs)

In the sdkconfig.xml file, idfa (iOS), imei (Android), oaid (Android), adid (Android), autotrackpage (iOS&Android) ) Configuration switch.

a. When the value of isRequired in the idfa, imei, oaid, and adid configuration is set to true, get the above id;
b. When the value of isRequired in the idfa, imei, oaid, and adid configuration is set to false, the above id will not be obtained;
c. When you need to automatically monitor the page, please set the value of isRequired corresponding to the autotrackpage to true, otherwise set it to false;
d. When the page needs to be automatically monitored, but the automatic monitoring of a specific page A needs to be filtered: first set the value value corresponding to autotrackpage to true; then modify the value corresponding to manualtrackpage to be the page title. After setting, page A will not Be automatically monitored;
e. When there are multiple pages without automatic monitoring, just enter multiple page titles in the value section, and separate multiple page titles with Chinese ",".
Note: When filling in the page title that does not need to be automatically monitored, the page title must not contain "," under the Chinese input method, otherwise it will cause incorrect filtering.

Example: The following part is an example of how to configure whether to collect idfa and imei in the sdkconfig.xml file.

  //Collect idfa configuration example
  <argument>
     <key>idfa</key> // This switch controls the collection of idfa
     <value>z</value>
     <urlEncode>true</urlEncode>
     <isRequired>true</isRequired> //The value of isRequired of idfa is true, indicating that the SDK will collect idfa
 </argument>

 //Configuration example without collecting imei
 <argument>
     <key>imei</key> // This switch controls the collection of imei
     <value>0c</value>
     <urlEncode>true</urlEncode>
     <isRequired>false</isRequired> //The value of isRequired of imei is false, which means that the SDK will not collect imei
 </argument>

1.5.3 iOS operating environment configuration

Open the Runner.xcworkspace in the root directory of the iOS project under the flutter project, drag the sdkconfig.xml file to the project path, and check Copy items if needed and Add to targets in the Destination Select Runner and click Finish.

1.5.4 Android operating environment configuration

a. Enter the android project directory `app/src/main`.
b. Create a new assets folder in the `main` directory, and put sdkconfig.xml in the assets folder.
c. (Optional) Add channelId to the application tag of the `AndroidManifest.xml` file (please modify xxxxx to the actual subcontract promotion channel name according to business requirements):
   
     <meta-data
       android:name="com.miaozhen.mzsdk.channelId"
       android:value="xxxxx" />

2. Miaozhen analysis SDK usage

Introducing header files in flutter code

import'package:mzanalytics_mybmw/mzanalytics_mybmw.dart';

2.1 Code buried point call example

2.1.1 Initialize SDK (required embedding point)

Description:
a. In order to ensure that all collected data is successfully sent, it is recommended that the SDK initialization method be executed as soon as possible after obtaining the device ID, storage, privacy regulations and other permissions;
b. If the SDK initialization method is placed before authorization, it will affect the acquisition of imei and old visitor id data;
c. If the sdk initialization method is executed after page browsing, custom events, advanced events, etc., then the data before the sdk initialization will be lost;
d. **Replace appid with the actual appid during actual use (appid is a required param of Android and iOS ). **

Interface definition:

 Future<void> appid(String appid)

Parameter Description:

Parameter Type Description Is it required
appid String is the site id when creating the site required
Sample code:
//The site id is the appid you actually use;

MzanalyticsMybmw.appid("2814");

2.1.2 App crash collection (optional buried point)

Description:

a. In order to ensure that the SDK can collect the crash information of the app completely, please put the initialization method of the second hand analysis SDK after the initialization method of all third-party SDKs;

b. The process of correctly opening app crash collection is: first import the header file, register the monitoring method at the program entrance, after Miaozhen analyzes the SDK initialization method, turn on the crash collection switch, The crash information of the app can be collected correctly.

// 1. Import the header file
import'package:mzanalytics_mybmw/mzanalytics_bugService.dart';
// 2. Register the monitoring method at the program entrance:
void main() =>
Mzanalytics_bugService.exceptionListener(() => runApp(new MaterialApp(
title:'Navigation Basics',
home: new MyApp(),
)));

Interface definition:

static Future<void> enableExceptionService(bool enabled)

Parameter Description:

| Parameter | Type | Description | Is it required |
| ----- | -------- | ------ | ------ |
| enabled | Bool | Whether to enable the switch of crash collection | Required |

Sample code:

  // 3. Turn on the crash collection switch
      MzanalyticsMybmw.enableExceptionService(true);

2.1.3 Developers manually input App crash information (optional buried point)

Description:

a. Miaozhen analysis SDK supports developers to manually pass in crash information through the following api;

Interface definition:

static Future<void> trackException(Map exception)

Parameter Description:

| Parameter | Type | Description | Is it required |
| ----- | -------- | ------ | ------ |
| name | String | The name of the crash information manually passed in | Required |
| reason | String | The name of the manually passed crash information | Required |
| stack | String | Crash stack information | Required |
| customerror | String | Exception type, manual 0, automatic 1| Required |

Sample code:

Map exceptionMap = {
"name": errorname,
"reason": errorMessage,
"stack": stack,
"customerror": "0"
      };

  MzanalyticsMybmw.trackException(exceptionMap);

2.1.4 Page Browsing (Optional burying point, choose one of the two with 2.2 Turn on the page automatic monitoring function)

Description:
a. Used to monitor page browsing behavior. After adding the following code to the page startup method that needs to be monitored, the user's page browsing behavior can be collected;

b. If you need to carry more information when reporting page browsing data, you can use custom dimensions and custom indicators. **For specific usage rules, please refer to the document: 2.1.8 How to use custom dimensions and indicators**

Interface definition:

Future<void> trackPageView(Map parameter)

Parameter Description:

Parameter Type Description Is it required
dt String The name of the page to be monitored Required
customDimMetrics Map Custom dimension and custom indicator collection name Optional, if custom dimensions and custom indicators do not need to be carried in the business scenario, customDimMetrics does not need to be transmitted

Description of custom parameters to be passed in customDimMetrics:

Parameter Type Description Required
cd1~25 String Custom dimensions, up to 25 Optional
cm1~25 String type value Custom indicators, up to 25 Optional
Sample code that does not pass custom dimensions and custom metrics:
MzanalyticsMybmw.trackPageView({"dt":"Homepage"});//page name, such as homepage


Sample code for passing custom dimensions and custom metrics:
 MzanalyticsMybmw.trackPageView({
                   "dt": "Home",
                 "CustomDimMetrics": {
                   "cd1": "ID88888",//The name of custom dimension 1, such as the ID of the user who browses the page
                   "cd2": "Xiaoming Robot", //The name of custom dimension 2, such as the name of the user who browses the page
                   "cm1": "1" //The value of the custom indicator, such as the number of users 1
                 }
});

2.1.5 Custom event (optional buried point)

Description:
a. In the click method of buttons or other controls that need to count and interact with the user, add custom event burying points; b. If you need to carry more information when reporting custom event data, you can use custom dimensions And custom indicators. **For specific usage rules, please refer to the document: 2.1.11 How to use custom dimensions and indicators**

Interface definition:

Future<void> trackEvent(Map parameter)

Parameter Description:

| Parameter | Type | Description | Is it required |
| ------------- | --------- | ---------------- |---------|
| ec | String | Event category |Required |
| ea | String | Event Action |Required |
| el | String | Event Label | Optional |
| ev | String type value | Event value | Optional |
| customDimMetrics | Map | Custom dimension and custom metric collection name | Optional, if there is no custom dimension and custom metric, customDimMetrics can not be transmitted |

Description of custom parameters to be passed in customDimMetrics:

| Parameter | Type | Description | Required |
| --------- | ------- | ---- | --------- |
| cd[1~25] | String | Custom dimensions, up to 25 | Optional |
| cm[1~25] | String type value | Custom indicators, up to 25 | Optional |


 Sample code that does not pass custom dimensions and custom metrics:
MzanalyticsMybmw.trackEvent({
               "ec": "Receiving reward",//Event category name, such as receiving reward
               "ea": "Click",//Event action name, such as Click
               "el": "task box to receive rewards", //event label, such as task box to receive rewards and punishments
               "ev": "10" //The event value, such as 10
             });
             
Sample code for passing custom dimensions and custom metrics:
MzanalyticsMybmw.trackEvent({
               "ec": "Receive Award",
               "ea": "Click",
               "el": "Task box to receive rewards",
               "ev": "10",
             "CustomDimMetrics": {
               "cd3": "Login to task box for the first time", //Custom dimension name, such as task box name
               "cm2": "2" //Custom indicator value, such as the number of open task boxes, total 2
             }
             });

2.1.6 Advanced event (optional buried point)

Description: a. If you need to count user interaction events with more dimensions and indicators, users can use advanced event burying points to set the dimensions and indicators to be counted;

b. If you need to carry more information when reporting advanced event data, you can use custom dimensions and custom indicators. 【For specific usage rules, please refer to the document: 2.1.8 How to use custom dimensions and indicators

Interface definition:

Future<void> trackSiteCustomEvent(Map parameter)

Parameter Description:

Parameter Type Description Required
customEvent Map Contains advanced event id, advanced event dimensions, and the number of indicators are subject to the actual advanced event created in the system Required
customDimMetrics Map Custom dimension and custom metric collection name Optional, if there is no custom dimension and custom metric, customDimMetrics can not be passed

Description of advanced event parameters to be passed in CustomEvent:

Parameter Type Description Required
caid String type value Advanced event id Required, this event needs to be registered in the Miaozhen analysis system
cal1~20 String Advanced event dimensions, up to 20 Optional
cav1~20 String type value Advanced event indicators, up to 20 Optional

Description of custom parameters to be passed in customDimMetrics:

Parameter Type Description Required
cd1~25 String Custom dimensions, up to 25 Optional
cm1~25 String type value Custom indicators, up to 25 Optional
 Sample code without passing custom dimensions and metrics:
 MzanalyticsMybmw.trackSiteCustomEvent({
                 "CustomEvent": {
                   "caid": "1", //Advanced event ID, such as 1
                   "cal1": "2020/01/10", //Advanced event dimension 1, such as registration time
                   "cal2": "Beijing",//Advanced event dimension 2, such as registered location
                   "cav1": "20" //Advanced event indicators, such as the age of the user who triggered the registration event
                 }
               });


Sample code for passing custom dimensions and metrics:
 MzanalyticsMybmw.trackSiteCustomEvent({
                 "CustomEvent": {
                   "caid": "1",
                   "cal1": "2020/01/10",
                   "cal2": "Beijing",
                   "cav1": "20"
                 },
                 "CustomDimMetrics": {
                   "cd1": "ID88888",//Custom dimensions, such as the ID of the user who triggered the registration event
                   "cm1": "1"//Custom indicators, such as the number of users triggering advanced events 1
                 }
               });

2.1.7 Set CAID (optional buried point, iOS only)

Note: The caid can be passed in through the following api (generated by the third-party SDK of the Institute of Information and Communication Technology) for the attribution calculation of Miaozhen analysis.

Interface definition:
  static Future<void> setCAIDandVersion(Map parameter)

Parameter Description:

Parameters Type Description Required
currentCAID String The caid value of the current version Required
currentCAIDVersion String The version number corresponding to the current caid Required
lastCAID String The caid value of the previous version Required
lastCAIDVersion String The version number corresponding to the last caid Required
Sample code:
     
MzanalyticsMybmw.setCAIDandVersion({
'currentCAID':'e2b3d6e424963853821b2188cc5a00',
'currentCAIDVersion': '20210622',
'lastCAID':'e2b3d6e424963853821b2188c11111',
'lastCAIDVersion': '20210303'
                        });                  

2.1.8 Heartbeat event (optional buried point)

Note: This event can be buried when the user exits the App or page, and used to calculate more accurate App usage time.

Interface definition:

 Future<void> trackPulse()

Parameter description: None

Sample code:

 MzanalyticsMybmw.trackPulse();

2.1.9 Get visitor id (optional call api, not used for sdk statistics)

Note: The visitor id is the id of the unique user identified by Miaozhen Analysis. This interface can be used to obtain the cid generated by Miaozhen Analysis SDK.

Interface definition:

  Future<String> getCid()

Parameter description: None

Sample code:

 MzanalyticsMybmw.getCid();

Note: It is used to count the monitoring of deeplink links after Miaozhen analysis advertising parameters have been added. If Miaozhen advertising parameters are not added, the behavior of ordinary deeplink links lifting the app will not be counted.

 Interface definition:
 static Future<void> onDeepLinkReceived(String url)

Parameter Description:

Parameters Type Description
url String URL received after deeplink redirection (required)
 Sample code:
//deeplink
  MzanalyticsMybmw.onDeepLinkReceived(url);

url example:

mltsite://event/page/view/last?name=ceshi&age=30&mz_ca=2220134&mz_sp=35790

Format specification: scheme://host/path?key1=value1&key2=value2&mz_ca=2220134&mz_sp=35790 Description:

    a. Question mark? Please define your own according to the actual usage;
    b. After the question mark, the key and value must be connected with =, and the different key-value must be connected with &;
    c. Both mz_ca and mz_s existp is classified as deeplink traffic, otherwise it is classified as ordinary traffic;
    d. The legal mz_ca is 7 digits, and the legal mz_sp is 5 digits.

2.1.11 How to use custom dimensions and indicators (optional buried points)

When you need to carry additional information during page browsing, custom events, and advanced event data reporting, you can use the custom dimensions and custom indicators provided by Miaozhen Analysis. Use custom dimensions and custom indicators to follow the following rules:

a. When different custom dimensions and custom indicators need to be carried in the same event, the key of each custom dimension and custom indicator should not be the same, otherwise the value corresponding to the same key will be overwritten , The correct way to use it is to use keys as cd1, cd2...cd25 to store different dimension names, the same is true for custom indicators.

Example 1. Assuming that there is a page whose name is the homepage in the app, the user can receive task rewards on this page. Data analysis requirements: When the page browsing data is reported after the home page is opened, carry the user account id and nickname that opened the page. The correct solution is:

MzanalyticsMybmw.trackPageView({
                       "dt": "Home",
                     "CustomDimMetrics": {
                          "cd1":"ID88888", //Use cd1 to pass in user ID
                          "cd2": "Xiaoming Robot" //Use cd2 to pass in user nickname
                     }
    });

b. When different events report different custom dimensions and custom indicators, the key of each custom dimension and custom indicator should not be the same. If they all use the same key, all custom dimension data with the same key will be It is associated with data from different events, which makes operational analysis difficult.

Example 2: Suppose that on the homepage of the app, the user can click the task box to receive a reward after completing a specific task.

Data analysis requirements: Users need to monitor the browsing events of the homepage, carry the user ID and nickname when reporting the page browsing data, and also need to monitor the click event of the reward button on the homepage, and report the received task box name and task box at the same time Number. The correct solution is: the user account ID, nickname, and task box name use different custom dimension keys, and the custom indicators are the same.

//Refer to the code example of example 1 for the embedded point part of the page, and only the code example of the embedded point of the button click event is provided below
MzanalyticsMybmw.trackEvent({
                   "ec": "Receive Award",
                   "ea": "Click",
                   "el": "Task box to receive rewards",
                   "ev": "1",
                 "CustomDimMetrics": {
                   "cd3": "Complete the information and fill in the task box", //When cd1 and cd2 already exist, use cd3, etc.
                   "cm2": "2" // The number of task boxes 1
             }
       });

c. When all page views, custom events, and advanced events need to carry the same information, you can set global custom dimensions and custom indicators. The global settings take effect in the life cycle of a single app (refer to the document section) :2.1.11 How to use custom dimensions and indicators)

2.1.12 Enable debug log

Description: This api is used to output the debug log of the second hand analysis SDK, which is closed by default. It is recommended to turn on this switch during integration debugging to test the integration effect,Please comment out this method when it is officially released.

Interface definition:

 static Future<void> logEnabled(bool enabled)

Parameter Description:

Parameters Type Description
enabled bool Pass true to turn on the log debugging switch; the default value is false, turn off the log debugging switch (required)
 Sample code:
 MzanalyticsMybmw.logEnabled(true);

2.2 Turn on automatic page monitoring function (optional, you can choose between 2.1.2 page browsing)

Need to use the navigatorObservers method to realize the automatic monitoring function of the page.
Explanation: You must set the value to true in the switch configuration file of sdkconfig.xml to enable automatic page monitoring.

2.2.1 Register page monitoring

First, you need to add an observer object method in the main Widget build(BuildContext context) method in the main.dart of the startup page as follows: mz_navigation_history_observer().

Examples are as follows:

@override
  Widget build(BuildContext context) {

    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Home",
      theme: ThemeData(
        primaryColor: Color(0xff303030),
        scaffoldBackgroundColor: Color(0xffebebeb),
        cardColor: Color(0xff393a3f)
      ),
      routes: routeTable,
      home: LoadingPage(),
      navigatorObservers:[mz_navigation_history_observer()],
       
      
    );
  }

2.2.2 Page Jump Sample Code

The `Navigator.of` method that needs to monitor the jump page name in the App needs to pass in the corresponding page name parameter.
Example method 1:

Navigator.of(_ctx).push(MaterialPageRoute(settings: RouteSettings(name: "Home"), builder: (_ctx) => page));
Example method 2:

Navigator.of(_ctx).pushNamed("Home");

2.2.3 Set global custom dimensions and custom indicators (optional buried points)

After calling the following api, global custom dimensions and custom indicators will be set, that is, each page view, custom event, and advanced event reported will carry the global custom dimensions and indicators that have been set.
Scope: only affects the app's single life cycle.
Priority description: If the global custom dimension, custom indicator and the dimension and indicator passed in the code embedding point have the same key, the dimension and indicator of the same key in the code embedding point have a higher priority. That is, if cd1 and cm1 are passed in the code embedding point and global cd1 and cm1 have been set at the same time, the cd1 and cm1 passed in the code embedding point will be reported, and the global cd1 and cm1 will be overwritten (not reported).

2.2.3.1 Set global custom dimension cd
 Interface definition:

  Future<void> setCd(String cdKey, String cdValue)

Parameter Description:

Parameter Type Description Required
cdKey1~25 String Custom dimension key (value range cd1-25) Required
cdValue String Custom dimension value Required
Sample code:

try {
 MzanalyticsMybmw.setCd("cd1", "ID12930");//carry the user account ID dimension
} on PlatformException {}
2.2.3.2 Setting global custom indicators cm
Interface definition:

  Future<void> setCm(String cmKey, String cmValue)

Parameter Description:

Parameter Type Description Required
cmKey1~25 String Custom indicator key (value range cm1-25) Required
cmValue String type value Custom indicator value Required
Sample code:

try {
  MzanalyticsMybmw.setCm("cm1", "1001");
} on PlatformException {}
2.2.3.3 Delete the global custom dimension cd in the App cache

Description: Call this interface to delete the custom dimension cd1~25 in the app cache.

Interface definition:

  Future<void> deleteCd(String cdKey)

Parameter Description:

Parameter Type Description Required
cdkey1~25 String Custom dimension key (value range cd1-25) Required
Sample code:

try {
  MzanalyticsMybmw.deleteCd("cd1");
} on PlatformException {}
2.2.3.4 Delete the global custom dimension cm in the App cache

Description: Call this interface to delete the custom indicator cm1~25 in the app cache.

Interface definition:

  Future<void> deleteCm(String cmKey)

Parameter Description:

Parameter Type Description Required
cmKey1~25 String Custom indicator key (value range cm1-25) Required
Sample code:

try {
  MzanalyticsMybmw.deleteCm("cm1");
} on PlatformException {}
2.2.3.5 Get global custom dimension cd and custom indicator cm collection

Description: Call this interface to get the global custom dimension cd and custom indicator cm in the app cache.

Interface definition:

Future<Map> getCdAndCm()


Sample code:

try {
   Map map = MzanalyticsMybmw.getCdAndCm();
 } on PlatformException {}

3. Testing suggestions for developers

It is recommended to use Android Studio, the official development tool of Android, and Xcode, the official development tool of iOS, for integrated debugging, and observe the log output to ensure the correct integration of the SDK. (If the developer uses other debugging tools, please debug by yourself. If you encounter problems, you can contact Miaozhen for analysis in time)