diff --git a/app/build.gradle b/app/build.gradle index 719fde7..d7361a4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -27,6 +27,9 @@ android { versionName rootProject.ext.appVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + /** 添加 App Center Secret 到 BuildConfig */ + buildConfigField("String", "APP_CENTER_SECRET", "\"${getAppCenterSecret()}\"") } buildTypes { @@ -58,10 +61,23 @@ android { } } +/** + * 获取 App Center Secret + * @return [String] + */ +String getAppCenterSecret() { + def fileName = '../.secret/APP_CENTER_SECRET' + def content = '' + if (file(fileName).exists()) file(fileName).eachLine { content = it } + return content +} + dependencies { compileOnly 'de.robv.android.xposed:api:82' implementation 'com.highcapable.yukihookapi:api:1.1.4' ksp 'com.highcapable.yukihookapi:ksp-xposed:1.1.4' + implementation "com.microsoft.appcenter:appcenter-analytics:4.4.5" + implementation "com.microsoft.appcenter:appcenter-crashes:4.4.5" implementation 'com.google.code.gson:gson:2.9.0' implementation 'com.github.duanhong169:drawabletoolbox:1.0.7' implementation "com.github.topjohnwu.libsu:core:3.1.2" diff --git a/app/src/main/java/com/fankes/apperrorstracking/application/AppErrorsApplication.kt b/app/src/main/java/com/fankes/apperrorstracking/application/AppErrorsApplication.kt index f92c773..9dc26f3 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/application/AppErrorsApplication.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/application/AppErrorsApplication.kt @@ -24,6 +24,7 @@ package com.fankes.apperrorstracking.application import androidx.appcompat.app.AppCompatDelegate import com.fankes.apperrorstracking.data.ConfigData import com.fankes.apperrorstracking.locale.LocaleString +import com.fankes.apperrorstracking.utils.tool.AppAnalyticsTool import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication class AppErrorsApplication : ModuleApplication() { @@ -36,5 +37,7 @@ class AppErrorsApplication : ModuleApplication() { LocaleString.bind(instance = this) /** 装载存储控制类 */ ConfigData.init(instance = this) + /** 装载 App Center */ + AppAnalyticsTool.init(instance = this) } } \ No newline at end of file diff --git a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt index 027b924..8eeb079 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt @@ -36,6 +36,7 @@ import com.fankes.apperrorstracking.ui.activity.debug.LoggerActivity import com.fankes.apperrorstracking.ui.activity.errors.AppErrorsMutedActivity import com.fankes.apperrorstracking.ui.activity.errors.AppErrorsRecordActivity import com.fankes.apperrorstracking.utils.factory.* +import com.fankes.apperrorstracking.utils.tool.AppAnalyticsTool.bindAppAnalytics import com.fankes.apperrorstracking.utils.tool.FrameworkTool import com.highcapable.yukihookapi.YukiHookAPI @@ -66,6 +67,8 @@ class MainActivity : BaseActivity() { if (btn.isPressed.not()) return@setOnCheckedChangeListener hideOrShowLauncherIcon(b) } + /** 设置匿名统计 */ + binding.enableAnonymousStatisticsSwitch.bindAppAnalytics() /** 系统版本点击事件 */ binding.mainTextSystemVersion.setOnClickListener { showDialog { diff --git a/app/src/main/java/com/fankes/apperrorstracking/utils/tool/AppAnalyticsTool.kt b/app/src/main/java/com/fankes/apperrorstracking/utils/tool/AppAnalyticsTool.kt new file mode 100644 index 0000000..1690dd8 --- /dev/null +++ b/app/src/main/java/com/fankes/apperrorstracking/utils/tool/AppAnalyticsTool.kt @@ -0,0 +1,87 @@ +/* + * AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer. + * Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com) + * https://github.com/KitsunePie/AppErrorsTracking + * + * This software is non-free but opensource software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * and eula along with this software. If not, see + * + * + * This file is Created by fankes on 2022/10/5. + */ +@file:Suppress("unused") + +package com.fankes.apperrorstracking.utils.tool + +import android.app.Application +import android.widget.CompoundButton +import com.fankes.apperrorstracking.BuildConfig +import com.highcapable.yukihookapi.hook.factory.modulePrefs +import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData +import com.microsoft.appcenter.AppCenter +import com.microsoft.appcenter.analytics.Analytics +import com.microsoft.appcenter.crashes.Crashes + +/** + * Microsoft App Center 工具 + */ +object AppAnalyticsTool { + + /** App Secret */ + private const val APP_CENTER_SECRET = BuildConfig.APP_CENTER_SECRET + + /** 启用匿名统计收集使用情况功能 */ + private val ENABLE_APP_CENTER_ANALYTICS = PrefsData("_enable_app_center_analytics", true) + + /** 当前实例 */ + private var instance: Application? = null + + /** + * 是否启用匿名统计收集使用情况功能 + * @return [Boolean] + */ + private var isEnableAppCenterAnalytics + get() = instance?.modulePrefs?.get(ENABLE_APP_CENTER_ANALYTICS) ?: true + set(value) { + instance?.modulePrefs?.put(ENABLE_APP_CENTER_ANALYTICS, value) + } + + /** 绑定到 [CompoundButton] 自动设置选中状态 */ + fun CompoundButton.bindAppAnalytics() { + isChecked = isEnableAppCenterAnalytics + setOnCheckedChangeListener { button, isChecked -> + if (button.isPressed.not()) return@setOnCheckedChangeListener + isEnableAppCenterAnalytics = isChecked + } + } + + /** + * 上传分析日志 + * @param name 事件名称 + * @param data 事件详细内容 - 默认空 + */ + fun trackEvent(name: String, data: HashMap? = null) { + if (data != null) Analytics.trackEvent(name, data) + else Analytics.trackEvent(name) + } + + /** + * 初始化 App Center + * @param instance 实例 + */ + fun init(instance: Application) { + this.instance = instance + if (isEnableAppCenterAnalytics && APP_CENTER_SECRET.isNotBlank()) + AppCenter.start(instance, APP_CENTER_SECRET, Analytics::class.java, Crashes::class.java) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_appcenter.xml b/app/src/main/res/drawable/ic_appcenter.xml new file mode 100644 index 0000000..94c09e8 --- /dev/null +++ b/app/src/main/res/drawable/ic_appcenter.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 95d8c9f..d16f840 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -581,6 +581,71 @@ android:textSize="12sp" /> + + + + + + + + + + + + + + + + +