Android中使用Kotlin封装一个友盟统计工具类

Android中事件统计是很常见的需求,最近做了一些封装,可以很好地看出统计事件的详细数据,使用也很方便简单,代码如下:

1.在App的build.gradle目录下添加友盟统计依赖:

implementation 'com.umeng.umsdk:common:9.4.0' // (必选)版本号
implementation 'com.umeng.umsdk:asms:1.4.0' // asms包依赖(必选)
implementation 'com.umeng.umsdk:apm:1.4.0' // apm包依赖(可选)
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'

2. 初始化:这里只是写了一个例子,所以隐私合规没有处理,真正项目需要用户同意隐私协议后才能初始化。

 3.友盟工具类:

package com.example.umengdemo.utils

import android.content.Context
import android.os.Bundle
import com.umeng.analytics.MobclickAgent
import com.umeng.commonsdk.BuildConfig
import com.umeng.commonsdk.UMConfigure
import com.umeng.umcrash.UMCrash

/**
 * @auth: njb
 * @date: 2021/10/21 15:06
 * @desc: 友盟工具类
 */
class UmengUtils private constructor() {

    /**
     * 友盟初始化方法
     */
    fun init(context: Context) {
        //集成Umeng崩溃
        val bundle = Bundle()
        bundle.putBoolean(UMCrash.KEY_ENABLE_CRASH_JAVA, true)
        bundle.putBoolean(UMCrash.KEY_ENABLE_CRASH_NATIVE, true)
        bundle.putBoolean(UMCrash.KEY_ENABLE_CRASH_UNEXP, true)
        bundle.putBoolean(UMCrash.KEY_ENABLE_ANR, false)
        bundle.putBoolean(UMCrash.KEY_ENABLE_PA, false)
        bundle.putBoolean(UMCrash.KEY_ENABLE_LAUNCH, false)
        bundle.putBoolean(UMCrash.KEY_ENABLE_MEM, false)
        UMCrash.initConfig(bundle)
        //设置友盟log开关,默认为false
        UMConfigure.setLogEnabled(BuildConfig.DEBUG)
        //初始化组件化基础库, 统计SDK
        UMConfigure.init(context, UM_APP_KEY, UM_APP_CHANNEL, UMConfigure.DEVICE_TYPE_PHONE, null)
        //设置统计模式
        MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
        //设置发送策略时间为40秒
        MobclickAgent.setSessionContinueMillis((1000 * 40).toLong())
    }


    companion object {
        val UM_APP_KEY = "617236e8e0f9bb492b3974f4"
        val UM_APP_CHANNEL = "android"
        val EVENT_ID = "event_compile"

        @Volatile
        var mInstance: UmengUtils? = null


        fun getInstance(): UmengUtils? {
            if (mInstance == null) {
                synchronized(UmengUtils::class.java) {
                    if (mInstance == null) {
                        mInstance = UmengUtils()
                    }
                }
            }
            return mInstance
        }
    }
}

4.友盟统计事件工具类:

package com.example.umengdemo.utils

import android.annotation.SuppressLint
import android.content.Context
import com.umeng.analytics.MobclickAgent
import java.util.*

/**
 * @auth: njb
 * @date: 2021/10/14 14:03
 * @desc: 友盟事件统计工具类
 */
object UmengEventUtil {
    //设备id
    private const val DEVICEID = "deviceid"

    //imsi
    private const val IMSI = "imsi"

    //mac地址
    private const val MAC = "mac"

    //手机类型
    private const val PHONE_MODEL = "phone_model"

    //手机系统版本
    private const val PHONE_VERSION = "phone_version"

    //用户id
    private const val USERID = "userId"

    //手机号
    private const val PHONE = "phone"

    //邮箱
    private const val EMAIL = "email"

    //版本号
    private const val VERSION_CODE = "version_code"

    //版本名称
    private const val VERSION_NAME = "version_name"

    //当前时间
    private const val CURRENT_TIME = "current_time"

    //用户登录事件
    private const val USER_LOGIN = "User_Login"

