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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,740評論 3 420
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,931評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,321評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,533評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,082評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,891評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,319評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,794評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,076評論 2 375

推薦閱讀更多精彩內容