Page tree
Skip to end of metadata
Go to start of metadata
  • 基础集成

    通过本模块的集成操作,即可统计到最基本的数据,如活跃用户、新增用户、启动次数以及设备相关的统计等。如需更详细的统计,则需继续集成后续章节的代码。

1.1 获取AppKey

1)登陆账号后,点击管理->新建应用:

2)填写应用的相关信息,平台请选择Android:

3)信息填写完成后在页面最下方,点击:提交并获取应用AppKey,完成应用注册,页面将跳转返回一个AppKey:

4)除了第一次创建应用可以查看到AppKey之外,还可以在应用对应报表左侧:管理->应用渠道 查看。

1.2  导入SDK

打开下载文件中的razor-0.8.0\sdk\android_sdk目录, 导入SDK项目到eclipse(或其它IDE),打包生成jar包,此过程不具体叙述。

1)Eclipse环境下:将打包好的jar包复制到本地工程libs子目录下;在Eclipse中右键工程根目录,选择Properties -> Java Build Path -> Libraries,然后点击Add External JARs..

选择指向jar的路径,点击OK,即导入成功。

2)Android Stutio环境下:将打包好的jar包复制到项目以下路径(此处假设项目名为Test):Test\app\libs,然后在Android Stutio中,点击:File->Project Structure,选中Modules下的app->选择Dependencies->点击右上角的"+"图标->File Dependency->libs->选中你复制过来的jar包->OK。然后打开gradle配置文件build.gradle(app),查看节点dependencies下是否存在:compile file('jar包名称'),若无,请添加此行代码,rebuild project,导入成功。

1.3 配置权限

        将以下权限添加至AndroidManifest.xml文件的<manifest>结点内,<application>结点外。

        1)修改AndroidManifest.xml文件

<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"。

    @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)设置数据发送模式(默认情况下为实时发送)

              提供三种种数据发送模式 实时发送、下次启动发送和定时发送模式,通过如下方法可以设置数据的发送模式。

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发送一次。如果需要修改该时间间隔,可以通过如下方法修改:

UmsAgent.setPostIntervalMillis(Context context, long interval); //参数interval的时间单位为:毫秒。


         3)设置是否发送位置信息

               该方法用来设置客户端是否发送用户的位置信息。在程序中调用如下方法来设置是否发送位置信息:

UmsAgent.setAutoLocation(boolean isSendLocation); //true:发送;false:不发送。默认false,不发送。


         4)设置session存活时间

              用于统计启动次数,两次启动程序的间隔超过设置的时长时,第二次打开应用会生成一个新的session,视为第二次启动。否则两次打开应用的操作视为一次启动。在程序                 中调用如下方法设置session的存活时间,默认时间为30s。
UmsAgent.setSessionContinueMillis(Context context,long interval); //参数interval的时间单位为:毫秒。默认30s。

          5)设置日志缓存文件大小

                SDK未提供该方法,只能通过修改源码属性或者使用在线配置。

        2.2 在线配置

                启用在线配置参数方法如下(需要在web端开启在线配置功能,并进行相应参数配置):

UmsAgent.updateOnlineConfig(Context context); //在后台进行相关配置后,即可获取并应用在线配置

 

  • 页面统计

          通过本模块的集成操作,即可统计到页面访问路径,页面访问时长等信息。如需更详细的统计,则需继续集成后续章节的代码。

       3.1 Activity页面统计

               在Android应用的每个Activity页面文件的onResume()和onPause()函数中添加代码如下,以便追踪并统计页面的相关信息:

@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() 方法,添加代码:

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页面的常见使用场景如下:

    上图为三种典型的页面统计场景

  1. 纯粹基于 Activity 的页面
  2. Activity中包含 Fragment 的页面(也有可能是Fragment包含Fragment)
  3. 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:

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方法中调用如下方法:

@Overridepublic void onResume() {
// TODO Auto-generated method stub
super.onResume();
UmsAgent.onFragmentResume(getActivity(), "Fragment—名字");
}

          然后在onHiddenChanged 方法中调用如下方法:

@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自动更新

          在入口Activity的onCreate()方法中调用如下方法,应用程序将自动检测服务端是否有新的版本。

         机制说明:

          每次更新Android应用程序,您只需要修改VersionCode,把Android应用程序的apk文件上传到服务器。UmsAgent.update(Context context)方法会判断是否有新版应用程序,           如果发现可更新的应用程序安装包,会提示用户是否更新。用户选择更新后,安装包会下载安装更新。(根据version code来检测是否需要更新

 

UmsAgent.update(this); //启用app新版本自动更新功能

          相关方法:UmsAgent.setUpdateOnlyWifi(boolean); //是否只在wifi状态下更新。

          在调用update()方法前调用setUpdateOnlyWifi()方法设置是否只在wifi状态下更新,默认为true,即只在wifi状态下更新!

  • 自定义参数接口

           
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还支持您自定义的事件的统计分析,例如您可以统计广告点击次数或者视频被播放的次数等等,这里我们将提供几个简单而通用的接口:

// 事件次数的统计,默认值为1次,调用该函数意味着 事件event_id 发生了一次
UmsAgent.onEvent(Context context, String event_id); 
 
//事件统计,int参数为整形参数,调用该函数意味着事件event_id 发生了number次
UmsAgent.onEvent(Context context, String event_id, int number); 

//如果本地有计数变量的 可以使用acc 参数传递。调用该函数意味着事件event_id下分类为label的事件发生acc次,如菜单页我的信息被点击一次,
//onEvent(context,"menu","myInfo",1);
UmsAgent.onEvent(final Context context, final String event_id, final String label, final int acc); 

//需要传递多个自定义变量时可以使用json,如{"shuliang":10,"zongjia":100}
//如在购物车信用卡付款,onEvent(context,"shoppingcar","creditcard","{\"shuliang\":10,\"zongjia\":100}");
UmsAgent.onEvent(final Context context, final String event_id, final String label, final String json) 

             在您需要发送事件报告的代码段,调用如下方法就可以向服务器发送事件记录,将统计event_id对应事件发送次数,变化趋势,例如广告点击,短信发送量等等。参数                      context为当前context的引用,event_id为当前统计事件的ID(在Cobub Razor后台需事先定义,如click_button_login)。如:

UmsAgent.onEvent(this, "click_button_login");

             发送默认事件数据到后台

UmsAgent.onGenericEvent(this, default_event, value);
  • 错误日志

       4.1 SDK已集成了UncaughtExceptionHandler自动捕获导致应用crash的异常,只需初始化SDK即生效。

       4.2 手动调用上传错误信息

               该方法的目的是手动调用将捕获到的错误或异常信息上传到服务端。

               使用方法:调用UmsAgent.onError(Context context, final String errorinfo); 

               其中errorinfo为自定义错误信息,为了后台错误信息的分类,请先将自定义错误分成若干类,比如:appException,userException,fileOptionException等等。

               errorinfo使用自定义错误类型加换行符“\n”加错误信息组成,实例如下:

//其中"userException"为自定义错误类型,"errorinfo"为错误信息可以包含包名、类名等其他信息。
String  errorinfo = "userException:"+"\n at "+this.getClass().getCanonicalName()+" errorinfo";
UmsAgent.onError( context,  errorinfo);
  • 用户标识

      5.1 用户ID绑定

              该功能将一个自定义的用户ID(用来区分用户的唯一标识符,如登录时用户输入的帐号、手机号等用户输入的相关信息)绑定在系统中,一旦绑定后,后续的统计数据中均               带有用户的ID信息,以备查询。

UmsAgent.bindUserIdentifier(this, "username");

       5.2 用户标签

               通过该方法给用户打上特定标签。在程序中需要打标签的地方调用:

UmsAgent.postTags( Context context, String tags);
  • 调试功能

           SDK提供了调试的功能,在应用集成调试过程中,可以调用以下接口打开日志进行查看:

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 中已经提供该类)

 
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中

mWebView=(WebView)findViewById(R.id.wv_test);JSUMSAgent jsUmsAgent = new JSUMSAgent(this);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(jsUmsAgent , "umsagent");// 如果HTML页面放到了服务端,IOS和Android使用一套页面别名需要统一为umsagent 


       6.3 在JavaScript中通过umsagent调用对应的方法。

 umsagent.onEvent(event_id);
      
       6.4 WebView注入Java对象注意事项

               在android4.2以前可以采用以上的方式直接注入Java对象,在android4.2之后注入对象的方法要加注释语句@JavascriptInterface
               如下:

 
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.** {*;}

注意事项

  • 权限
    确认所需的权限都已经添加
  • 联网检查
    确认测试手机或者模拟器已成功连入网络
  • No labels