    //用户退出事件
    private const val USER_SIGN_OUT = "User_Sign_Out"

    //用户打开App事件
    private const val OPEN_APP = "Open_App"

    /**
     * 用户打开App事件
     *
     * @param context
     */
    fun toOpenApp(context: Context?) {
        val map = getInstallMap(context)
        MobclickAgent.onEvent(context, OPEN_APP, map)
    }

    /**
     * 用户安装app事件
     *
     * @param ctx
     * @return
     */
    @SuppressLint("MissingPermission")
    fun getInstallMap(ctx: Context?): HashMap<String, String> {
        val map = HashMap<String, String>()
        setBaseMap(ctx, map)
        map[PHONE_MODEL] = CommonUtils.getPhoneModel()
        map[PHONE_VERSION] = CommonUtils.getVersionRelease()
        map[CURRENT_TIME] =
            TimeUtils.parserTimeToYmdHmSpace(System.currentTimeMillis())
        return map
    }

    /**
     * 设置拍照基本参数
     *
     * @param context
     * @param map
     * @return
     */
    private fun setBaseMap(
        context: Context?,
        map: HashMap<String, String>
    ): HashMap<String, String> {
        val userId = "user_id"
        if (userId != null) {
            map[USERID] = userId //userId
        }
        val versionCode = CommonUtils.getVersionName(context)
        if (versionCode != null) {
            map[VERSION_CODE] = versionCode //版本号
        }
        val currentTime = System.currentTimeMillis()
        //当前时间
        map[CURRENT_TIME] =
            TimeUtils.parserTimeToYmdHmSpace(currentTime)
        //手机型号
        map[PHONE_MODEL] = CommonUtils.getPhoneModel()
        return map
    }
}

封装一个打开app的事件:

/**
 * 用户打开App事件
 *
 * @param context
 */
fun toOpenApp(context: Context?) {
    val map = HashMap<String, String>()
    setBaseMap(context,map)
    MobclickAgent.onEvent(context, OPEN_APP, map)
}

统计参数有手机型号、app版本号、当前时间、用户id等,这些参数可以根据产品需求进行统一封装,方便后期查看数据,其他人接手一看就明白又那些参数,统计事件的含义。

/**
 * 设置基本参数
 *
 * @param context
 * @param map
 * @return
 */
private fun setBaseMap(
    context: Context?,
    map: HashMap<String, String>
): HashMap<String, String> {
    val userId = "user_id"
    if (userId != null) {
        map[USERID] = userId //userId
    }
    val versionCode = CommonUtils.getVersionName(context)
    if (versionCode != null) {
        map[VERSION_CODE] = versionCode //版本号
    }
    val currentTime = System.currentTimeMillis()
    //当前时间
    map[CURRENT_TIME] =
        TimeUtils.parserTimeToYmdHmSpace(currentTime)
    //手机型号
    map[PHONE_MODEL] = CommonUtils.getPhoneModel()
    return map
}

 

 5.手机信息工具类:

package com.example.umengdemo.utils

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.text.TextUtils
import android.util.Log
import java.net.Inet6Address
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.SocketException
import java.util.*

/**
 * @auth: njb
 * @date: 2021/7/15 14:03
 * @desc: 获取版本及手机信息工具类
 */
object CommonUtils {
    /**
     * 获取版本号(内部识别号) = 101
     *
     * @param context
     * @return
     */
    fun getVersionCode(context: Context): Int {
        return try {
            val pi = context.packageManager.getPackageInfo(context.packageName, 0)
            pi.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
            0
        }
    }

    /**
     * 获取版本号 = "1.0.1";
     *
     * @param context
     * @return
     */
    fun getVersionName(context: Context): String {
        return try {
            val pi = context.packageManager.getPackageInfo(context.packageName, 0)
            pi.versionName
        } catch (e: PackageManager.NameNotFoundException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
            "未知版本"
        }
    }



