update
This commit is contained in:
parent
40fb451fa4
commit
6565860cbb
@ -4,6 +4,8 @@ plugins {
|
||||
id("kotlin-kapt")
|
||||
id("org.jetbrains.kotlin.plugin.serialization")
|
||||
id("kotlin-android")
|
||||
id("com.google.gms.google-services")
|
||||
id("com.google.firebase.crashlytics")
|
||||
}
|
||||
|
||||
android {
|
||||
@ -30,13 +32,13 @@ android {
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
debug {
|
||||
isMinifyEnabled = true
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
// debug {
|
||||
// isMinifyEnabled = true
|
||||
// proguardFiles(
|
||||
// getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
// "proguard-rules.pro"
|
||||
// )
|
||||
// }
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
@ -97,4 +99,10 @@ dependencies {
|
||||
|
||||
//google
|
||||
// implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
|
||||
|
||||
// Import the Firebase BoM
|
||||
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
|
||||
implementation("com.google.firebase:firebase-analytics-ktx")
|
||||
implementation("com.google.firebase:firebase-crashlytics-ktx")
|
||||
implementation("com.google.firebase:firebase-config")
|
||||
}
|
||||
29
app/google-services.json
Normal file
29
app/google-services.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "320083292372",
|
||||
"project_id": "musiclax-and",
|
||||
"storage_bucket": "musiclax-and.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:320083292372:android:047dd51c4c373acf9a8b41",
|
||||
"android_client_info": {
|
||||
"package_name": "relax.offline.mp3.music"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyCs8V_b7UYuUfcs_mAWIAbr06VZKBM-680"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@ -41,6 +41,7 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.MainActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".activity.PrimaryActivity"
|
||||
|
||||
@ -20,10 +20,13 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import relax.offline.music.database.AppFavoriteDBManager
|
||||
import relax.offline.music.firebase.RemoteConfig
|
||||
import relax.offline.music.http.CommonIpInfoUtil
|
||||
import relax.offline.music.http.UploadEventName
|
||||
import relax.offline.music.util.AppLifecycleHandler
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
class App : Application() {
|
||||
@ -107,9 +110,15 @@ class App : Application() {
|
||||
}
|
||||
}
|
||||
|
||||
var isAdShowing: AtomicBoolean = AtomicBoolean(false)//是否正在广告界面
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
app = this
|
||||
AppLifecycleHandler(this)
|
||||
CommonIpInfoUtil.shared.initIPInfo()
|
||||
UploadEventName.shared.init(this)
|
||||
RemoteConfig.instance.init(this)
|
||||
initialize(this)
|
||||
MediaControllerManager.init(this)
|
||||
LocalMediaControllerManager.init(this)
|
||||
@ -121,8 +130,5 @@ class App : Application() {
|
||||
initImportAudio()
|
||||
CacheManager.initializeCaches(this)
|
||||
DownloadUtil.getDownloadManager(this)
|
||||
CommonIpInfoUtil.shared.initIPInfo()
|
||||
UploadEventName.shared.init(this)
|
||||
}
|
||||
|
||||
}
|
||||
@ -8,7 +8,7 @@ import relax.offline.music.databinding.ActivityLaunchBinding
|
||||
|
||||
class LaunchActivity : MoBaseActivity() {
|
||||
private lateinit var binding: ActivityLaunchBinding
|
||||
private val totalTime = 3000L // 5秒
|
||||
private val totalTime = 5000L // 5秒
|
||||
private val interval = 50L // 更新间隔,毫秒
|
||||
private val steps = totalTime / interval
|
||||
private val progressPerStep = 100f / steps.toFloat()
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package relax.offline.music.activity
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
@ -32,7 +31,6 @@ import relax.offline.music.App
|
||||
import relax.offline.music.R
|
||||
import relax.offline.music.bean.FavoriteBean
|
||||
import relax.offline.music.bean.OfflineBean
|
||||
import relax.offline.music.innertube.Innertube
|
||||
import relax.offline.music.media.MediaControllerManager
|
||||
import relax.offline.music.sp.AppStore
|
||||
import relax.offline.music.util.LogTag
|
||||
@ -235,7 +233,7 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope
|
||||
thumbnail = mediaItem.mediaMetadata.artworkUri.toString(),
|
||||
isOffline = true
|
||||
)
|
||||
LogTag.LogD(Innertube.TAG, "insertOfflineBean bean->${bean}")
|
||||
LogTag.LogD(TAG, "insertOfflineBean bean->${bean}")
|
||||
App.appOfflineDBManager.insertOfflineBean(bean)
|
||||
}
|
||||
|
||||
@ -247,14 +245,30 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope
|
||||
thumbnail = mediaItem.mediaMetadata.artworkUri.toString(),
|
||||
isFavorite = true
|
||||
)
|
||||
LogTag.LogD(Innertube.TAG, "insertFavoriteBean bean->${bean}")
|
||||
LogTag.LogD(TAG, "insertFavoriteBean bean->${bean}")
|
||||
App.appFavoriteDBManager.insertFavoriteBean(bean)
|
||||
}
|
||||
|
||||
fun withPermission(): Boolean {
|
||||
//先判断当前配置的开关是否为true,为false的话就直接进入A
|
||||
LogTag.LogD(TAG, "withPermission shouldEnterMusicPage->${appStore.shouldEnterMusicPage}")
|
||||
if (!appStore.shouldEnterMusicPage) {
|
||||
return false
|
||||
}
|
||||
// 不允许的国家代码
|
||||
val restrictedCountries = setOf("CN", "HK", "TW", "JP", "KR", "GB", "CH", "BE", "MO", "SG")
|
||||
val restrictedCountries = setOf(
|
||||
// "CN",
|
||||
// "HK",
|
||||
"TW",
|
||||
"JP",
|
||||
"KR",
|
||||
"GB",
|
||||
"CH",
|
||||
"BE",
|
||||
"MO",
|
||||
"SG")
|
||||
// 检查是否包含当前的国家代码
|
||||
LogTag.LogD(TAG, "withPermission ipCountryCode->${appStore.ipCountryCode}")
|
||||
if (appStore.ipCountryCode in restrictedCountries) {
|
||||
return false
|
||||
}
|
||||
@ -275,9 +289,9 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope
|
||||
//525 Singapore (Republic of)
|
||||
val restrictedCountryCodes =
|
||||
setOf(
|
||||
"460",
|
||||
"461",
|
||||
"454",
|
||||
// "460",
|
||||
// "461",
|
||||
// "454",
|
||||
"466",
|
||||
"440",
|
||||
"441",
|
||||
@ -290,6 +304,7 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope
|
||||
"525"
|
||||
)
|
||||
val currentCountryCode = getCountryCode(this)
|
||||
LogTag.LogD(TAG, "withPermission currentCountryCode->${currentCountryCode}")
|
||||
return currentCountryCode !in restrictedCountryCodes
|
||||
}
|
||||
}
|
||||
@ -31,10 +31,8 @@ class AppOfflineDBManager private constructor(context: Context) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val offlineBean = getOfflineBeanByID(bean.videoId)
|
||||
if (offlineBean == null) {
|
||||
LogTag.LogD(LogTag.VO_TEST_ONLY,"insertOfflineBean")
|
||||
dao.insertOfflineBean(bean)
|
||||
} else {
|
||||
LogTag.LogD(LogTag.VO_TEST_ONLY,"updateOfflineBean")
|
||||
dao.updateOfflineBean(bean)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package relax.offline.music.firebase
|
||||
|
||||
object Constants {
|
||||
const val KEY_SHOULD_ENTER_MUSIC_PAGE = "key_should_enter_music_page"
|
||||
const val DEFAULT_SHOULD_ENTER_MUSIC_PAGE = false
|
||||
}
|
||||
|
||||
146
app/src/main/java/relax/offline/music/firebase/RemoteConfig.kt
Normal file
146
app/src/main/java/relax/offline/music/firebase/RemoteConfig.kt
Normal file
@ -0,0 +1,146 @@
|
||||
package relax.offline.music.firebase
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.text.TextUtils
|
||||
import com.google.firebase.remoteconfig.ConfigUpdate
|
||||
import com.google.firebase.remoteconfig.ConfigUpdateListener
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigException
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue
|
||||
import relax.offline.music.App
|
||||
import relax.offline.music.BuildConfig
|
||||
import relax.offline.music.sp.AppStore
|
||||
import relax.offline.music.util.LogTag
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class RemoteConfig {
|
||||
|
||||
private val TAG = LogTag.VO_TEST_ONLY
|
||||
private var ctx: Context? = null
|
||||
private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null
|
||||
|
||||
//配置是否初始化成功
|
||||
private var isInit = false
|
||||
|
||||
//上次获取数据的时间
|
||||
private var lastFetchTime: Long = 0
|
||||
private val handler = MHandler(this)
|
||||
|
||||
companion object {
|
||||
const val MSG_REFRESH_CONFIG = 1
|
||||
val instance: RemoteConfig by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
RemoteConfig()
|
||||
}
|
||||
}
|
||||
|
||||
fun init(ctx: Application) {
|
||||
this.ctx = ctx
|
||||
initConfig()
|
||||
fetchConfig()
|
||||
onConfigUpdate()
|
||||
}
|
||||
|
||||
private fun initConfig() {
|
||||
var intervalTime = (60 * 10).toLong()
|
||||
//如果是开发状态,则将提取时间缩短
|
||||
if (BuildConfig.DEBUG) {
|
||||
intervalTime = (60 * 5).toLong()
|
||||
}
|
||||
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
|
||||
val configSettings =
|
||||
FirebaseRemoteConfigSettings.Builder() //默认值12小时的最短提取间隔,如果在间隔内取值,则优先取上次的结果
|
||||
.setMinimumFetchIntervalInSeconds(intervalTime)
|
||||
.build()
|
||||
mFirebaseRemoteConfig!!.setConfigSettingsAsync(configSettings)
|
||||
}
|
||||
|
||||
private fun onConfigUpdate() {
|
||||
mFirebaseRemoteConfig!!.addOnConfigUpdateListener(object : ConfigUpdateListener {
|
||||
override fun onUpdate(configUpdate: ConfigUpdate) {
|
||||
LogTag.LogD(TAG, "Updated keys: " + configUpdate.updatedKeys)
|
||||
|
||||
if (configUpdate.updatedKeys.contains(Constants.KEY_SHOULD_ENTER_MUSIC_PAGE)) {
|
||||
mFirebaseRemoteConfig!!.activate().addOnCompleteListener { task ->
|
||||
if (task.isSuccessful) {
|
||||
updateData("onConfigUpdate", mFirebaseRemoteConfig!!.all)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(error: FirebaseRemoteConfigException) {
|
||||
LogTag.LogD(TAG, "Config update error with code: " + error.code)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("LongLogTag")
|
||||
private fun fetchConfig() {
|
||||
//这里可能会抛出异常 FirebaseRemoteConfigFetchThrottledException
|
||||
try {
|
||||
mFirebaseRemoteConfig!!.fetchAndActivate().addOnCompleteListener { task ->
|
||||
if (task.isSuccessful) {
|
||||
isInit = true
|
||||
lastFetchTime = System.currentTimeMillis()
|
||||
updateData("fetchAndActivate", mFirebaseRemoteConfig!!.all)
|
||||
//24小时后,重新再去获取
|
||||
handler.removeMessages(MSG_REFRESH_CONFIG)
|
||||
handler.sendEmptyMessageDelayed(
|
||||
MSG_REFRESH_CONFIG,
|
||||
(1000 * 60 * 60 * 24).toLong()
|
||||
)
|
||||
} else {
|
||||
//这里需要重新再去获取
|
||||
handler.removeMessages(MSG_REFRESH_CONFIG)
|
||||
handler.sendEmptyMessageDelayed(MSG_REFRESH_CONFIG, (1000 * 60 * 15).toLong())
|
||||
}
|
||||
}
|
||||
} catch (ignore: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateData(from: String, all: Map<String, FirebaseRemoteConfigValue>) {
|
||||
val appStore = AppStore(App.app)
|
||||
for ((key, value) in all) {
|
||||
try {
|
||||
LogTag.LogD(
|
||||
TAG,
|
||||
"from = " + from + "Key = " + key + " Value = " + value.asString()
|
||||
)
|
||||
if (TextUtils.equals(
|
||||
Constants.KEY_SHOULD_ENTER_MUSIC_PAGE, key
|
||||
)
|
||||
) {
|
||||
val shouldEnterMusicPage = value.asBoolean()
|
||||
appStore.shouldEnterMusicPage = shouldEnterMusicPage
|
||||
}
|
||||
} catch (ignore: Exception) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MHandler(remoteConfig: RemoteConfig) : Handler() {
|
||||
private val weakReference: WeakReference<RemoteConfig>
|
||||
|
||||
init {
|
||||
weakReference = WeakReference(remoteConfig)
|
||||
}
|
||||
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
val remoteConfig = weakReference.get()
|
||||
if (remoteConfig?.ctx != null) {
|
||||
if (msg.what == MSG_REFRESH_CONFIG) {
|
||||
remoteConfig.fetchConfig()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package relax.offline.music.sp
|
||||
|
||||
import android.content.Context
|
||||
import relax.offline.music.firebase.Constants
|
||||
import relax.offline.music.sp.store.Store
|
||||
import relax.offline.music.sp.store.asStoreProvider
|
||||
import relax.offline.music.util.PlayMode
|
||||
@ -32,7 +33,7 @@ class AppStore(context: Context) {
|
||||
defaultValue = ""
|
||||
)
|
||||
|
||||
var appUUID : String by store.string(
|
||||
var appUUID: String by store.string(
|
||||
key = APP_UUID,
|
||||
defaultValue = ""
|
||||
)
|
||||
@ -42,10 +43,16 @@ class AppStore(context: Context) {
|
||||
defaultValue = ""
|
||||
)
|
||||
|
||||
var firstOpenIsSucceed : Boolean by store.boolean(
|
||||
var firstOpenIsSucceed: Boolean by store.boolean(
|
||||
key = FIRST_OPEN_IS_SUCCEED,
|
||||
defaultValue = false
|
||||
)
|
||||
|
||||
var shouldEnterMusicPage: Boolean by store.boolean(
|
||||
key = Constants.KEY_SHOULD_ENTER_MUSIC_PAGE,
|
||||
defaultValue = Constants.DEFAULT_SHOULD_ENTER_MUSIC_PAGE
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val FILE_NAME = "music_oo_app"
|
||||
const val SEARCH_HISTORY = "search_history"
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
package relax.offline.music.util
|
||||
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
|
||||
object AnalysisUtil {
|
||||
private lateinit var firebaseAnalytics: FirebaseAnalytics
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package relax.offline.music.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import relax.offline.music.App
|
||||
import relax.offline.music.activity.LaunchActivity
|
||||
|
||||
/**
|
||||
* 一个处理应用程序生命周期事件并管理启动页显示的类。
|
||||
*
|
||||
* @param application 应用程序实例。
|
||||
*/
|
||||
class AppLifecycleHandler(private val application: Application) : Application.ActivityLifecycleCallbacks {
|
||||
|
||||
private var activityReferences = 0
|
||||
private var isActivityChangingConfigurations = false
|
||||
private var lastPausedTime: Long = 0
|
||||
private val intervalTime = 5000L
|
||||
|
||||
init {
|
||||
application.registerActivityLifecycleCallbacks(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
|
||||
|
||||
override fun onActivityStarted(activity: Activity) {
|
||||
if (++activityReferences == 1 && !isActivityChangingConfigurations) {
|
||||
// 应用进入前台
|
||||
val currentTime = SystemClock.elapsedRealtime()
|
||||
val isAdShowing = App.app.isAdShowing.get()
|
||||
//间隔时间是否满足,当前不是启动页,当前不是广告show
|
||||
if (currentTime - lastPausedTime > intervalTime && activity !is LaunchActivity && !isAdShowing) {
|
||||
val intent = Intent(activity, LaunchActivity::class.java)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResumed(activity: Activity) {}
|
||||
|
||||
override fun onActivityPaused(activity: Activity) {}
|
||||
|
||||
override fun onActivityStopped(activity: Activity) {
|
||||
isActivityChangingConfigurations = activity.isChangingConfigurations
|
||||
if (--activityReferences == 0 && !isActivityChangingConfigurations) {
|
||||
// 应用进入后台
|
||||
lastPausedTime = SystemClock.elapsedRealtime()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
||||
|
||||
override fun onActivityDestroyed(activity: Activity) {}
|
||||
}
|
||||
@ -3,4 +3,6 @@ plugins {
|
||||
id("com.android.application") version "8.2.1" apply false
|
||||
id("org.jetbrains.kotlin.android") version "1.9.22" apply false
|
||||
id("org.jetbrains.kotlin.plugin.serialization") version "1.7.20" apply false
|
||||
id("com.google.gms.google-services") version "4.3.15" apply false
|
||||
id("com.google.firebase.crashlytics") version "2.9.5" apply false
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user