本文参考自Umeng官方:https://developer.umeng.com/docs/119267/cate/118577
一、合规指南
近日,APP违法违规收集用户个人信息的问题再次受到监管关注。据悉,工信部将在2020年8月底前上线运行全国APP技术检测平台管理系统,2020年12月10日前完成覆盖40万款主流App的合规检测工作。
为了保证您的App顺利通过检测,结合当前监管关注重点,我们制作了友盟+SDK初始化合规方案。熟悉监管要求,掌握合规操作流程,拒绝App被下架。
合规三步走
1、您需要确保App有《隐私政策》,并且在用户首次启动App时就弹出《隐私政策》取得用户同意。
2、您务必告知用户您选择友盟+SDK服务,请在《隐私政策》中增加如下参考条款:
“我们的产品集成友盟+SDK,友盟+SDK需要收集您的设备Mac地址、唯一设备识别码(IMEI/android ID/IDFA/OPENUDID/GUID、SIM 卡 IMSI 信息)以提供统计分析服务,并通过地理位置校准报表数据准确性,提供基础反作弊能力。”
3、您务必确保用户同意《隐私政策》之后,再初始化友盟+SDK。具体初始化步骤详见下文
二、初始化步骤
注意:本方案支持友盟统计SDK 9.3.x及更高版本,强烈建议目前集成6.x.x、7.x.x、8.x.x、9.3.x以下 版本的开发者将统计SDK升级到9.3.7版本。
为保证您的在集成【友盟+】统计SDK之后,能够满足工信部相关合规要求,您应确保在App安装后首次冷启动时按照如下方式进行初始化。
-
在Applicaiton.onCreate函数中调用预初始化函数UMConfigure.preInit(),预初始化函数不会采集设备信息,也不会向友盟后台上报数据。
// SDK预初始化函数
// preInit预初始化函数耗时极少,不会影响App首次冷启动用户体验
publicstaticvoid preInit(Context context,String appkey,String channel)
-
确保App首次冷启动时,在用户阅读您的《隐私政策》并取得用户授权之后,才调用正式初始化函数UMConfigure.init()初始化统计SDK,此时SDK才会真正采集设备信息并上报数据。反之,如果用户不同意《隐私政策》授权,则不能调用UMConfigure.init()初始化函数。
-
一旦App获取到《隐私政策》的用户授权,后续的App冷启动,开发者应该保证在Applicaiton.onCreate函数中调用预初始化函数UMConfigure.preInit()。正式初始化函数UMConfigure.init可以按需调用(可以在预初始化函数之后紧接着调用,也可以放到后台线程中延迟调用,但还是必须调用,不能遗漏)。
三、集成流程
1、maven依赖配置
maven { url 'https://dl.bintray.com/umsdk/release' }
buildscript {
repositories {
google()
jcenter()
maven { url 'https://dl.bintray.com/umsdk/release' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven { url 'https://dl.bintray.com/umsdk/release' }
}
}
2、在工程App 对应build.gradle配置脚本dependencies段中添加统计SDK库和其它库依赖:
dependencies {
implementation fileTree(include:['*.jar'], dir:'libs')
// 下面各SDK根据宿主App是否使用相关业务按需引入。
// 友盟统计SDK
implementation 'com.umeng.umsdk:common:9.3.8'// 必选
implementation 'com.umeng.umsdk:asms:1.2.2'// 必选
implementation 'com.umeng.umsdk:abtest:1.0.0'//可选(使用U-App中ABTest能力)
}
在Android Studio 3.1及以上版本开发环境下,指定引用最新版本依赖写法”latest.integration”可能导致下载库超时,此时需要指定具体版本号。
3、AndroidManifest.xml清单文件示例:
<manifest ……>
<uses-sdk android:minSdkVersion="8"></uses-sdk>
<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"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application ……>
4、混淆设置
-keep class com.umeng.** {*;}
-keepclassmembers class * {
public <init> (org.json.JSONObject);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
//SDK 9.2.4及以上版本自带oaid采集模块,不再需要开发者再手动引用oaid库,所以可以不添加这些混淆
-keep class com.zui.**{*;}
-keep class com.miui.**{*;}
-keep class com.heytap.**{*;}
-keep class a.**{*;}
-keep class com.vivo.**{*;}
SDK需要引用导入工程的资源文件,通过了反射机制得到资源引用文件R.java,但是在开发者通过proguard等混淆/优化工具处理apk时,proguard可能会将R.java删除,如果遇到这个问题,请添加如下配置:
-keep public class [您的应用包名].R$*{
public static final int *;
}
三、基础功能初始化及通用接口
1、初始化方法由基础组件包提供,要使用统计SDK,需要在宿主应用application.onCreate函数中调用基础组件包提供的初始化函数:
/**
* 注意: 即使您已经在AndroidManifest.xml中配置过appkey和channel值,也需要在App代码中调
* 用初始化接口(如需要使用AndroidManifest.xml中配置好的appkey和channel值,
* UMConfigure.init调用中appkey和channel参数请置为null)。
*/
UMConfigure.init(Context context,String appkey,String channel,int deviceType,String pushSecret);
或
/**
* 注意:如果您已经在AndroidManifest.xml中配置过appkey和channel值,可以调用此版本初始化函数。
*/
UMConfigure.init(Context context,int deviceType,String pushSecret);
Channel渠道的使用规范
每台设备仅记录首次安装激活的渠道,在其他渠道再次安装不会重复计量。 所以在测试不同的渠道的时候,请使用不同的设备来分别测试不要改变’UMENG_CHANNEL’。
Channel渠道的命名规范
-
可以由英文字母、阿拉伯数字、下划线、中划线、空格、括号组成,可以含汉字以及其他明文字符,但是不建议使用中文命名,会出现乱码。
-
首尾字符不可以为空格。
-
不要使用纯数字作为渠道ID。
-
最多256个字符。
-
“unknown” 及其各种大小写形式,作为【友盟+】保留的字段,不可以作为渠道名。
在您查看数据时,渠道会作为一个数据细分的维度。
2、预初始化
如果App不能保证在Appcalition.onCreate函数中调用UMConfigure.init初始化函数,则必须在Appcalition.onCreate函数中调用此预初始化函数。
对于有延迟初始化SDK需求的开发者(不能在Application.onCreate函数中调用UMConfigure.init初始化函数),必须在Application.onCreate函数中调用UMConfigure.preInit预初始化函数(preInit耗时极少,不会影响冷启动体验),而后UMConfigure.init函数可以按需延迟调用(可以放到后台线程中延时调
publicstaticvoid preInit(Context context,String appkey,String channel)
用,可以延迟,但还是必须调用)。如果您的App已经是在Application.onCreate函数中调用UMConfigure.init进行初始化,则无需额外调用UMConfigure.preInit预初始化函数。
3、日志开关
可以通过调用如下方法控制SDK运行调试日志是否输出,默认情况下SDK运行调试日志关闭。需要用户手动打开。
/**
*设置组件化的Log开关
*参数: boolean 默认为false,如需查看LOG设置为true
*/
UMConfigure.setLogEnabled(true);
日志等级
日志分为四种等级,方便用户查看:
Error(打印SDK集成或运行时错误信息)。
Warn(打印SDK警告信息)。
Info(打印SDK提示信息)。
Debug(打印SDK调试信息)。
初始化函数使用说明见:初始化及通用接口
4、APP启动、使用时长等基础数据统计接口
@Override
publicvoid onResume(){
super.onResume();
// umeng
MobclickAgent.onResume(this);
}
@Override
publicvoid onPause(){
super.onPause();
// umeng
MobclickAgent.onPause(this);
}
说明
注意: 确保在所有的Activity中都调用 MobclickAgent.onResume和onPause方法(如果是在AUTO页面采集模式下,则需要注意,所有Activity中都不能调用MobclickAgent.onResume和onPause方法,详见后续页面采集章节),这两个调用不会阻塞应用程序的主线程,也不会影响应用程序的性能。 页面采集模式的设置不仅影响采集页面,也影响了新增启动活跃数据,因为其作用是对App整个生命周期的监控。您的用户可能从任何activity进入您的App,需要对所有activity进行完整的监控。如果您选择的模式是AUTO,初始化函数是默认对所有activity自动埋点,因此不需要调用MobclickAgent.onResume和onPause方法。 如果您的Activity之间有继承或者控制关系,请不要同时在父和子Activity中重复添加nPause和nResume方法,否则会造成重复统计,导致启动次数异常增高。(例如:使用TabHost、TabActivity、ActivityGroup时)。 当应用在后台运行超过30秒(默认)再回到前台,将被认为是两次独立的Session(启动),例如:用户回到home,或进入其他程序,经过一段时间后再返回之前的应用。即被认为是两个独立的Session。
5、页面采集
四种页面采集模式对比
AUTO模式
SDK9.0.0之后的版本默认此模式。Android 4.0及以上版本支持Activity生命周期的自动监控(通过注册自定义callback函数)。在Android 4.0以上设备中,推荐使用系统自动监控机制进行页面及基础指标自动埋点(AUTO模式下SDK会自动调用MobclickAgent.onResume/MobclickAgent.onPause接口,用户无须手动调用这两个接口)。
首次使用【友盟+】统计SDK的用户选用AUTO模式采集页面数据,仅需执行SDK初始化函数后调用 MobclickAgent.setPageCollectionMode(PageMode mode) 函数即可。
例子:
publicclassUmengApplicationextendsApplication{
@Override
publicvoid onCreate(){
super.onCreate();
// 初始化SDK
UMConfigure.init(this,"您的appkey","您的渠道",UMConfigure.DEVICE_TYPE_PHONE,null);
// 选用AUTO页面采集模式
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO);
MANUAL模式
如果需要统计 Android 4.0 以下版本设备统计数据,则必须选择手动模式(MANUAL),对宿主App中所有Activity都手动调用MobclickAgent.onResume/MobclickAgent.onPause手动埋点。
例子:
publicclassUmengApplicationextendsApplication{
@Override
publicvoid onCreate(){
super.onCreate();
// 初始化SDK
UMConfigure.init(this,"您的appkey","您的渠道",UMConfigure.DEVICE_TYPE_PHONE,null);
// 选用MANUAL页面采集模式
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.MANUAL);
MANUAL模式下需要在Activity的onResume/onPause函数中手动调用MobclickAgent.onResume/MobclickAgent.onPause函数,保证正确统计应用使用时长、启动、活跃等基础指标。
例子:
// Activity页面onResume函数重载
@Override
publicvoid onResume(){
super.onResume();
MobclickAgent.onResume(this);// 不能遗漏
}
// Activity页面onResume函数重载
@Override
publicvoid onPause(){
super.onPause();
MobclickAgent.onPause(this);// 不能遗漏
}
-
在AUTO或MANUAL模式下,如果需要对非Activity页面,如Fragment、自定义View等非标准页面进行统计。需要通过MobclickAgent.onPageStart/MobclickAgent.onPageEnd接口在合适的时机进行页面统计。
-
一次成对的 onPageStart -> onPageEnd 调用,对应一次非Activity页面(如:Fragment)生命周期统计。
-
手动统计Fragemnt页面的例子代码:
// Fragment页面onResume函数重载 publicvoid onResume(){ super.onResume(); MobclickAgent.onPageStart("MainScreen");//统计页面("MainScreen"为页面名称,可自定义) } // Fragment页面onResume函数重载 publicvoid onPause(){ super.onPause(); MobclickAgent.onPageEnd("MainScreen"); }
LEGACY_AUTO模式
SDK9.0.0之前的版本默认情况下使用此模式,对于多数老版本【友盟+】统计SDK的开发者,如果在您的App中之前没有使用MobclickAgent.onPageStart/MobclickAgent.onPageEnd这两个接口对非Activity页面(如:Fragment)进行埋点统计。则请选择此模式,这样您的App埋点代码不需要做任何修改,SDK即可正常工作。(需确保您应用中所有Activity中都已经手动调用MobclickAgent.onResume/MobclickAgent.onPause接口)
例子:
publicclassUmengApplicationextendsApplication{
@Override
publicvoid onCreate(){
super.onCreate();
// 初始化SDK
UMConfigure.init(this,"您的appkey","您的渠道",UMConfigure.DEVICE_TYPE_PHONE,null);
// 选用LEGACY_AUTO页面采集模式
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.LEGACY_AUTO);
LEGACY_MANUAL模式
对于已经在App中使用MobclickAgent.onPageStart/MobclickAgent.onPageEnd这两个接口对非Activity页面(如:Fragment)进行埋点统计的SDK老用户,则请选择LEGACY_MANUAL模式,这样您的App埋点代码不需要做任何修改,SDK即可正常工作。(需确保您应用中所有Activity中都已经手动调用MobclickAgent.onResume/MobclickAgent.onPause接口)
例子:
publicclassUmengApplicationextendsApplication{
@Override
publicvoid onCreate(){
super.onCreate();
// 初始化SDK
UMConfigure.init(this,"您的appkey","您的渠道",UMConfigure.DEVICE_TYPE_PHONE,null);
// 选用LEGACY_AUTO页面采集模式
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.LEGACY_MANUAL);
至此,基本功能集成已经完成。