Skip to content

Commit

Permalink
[新增] Firebase 崩溃埋点上报
Browse files Browse the repository at this point in the history
  • Loading branch information
YenalyLiew committed Oct 13, 2024
1 parent c5ce279 commit 15c3b94
Show file tree
Hide file tree
Showing 38 changed files with 390 additions and 21 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ jobs:
distribution: 'temurin'
cache: gradle

- name: Load Google Services file
env:
DATA: ${{ secrets.HA1_GOOGLE_SERVICES_JSON_BASE64 }}
run: echo $DATA | base64 -di > app/google-services.json

- name: Grant execute permission for gradlew
run: chmod +x gradlew

Expand All @@ -30,6 +35,7 @@ jobs:
env:
HA1_KEYSTORE_PASSWORD: ${{ secrets.HA1_KEYSTORE_PASSWORD }}
HA1_GITHUB_TOKEN: ${{ secrets.HA1_GITHUB_TOKEN }}
HA1_VERSION_SOURCE: 'ci'

- name: Upload APK
uses: actions/upload-artifact@v4
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/pr_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ jobs:
distribution: 'temurin'
cache: gradle

- name: Load Google Services file
env:
DATA: ${{ secrets.HA1_GOOGLE_SERVICES_JSON_BASE64 }}
run: echo $DATA | base64 -di > app/google-services.json

- name: Grant execute permission for gradlew
run: chmod +x gradlew

Expand Down
14 changes: 11 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import Config.Version.createVersionCode
import Config.Version.createVersionName
import Config.Version.source
import Config.isRelease
import Config.lastCommitSha
import com.android.build.gradle.internal.api.BaseVariantOutputImpl

Expand All @@ -11,11 +13,10 @@ plugins {
alias(libs.plugins.org.jetbrains.kotlin.plugin.parcelize)
alias(libs.plugins.org.jetbrains.kotlin.plugin.serialization)
alias(libs.plugins.com.google.devtools.ksp)
alias(libs.plugins.com.google.gms.google.services)
alias(libs.plugins.com.google.firebase.crashlytics)
}

val isRelease: Boolean
get() = gradle.startParameter.taskNames.any { it.contains("Release") }