    /**
     * 根据Wifi信息获取本地Mac
     *
     * @param context
     * @return
     */
    @SuppressLint("HardwareIds")
    fun getLocalMacAddressFromWifiInfo(context: Context): String? {
        var info: WifiInfo? = null
        try {
            val wifi = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
            info = wifi.connectionInfo
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return info?.macAddress
    }// skip ipv6

    /**
     * 获取ip地址
     *
     * @return
     */
    val hostIP: String
        get() {
            var hostIp = ""
            try {
                val nis: Enumeration<*> = NetworkInterface.getNetworkInterfaces()
                var ia: InetAddress? = null
                while (nis.hasMoreElements()) {
                    val ni = nis.nextElement() as NetworkInterface
                    val ias = ni.inetAddresses
                    while (ias.hasMoreElements()) {
                        ia = ias.nextElement()
                        if (ia is Inet6Address) {
                            continue  // skip ipv6
                        }
                        val ip = ia.hostAddress
                        if ("127.0.0.1" != ip) {
                            hostIp = ia.hostAddress
                            break
                        }
                    }
                }
            } catch (e: SocketException) {
                Log.e("e", "SocketException")
                e.printStackTrace()
            }
            return hostIp
        }

    /**
     * 获取手机型号
     *
     * @return
     */
    val phoneModel: String
        get() {
            val model = Build.MODEL
            return if (TextUtils.isEmpty(model)) {
                ""
            } else model
        }

    /**
     * 获取手机系统版本号
     *
     * @return
     */
    val versionRelease: String
        get() {
            val version = Build.VERSION.RELEASE
            return if (TextUtils.isEmpty(version)) {
                ""
            } else version
        }

    /**
     * 是否有访问所有文件的权限
     *
     * @param activity
     * @return
     */
    fun isRequestAllFileManager(activity: Activity?): Boolean {
        /*   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
            //手机版本为Android11且没有申请权限跳转新页面申请权限,有权限则去做相应工作
            Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            intent.setData(Uri.parse("package:" + AppUtils.getPackageName(activity)));
            activity.startActivity(intent);
            return false;
        }*/
        return true
    }

    /**
     * 检测是否安装支付宝
     * @param context
     * @return
     */
    fun isAliPayInstalled(context: Context): Boolean {
        val uri = Uri.parse("alipays://platformapi/startApp")
        val intent = Intent(Intent.ACTION_VIEW, uri)
        val componentName = intent.resolveActivity(context.packageManager)
        return componentName != null
    }

    /**
     * 检测是否安装微信
     * @param context
     * @return
     */
    fun isWeChatInstalled(context: Context): Boolean {
        val packageManager = context.packageManager // 获取packagemanager
        val packageInfo = packageManager.getInstalledPackages(0) // 获取所有已安装程序的包信息
        for (i in packageInfo.indices) {
            val pn = packageInfo[i].packageName
            if (pn == "com.tencent.mm") {
                return true
            }
        }
        return false
    }
}

6.统计事件的使用:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //打开App统计事件
        UmengEventUtil.toOpenApp(this)
    }

}

7.说一下需要注意的问题:

 a.初始化一定要在用户同意隐私之后进行,要不然华为、google各大应用市场上架不会通过.

b.可以友盟崩溃统计需要设置统计类型和参数.

c.可以需要设置统计log开关,参考友盟官网,一般项目debug开启日志,release关闭日志。

d.可以设置统计模式,如果为PageMode.AUTO,Activity不需要单独设置,其他2个模式需要.

e.可以设置发送策略时间,默认为40秒

f.统计参数使用Map,Key值不能为空字符串或者null,必须填写,value可为空.

8.可以看到,使用的时候很方便,就一句话,参数也封装起来,不需要额外传递,当然这些参数只是基础的,后期可以根据实际情况传递相应参数,如果想做组件化,可以独立成模块,也可以放到Base组件,这样可以统一管理统计事件。

最后,放出项目的源码地址:

UmengStatisDemo: 友盟统计事件的使用demo

猜你喜欢

转载自blog.csdn.net/u012556114/article/details/120944139