Android全埋点解决方案
上QQ阅读APP看书,第一时间看更新

2.5 扩展采集能力

对于Activity的页面浏览事件,仅仅采集当前Activity的名称(包名+类名)是远远不够的,还需要采集当前Activity的title(标题)才能满足实际的分析需求。

但是一个Activity的title的来源是非常复杂的,因为可以通过不同的方式来设置一个Activity的title,甚至可以使用自定义的View来设置title。比如说,可以在Android-Manifest.xml文件中声明activity时通过android:label属性来设置,还可以通过activity.setTitle()来设置,也可以通过ActionBar、ToolBar来设置。所以,在获取Activity的title时,需要兼容不同的设置title的方式,同时更需要考虑其优先级顺序。

我们目前写了一个比较简单的方法来获取一个Activity的title,内容参考如下:

/**
 * 获取 Activity 的 title
 * @param activity Activity
 * @return 
 */
public static String getActivityTitle(Activity activity) {
    String activityTitle = null;

    if (activity == null) {
        return null;
    }

    try {
        activityTitle = activity.getTitle().toString();

        if (Build.VERSION.SDK_INT >= 11) {
            String toolbarTitle = getToolbarTitle(activity);
            if (!TextUtils.isEmpty(toolbarTitle)) {
                activityTitle = toolbarTitle;
            }
        }

        if (TextUtils.isEmpty(activityTitle)) {
            PackageManager packageManager = activity.getPackageManager();
            if (packageManager != null) {
                ActivityInfo activityInfo = packageManager.getActivityInfo(activity.getComponentName(), 0);
                if (activityInfo != null) {
                    activityTitle = activityInfo.loadLabel(packageManager).toString();
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return activityTitle;
}

我们首先通过activity.getTitle()获取当前Activity的title,因为用户有可能会使用ActionBar或ToolBar,所以我们还需要获取ActionBar或ToolBar设置的title,如果能获取到,就以这个为准(即覆盖通过activity.getTitle()获取的title)。如果以上两个步骤都没有获取到title,那我们就要尝试获取android:label属性的值。

获取ActionBar或ToolBar的title逻辑如下:

@TargetApi(11)
private static String getToolbarTitle(Activity activity) {
    try {
        ActionBar actionBar = activity.getActionBar();
        if (actionBar != null) {
            if (!TextUtils.isEmpty(actionBar.getTitle())) {
                return actionBar.getTitle().toString();
            }
        } else {
            if (activity instanceof AppCompatActivity) {
                AppCompatActivity appCompatActivity = (AppCompatActivity) activity;
                android.support.v7.app.ActionBar supportActionBar = appCompat-Activity.getSupportActionBar();
                if (supportActionBar != null) {
                    if (!TextUtils.isEmpty(supportActionBar.getTitle())) {
                        return supportActionBar.getTitle().toString();
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

修改trackAppViewScreen(Activity activity)方法,添加设置$title属性的逻辑:

/**
 * Track 页面浏览事件
 *
 * @param activity Activity
 */
@Keep
private static void trackAppViewScreen(Activity activity) {
    try {
        if (activity == null) {
            return;
        }
        if (mIgnoredActivities.contains(activity.getClass().hashCode())) {
            return;
        }
        JSONObject properties = new JSONObject();
        properties.put("$activity", activity.getClass().getCanonicalName());
        properties.put("$title", getActivityTitle(activity));
        SensorsDataAPI.getInstance().track("$AppViewScreen", properties);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

运行demo,可以看到打印的如下事件信息,参考图2-3。

图2-3 页面浏览事件详细信息

至此,一个相对完善的用来采集页面浏览事件的全埋点方案就算完成了。