...
Code Block |
---|
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.GET_TASKS"/> <uses-permission android:name="android.permission.READ_LOGS"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> |
2)权限说明
权限 | 用途 |
---|---|
ACCESS_NETWORK_STATE(必须) | 允许检测网络连接状态,在网络不好的状态下避免数据发送,节省流量和电量 |
READ_PHONE_STATE(必须) | 允许访问手机设备的信息,通过获取的IMEI信息来唯一标识用户 |
ACCESS_WIFI_STATE(必须) | 允许获取手机设备的WiFi Mac地址,在平板设备上,无法通过IMEI标识设备,我们会将WiFi Mac地址作为用户唯一标识 |
INTERNET(必须) | 允许程序联网,以便向我们的服务器端发送数据 |
ACCESS_FINE_LOCATION(必须) | 允许程序获取设备的位置信息(如GPS信息) |
WRITE_EXTERNAL_STORAGE(必须) | 允许程序获得外部存储写入权限,用于保存设备信息和日志记录 |
GET_TASKS(必须) | 允许程序获取设备当前或最近运行的任务 |
READ_LOGS(必须) | 允许程序读取底层系统日志文件 |
1.4 添加引用
在使用cobub sdk函数的Activity文件头中,添加引用 import com.wbtech.ums.UmsAgent;
1.5 初始化sdk
在Android应用的入口Activity的onCreate()方法中调用UmsAgent.init(Context context, String url,String AppKey)方法,注意这个方法应置于所有其他的方法之前。url为自行安装的Cobub Razor服务端地址,注意地址以index.php?/ums结束,如:"http://demo.cobub.com/razor/index.php?/ums"。
Code Block @Override public void onCreate(Bundle savedInstanceState) { ... UmsAgent.init(this,"http://demo.cobub.com/razor/index.php?/ums", "your appkey"); }
注:如果同时使用了其他统计SDK,如果cobub先注册,其他错误统计后注册,会导致cobub的自动捕捉错误统计被覆盖而无数据。同理应用内如果有捕捉错误信息的代码(实现了UncaughtExceptionHandler类),建议注释掉!
完成初始化配置之后,集成了Cobub SDK的应用可以运行,并搜集到最基本的统计数据,如活跃用户、新增用户、启动次数以及设备相关的统计等。如需更详细的统计,则需继续集成后续章节的代码。
参数配置
通过本模块的集成操作,你可以进行一些关于SDK的参数配置,包含:
1.数据发送模式;
2.数据发送间隔时长;
3.是否发送位置信息;
4.session存活时长;
5.缓存文件大小;
6.是否只在wifi状态下更新。
有两种方式配置sdk的相关参数。
2.1 本地配置
1)设置数据发送模式(默认情况下为实时发送)
提供三种种数据发送模式 实时发送、下次启动发送和定时发送模式,通过如下方法可以设置数据的发送模式。
Code Block |
---|
UmsAgent.setDefaultReportPolicy(Context context, SendPolicy.POST_ONSTART); //下次启动发送 UmsAgent.setDefaultReportPolicy(Context context, SendPolicy.POST_NOW); //实时发送 UmsAgent.setDefaultReportPolicy(Context context,SendPolicy.POST_INTERVAL); //按时间间隔发送 |
模式解释
- 启动时发送
应用程序每次只会在启动时向服务器发送一次消息,在应用程序过程中产生的所有消息都会在下次启动时候发送。如果应用程序启动时处在不联网状态,那么消息将会缓存在本地,下次再尝试发送。 - 实时发送(推荐使用)
应用程序每产生条消息时,就立即发送到服务器。这种方式使得计算更及时 - 间隔发送
按时间间隔发送,默认的时间间隔为1min。如果需要修改该时间间隔,可以通过如下函数修改:
UmsAgent.setPostIntervalMillis(Context context, long interval); 参数 interval的时间单位为:ms。
2)设置数据发送间隔时长
前提:数据发送格式设置为了按时间间隔发送。默认的时间间隔为1min发送一次。如果需要修改该时间间隔,可以通过如下方法修改:
Code Block |
---|
UmsAgent.setPostIntervalMillis(Context context, long interval); //参数interval的时间单位为:毫秒。 |
3)设置是否发送位置信息
该方法用来设置客户端是否发送用户的位置信息。在程序中调用如下方法来设置是否发送位置信息:
Code Block |
---|
UmsAgent.setAutoLocation(boolean isSendLocation); //true:发送;false:不发送。默认false,不发送。 |
4)设置session存活时间
Code Block |
---|
UmsAgent.setSessionContinueMillis(Context context,long interval); //参数interval的时间单位为:毫秒。默认30s。 |
5)设置日志缓存文件大小
2.2 在线配置
启用在线配置参数方法如下(需要在web端开启在线配置功能,并进行相应参数配置):
Code Block |
---|
UmsAgent.updateOnlineConfig(Context context); //在后台进行相关配置后,即可获取并应用在线配置 |
页面统计
通过本模块的集成操作,即可统计到页面访问路径,页面访问时长等信息。如需更详细的统计,则需继续集成后续章节的代码。
3.1 Activity页面统计
在Android应用的每个Activity页面文件的onResume()和onPause()函数中添加代码如下,以便追踪并统计页面的相关信息:
Code Block |
---|
@Override protected void onResume(){ super.onResume(); UmsAgent.onResume(this); } @Override protected void onPause(){ super.onPause(); UmsAgent.onPause(this); } |
3.2 Web页面访问统计
Cobub Razor的Android SDK同时提供了针对Web页面的统计,在加载WebView控件(或继承了WebView控件的第三方控件)控件的Activity界面中,重写 onPageFinished() 方法,添加代码:
Code Block |
---|
WebView webview = (WebView)findViewById(R.id.webView1); webview.setWebViewClient(new WebViewClient(){ @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); //在此需截取url中的有效页面名称,防止因参数不同而将同一页面重复统计 UmsAgent.postWebPage(url); } }); |
3.3 fragment 页面统计
由于现在的应用很多都是有少数的Activity加大量的Fragment组成,因此我们在统计中增加了对Fragment页面的统计。
app页面的常见使用场景如下:
上图为三种典型的页面统计场景
- 纯粹基于 Activity 的页面
- Activity中包含 Fragment 的页面(也有可能是Fragment包含Fragment)
- Activity 中包含多个并列 Fragment 的页面
在上述场景中, 我们可以统计到的页面为:
1.A activity -> B activity ->C activity;
2.A activity -> B activity ->Fragment 2;
3.A activity -> B activity ->Fragment 3;
4.A activity -> Fragment 1 ->C activity;
5.A activity -> Fragment 1 ->Fragment 2;
6.A activity -> Fragment 1 ->Fragment 3;
如下的顺序目前是无法统计到的:
A activity > B activity ->C activity>Fragment 2;
A activity > B activity ->C activity>Fragment 3;
如果页面是使用FragmentActivity + Fragment实现的,需要在 FragmentActivity 中统计时长:
1)针对无ViewPager:
Code Block |
---|
public class Fragment2 extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragment2, container, false); } @Override public void onPause() { // TODO Auto-generated method stub super.onPause(); UmsAgent.onPause(activity); } @Override public void onResume() { // TODO Auto-generated method stub super.onResume(); UmsAgent.onFragmentResume(activity, "Fragment 2"); } Activity activity; @Override public void onAttach(Activity activity) { super.onAttach(activity); this.activity = activity; } } |
2)针对有ViewPager:(注意:不用在onPause方法中调用)
首先在onResume方法中调用如下方法:
Code Block |
---|
@Overridepublic void onResume() { // TODO Auto-generated method stub super.onResume(); UmsAgent.onFragmentResume(getActivity(), "Fragment—名字"); } |
然后在onHiddenChanged 方法中调用如下方法:
Code Block |
---|
@Override public void onHiddenChanged(boolean hidden) { // TODO Auto-generated method stub super.onHiddenChanged(hidden); if(hidden){ UmsAgent.onPause(getActivity()); }else{ UmsAgent.onFragmentResume(getActivity(), "fragment—名字"); } } |
App自动更新
机制说明:
Code Block |
---|
UmsAgent.update(this); //启用app新版本自动更新功能 |
相关方法:UmsAgent.setUpdateOnlyWifi(boolean); //是否只在wifi状态下更新。
可在调用update()方法前调用setUpdateOnlyWifi()方法设置是否只在wifi状态下更新,默认为true,即只在wifi状态下更新!
自定义参数接口
Code Block |
---|
updateCustomsParameters(); //获取在线配置参数 保存到本地 getConfigParameter(String key); //获取本地保存的在线配置参数 |
必须先调用方法updateCustomsParameters();将获取到的自定义参数缓存到本地,然后使用getConfigParameter(String key)获取指定的key对应的自定义值。
updateCustomsParameters()方法返回值格式:
{ reply: {returnCode: {domain: null, type: "S", code: "AAAAAA" }, parameters: [ { key: "showad", value: "1" }, { key: "display_menu", value: "1" } ] } } |
---|
...
SDK提供了调试的功能,在应用集成调试过程中,可以调用以下接口打开日志进行查看:
Code Block |
---|
UmsAgent.setDebugEnabled(boolean isEnableDebug); //是否打开调试功能 UmsAgent.setDebugLevel(LogLevel); //定义SDK的log输出等级 LogLevel的定义如下: public enum LogLevel { Info, // equals Log.INFO, for less important info Debug, // equals Log.DEBUG, for some debug information Warn, // equals Log.WARN, for some warning info Error, // equals Log.ERROR, for the exceptions errors Verbose // equals Log.VERBOSE, for the verbose info } |
注意:在打包发布前请将日志功能关闭。
H5页面数据统计
在JavaScript中调用jar包中的原生方法(针对H5页面)
6.1 封装一个Java类 如 JSUMSAgent (SDK 中已经提供该类)
Code Block |
---|
import android.content.Context;public class JSUMSAgent { Context context; public JSUMSAgent(Context context) { super(); this.context = context; } public void bindUserIdentifier(String identifier){ UmsAgent.bindUserIdentifier(context, identifier); } public void onError(String errorInfo){ UmsAgent.onError(context, errorInfo); } public void postTags(String tags){ UmsAgent.postTags(context, tags); } public void onEvent(String event_id){ UmsAgent.onEvent(context, event_id); } public void onEvent(String event_id, int acc){ UmsAgent.onEvent(context, event_id, acc); } public void onEvent(String event_id, String label, int acc) { UmsAgent.onEvent(context, event_id, label, acc); } public void onEvent( String event_id, String label, String json) { UmsAgent.onEvent(context, event_id, label, json); } public void onGenericEvent(String label,String value){ UmsAgent.onGenericEvent(context, label, value); } public void postWebPage(String pageName){ UmsAgent.postWebPage(pageName); } } |
6. 2 在入口activity中创建该对象,同时将该对象传递到JavaScript中
Code Block |
---|
mWebView=(WebView)findViewById(R.id.wv_test);JSUMSAgent jsUmsAgent = new JSUMSAgent(this); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.addJavascriptInterface(jsUmsAgent , "umsagent");// 如果HTML页面放到了服务端,IOS和Android使用一套页面别名需要统一为umsagent如果HTML页面放到了服务端,IOS和Android使用一套页面别名需要统一为umsagent |
6.3 在JavaScript中通过umsagent调用对应的方法。
Code Block |
---|
umsagent.onEvent(event_id); |
在android4.2以前可以采用以上的方式直接注入Java对象,在android4.2之后注入对象的方法要加注释语句@JavascriptInterface
如下:
Code Block |
---|
public class JSUMSAgent { Context context;
public JSUMSAgent(Context context) {
super();
this.context = context;
}
@JavascriptInterface
public void bindUserIdentifier(String identifier){
UmsAgent.bindUserIdentifier(context, identifier);
}
@JavascriptInterface
public void onError(String errorInfo){
UmsAgent.onError(context, errorInfo);
}
@JavascriptInterface
public void postTags(String tags){
UmsAgent.postTags(context, tags);
}
@JavascriptInterface
public void onEvent(String event_id){
UmsAgent.onEvent(context, event_id);
}
@JavascriptInterface
public void onEvent(String event_id, int acc){
UmsAgent.onEvent(context, event_id, acc);
}
@JavascriptInterface
public void onEvent(String event_id,
String label, int acc) {
UmsAgent.onEvent(context, event_id, label, acc);
}
@JavascriptInterface
public void onEvent( String event_id,
String label, String json) {
UmsAgent.onEvent(context, event_id, label, json);
}
@JavascriptInterface
public void onGenericEvent(String label,String value){
UmsAgent.onGenericEvent(context, label, value);
}
@JavascriptInterface
public void postWebPage(String pageName){
UmsAgent.postWebPage(pageName);
}
} |
经过查官方文档所知,因为这个接口允许JavaScript 控制宿主应用程序,这是个很强大的特性,但同时,在4.2的版本前存在重大安全隐患,因为JavaScript 可以使用反射访问注入webview 的java对象的public fields,在一个包含不信任内容的WebView中使用这个方法,会允许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。因此4.2以后,任何为JS暴露的接口,都需要加@JavascriptInterface
代码混淆
代码混淆是请不要混洗jar包中的内容,请在混淆文件中添加:
-keep class com.wbtech.ums.** {*;}
Info |
---|
注意事项
|