android {
compileSdk = property("compile.sdk")?.toString()?.toIntOrNull()

Expand Down Expand Up @@ -52,6 +53,7 @@ android {
buildConfigField("String", "VERSION_NAME", "\"${versionName}\"")
buildConfigField("int", "VERSION_CODE", "$versionCode")
buildConfigField("String", "HA1_GITHUB_TOKEN", "\"${githubToken}\"")
buildConfigField("String", "HA1_VERSION_SOURCE", "\"${source}\"")

buildConfigField("int", "SEARCH_YEAR_RANGE_END", "${Config.thisYear}")
}
Expand Down Expand Up @@ -147,6 +149,12 @@ dependencies {
implementation(libs.statelayout)
implementation(libs.circular.reveal.switch)

// firebase

implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
implementation(libs.firebase.crashlytics)

ksp(libs.room.compiler)

coreLibraryDesugaring(libs.desugar.jdk.libs)
Expand Down
4 changes: 3 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile

-keepattributes SourceFile, LineNumberTable
11 changes: 11 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@
android:foregroundServiceType="dataSync"
tools:node="merge" />

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
android:initOrder="114514"
tools:node="merge">
<meta-data
android:name="com.yenaly.han1meviewer.HInitializer"
android:value="androidx.startup" />
</provider>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/com/yenaly/han1meviewer/FirebaseConstants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.yenaly.han1meviewer

object FirebaseConstants {
// analytics
const val ADV_SEARCH_OPT = "advanced_search_options"
const val H_KEYFRAMES = "h_keyframes"

// crashlytics
const val LOGIN_STATE = "login_state"
const val APP_LANGUAGE = "app_language"
const val VERSION_SOURCE = "version_source"
}
9 changes: 9 additions & 0 deletions app/src/main/java/com/yenaly/han1meviewer/HCrashHandler.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.yenaly.han1meviewer

import com.yenaly.yenaly_libs.ActivityManager

object HCrashHandler : Thread.UncaughtExceptionHandler {
override fun uncaughtException(t: Thread, e: Throwable) {
ActivityManager.restart(killProcess = true)
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/com/yenaly/han1meviewer/HInitializer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.yenaly.han1meviewer

import android.content.Context
import com.yenaly.yenaly_libs.base.YenalyInitializer

class HInitializer : YenalyInitializer() {
override fun create(context: Context) {
super.create(context)
// 用于处理 Firebase Crashlytics 初始化
Thread.setDefaultUncaughtExceptionHandler(HCrashHandler)
}
}
17 changes: 17 additions & 0 deletions app/src/main/java/com/yenaly/han1meviewer/HanimeApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ package com.yenaly.han1meviewer
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationManagerCompat
import com.google.android.material.color.DynamicColors
import com.google.firebase.Firebase
import com.google.firebase.analytics.analytics
import com.google.firebase.crashlytics.crashlytics
import com.google.firebase.crashlytics.setCustomKeys
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.MaterialHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.yenaly.han1meviewer.logic.network.HProxySelector
import com.yenaly.yenaly_libs.base.YenalyApplication
import com.yenaly.yenaly_libs.utils.LanguageHelper

/**
* @project Hanime1
Expand All @@ -29,10 +34,22 @@ class HanimeApplication : YenalyApplication() {
}
}

/**
* 已经在 [HInitializer] 中处理了
*/
override val isDefaultCrashHandlerEnabled: Boolean = false

override fun onCreate() {
super.onCreate()
DynamicColors.applyToActivitiesIfAvailable(this)
HProxySelector.rebuildNetwork()
// 用于处理 Firebase Analytics 初始化
Firebase.analytics.setAnalyticsCollectionEnabled(Preferences.isAnalyticsEnabled)
// 用于处理 Firebase Crashlytics 初始化
Firebase.crashlytics.setCustomKeys {
key(FirebaseConstants.APP_LANGUAGE, LanguageHelper.preferredLanguage.toLanguageTag())
key(FirebaseConstants.VERSION_SOURCE, BuildConfig.HA1_VERSION_SOURCE)
}

initNotificationChannel()
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/yenaly/han1meviewer/HanimeManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.itxca.spannablex.spannable
import com.yenaly.han1meviewer.Preferences.isAlreadyLogin
import com.yenaly.han1meviewer.Preferences.loginCookie
import com.yenaly.han1meviewer.logic.network.HCookieJar
import com.yenaly.han1meviewer.ui.viewmodel.AppViewModel
import com.yenaly.han1meviewer.util.CookieString
import kotlinx.serialization.json.Json

Expand Down Expand Up @@ -53,13 +54,15 @@ fun String.toVideoCode() = videoUrlRegex.find(this)?.groupValues?.get(1)

fun logout() {
isAlreadyLogin = false
AppViewModel.loginStateFlow.value = false
loginCookie = CookieString(EMPTY_STRING)
HCookieJar.cookieMap.clear()
CookieManager.getInstance().removeAllCookies(null)
}

fun login(cookies: String) {
isAlreadyLogin = true
AppViewModel.loginStateFlow.value = true
loginCookie = CookieString(cookies)
}

Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/com/yenaly/han1meviewer/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,10 @@ object Preferences {

val proxyPort: Int
get() = preferenceSp.getInt(NetworkSettingsFragment.PROXY_PORT, -1)

// 隐私 相關

val isAnalyticsEnabled: Boolean
get() = preferenceSp.getBoolean(HomeSettingsFragment.USE_ANALYTICS, true)

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import androidx.appcompat.widget.Toolbar
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.drawerlayout.widget.DrawerLayout.DrawerListener
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
Expand All @@ -40,6 +41,7 @@ import com.yenaly.han1meviewer.logic.state.WebsiteState
import com.yenaly.han1meviewer.logout
import com.yenaly.han1meviewer.ui.viewmodel.AppViewModel
import com.yenaly.han1meviewer.ui.viewmodel.MainViewModel
import com.yenaly.han1meviewer.util.logScreenViewEvent
import com.yenaly.han1meviewer.util.showAlertDialog
import com.yenaly.han1meviewer.util.showUpdateDialog
import com.yenaly.han1meviewer.videoUrlRegex
Expand Down Expand Up @@ -86,6 +88,10 @@ class MainActivity : YenalyActivity<ActivityMainBinding>(), DrawerListener {
)
}

override val fragmentOnAttachListener: (Fragment) -> Unit = { fragment ->
logScreenViewEvent(fragment)
}

/**
* 初始化数据
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isGone
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
Expand All @@ -44,6 +45,7 @@ import com.yenaly.han1meviewer.ui.fragment.search.HMultiChoicesDialog
import com.yenaly.han1meviewer.ui.fragment.search.SearchOptionsPopupFragment
import com.yenaly.han1meviewer.ui.viewmodel.MyListViewModel
import com.yenaly.han1meviewer.ui.viewmodel.SearchViewModel
import com.yenaly.han1meviewer.util.logScreenViewEvent
import com.yenaly.yenaly_libs.base.YenalyActivity
import com.yenaly.yenaly_libs.utils.dp
import com.yenaly.yenaly_libs.utils.intentExtra
Expand Down Expand Up @@ -91,6 +93,10 @@ class SearchActivity : YenalyActivity<ActivitySearchBinding>(), StateLayoutMixin
override fun getViewBinding(layoutInflater: LayoutInflater): ActivitySearchBinding =
ActivitySearchBinding.inflate(layoutInflater)

override val fragmentOnAttachListener: (Fragment) -> Unit = { fragment ->
logScreenViewEvent(fragment)
}

override fun setUiStyle() {
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import androidx.activity.viewModels
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.yenaly.han1meviewer.R
import com.yenaly.han1meviewer.databinding.ActivitySettingsBinding
import com.yenaly.han1meviewer.ui.viewmodel.SettingsViewModel
import com.yenaly.han1meviewer.util.logScreenViewEvent
import com.yenaly.yenaly_libs.base.YenalyActivity
import com.yenaly.yenaly_libs.utils.intentExtra

Expand All @@ -41,6 +43,10 @@ class SettingsActivity : YenalyActivity<ActivitySettingsBinding>() {
override fun getViewBinding(layoutInflater: LayoutInflater): ActivitySettingsBinding =
ActivitySettingsBinding.inflate(layoutInflater)

override val fragmentOnAttachListener: (Fragment) -> Unit = { fragment ->
logScreenViewEvent(fragment)
}

override fun setUiStyle() {
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@ import androidx.activity.viewModels
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import cn.jzvd.Jzvd
import coil.load
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.analytics.logEvent
import com.google.firebase.ktx.Firebase
import com.yenaly.han1meviewer.COMMENT_TYPE
import com.yenaly.han1meviewer.FirebaseConstants
import com.yenaly.han1meviewer.Preferences
import com.yenaly.han1meviewer.R
import com.yenaly.han1meviewer.VIDEO_CODE
Expand All @@ -38,6 +44,7 @@ import com.yenaly.han1meviewer.ui.view.video.HanimeDataSource
import com.yenaly.han1meviewer.ui.viewmodel.CommentViewModel
import com.yenaly.han1meviewer.ui.viewmodel.VideoViewModel
import com.yenaly.han1meviewer.util.getOrCreateBadgeOnTextViewAt
import com.yenaly.han1meviewer.util.logScreenViewEvent
import com.yenaly.han1meviewer.util.showAlertDialog
import com.yenaly.yenaly_libs.base.YenalyActivity
import com.yenaly.yenaly_libs.utils.OrientationManager
Expand Down Expand Up @@ -69,6 +76,10 @@ class VideoActivity : YenalyActivity<ActivityVideoBinding>(),
override fun getViewBinding(layoutInflater: LayoutInflater): ActivityVideoBinding =
ActivityVideoBinding.inflate(layoutInflater)

override val fragmentOnAttachListener: (Fragment) -> Unit = { fragment ->
logScreenViewEvent(fragment)
}

override fun setUiStyle() {
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT),
Expand Down Expand Up @@ -265,6 +276,17 @@ class VideoActivity : YenalyActivity<ActivityVideoBinding>(),
prompt = null // 這裏不要給太多負擔,保存就行了沒必要寫comment
)
)
// 使用到这里说明用户可能是关键H帧目标用户
Firebase.analytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT) {
param(
FirebaseAnalytics.Param.ITEM_ID,
FirebaseConstants.H_KEYFRAMES
)
param(
FirebaseAnalytics.Param.CONTENT_TYPE,
FirebaseConstants.H_KEYFRAMES
)
}
}
setNegativeButton(R.string.cancel, null)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.yenaly.han1meviewer.ui.adapter

import android.content.Context
import android.text.method.LinkMovementMethod
import android.util.Base64
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
import androidx.core.text.method.LinkMovementMethodCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
Expand Down Expand Up @@ -68,7 +68,7 @@ class HKeyframesRvAdapter : BaseDifferAdapter<HKeyframeEntity, QuickViewHolder>(
holder.setText(R.id.tv_title, item.title)
holder.setGone(R.id.btn_edit, item.author != null)
holder.getView<TextView>(R.id.tv_video_code).apply {
movementMethod = LinkMovementMethod.getInstance()
movementMethod = LinkMovementMethodCompat.getInstance()
text = spannable {
context.getString(R.string.h_keyframe_title_prefix).text()
item.videoCode.span {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package com.yenaly.han1meviewer.ui.adapter

import android.annotation.SuppressLint
import android.content.Context
import android.text.method.LinkMovementMethod
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.text.method.LinkMovementMethodCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
Expand Down Expand Up @@ -76,7 +76,7 @@ class SharedHKeyframesRvAdapter : BaseDifferAdapter<HKeyframeType, QuickViewHold
require(item is HKeyframeEntity)
holder.setText(R.id.tv_title, item.title)
holder.getView<TextView>(R.id.tv_video_code).apply {
movementMethod = LinkMovementMethod.getInstance()
movementMethod = LinkMovementMethodCompat.getInstance()
text = spannable {
context.getString(R.string.h_keyframe_title_prefix).text()
item.videoCode.span {
Expand Down
Loading

0 comments on commit 15c3b94

Please sign in to comment.