2 Commits

Author SHA1 Message Date
efa96c8e74 修正trtc sdk初始化问题 2024-10-24 17:40:46 +08:00
dbcb4025a6 优化启动速度 2024-10-24 17:17:01 +08:00
11 changed files with 182 additions and 114 deletions

View File

@@ -38,7 +38,7 @@
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/Theme.App.Starting" android:theme="@style/Theme.RiderPro"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@@ -7,6 +7,7 @@ import android.icu.util.TimeZone
import android.util.Log import android.util.Log
import com.aiosman.riderpro.data.AccountService import com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.AccountServiceImpl import com.aiosman.riderpro.data.AccountServiceImpl
import com.aiosman.riderpro.data.UserAuth
import com.aiosman.riderpro.ui.favourite.FavouriteListViewModel import com.aiosman.riderpro.ui.favourite.FavouriteListViewModel
import com.aiosman.riderpro.ui.favourite.FavouriteNoticeViewModel import com.aiosman.riderpro.ui.favourite.FavouriteNoticeViewModel
import com.aiosman.riderpro.ui.follower.FollowerNoticeViewModel import com.aiosman.riderpro.ui.follower.FollowerNoticeViewModel
@@ -25,6 +26,8 @@ import com.tencent.imsdk.v2.V2TIMManager
import com.tencent.imsdk.v2.V2TIMSDKConfig import com.tencent.imsdk.v2.V2TIMSDKConfig
import com.tencent.imsdk.v2.V2TIMUserFullInfo import com.tencent.imsdk.v2.V2TIMUserFullInfo
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
@@ -32,46 +35,70 @@ object AppState {
var UserId: Int? = null var UserId: Int? = null
suspend fun initWithAccount(scope: CoroutineScope, context: Context) { suspend fun initWithAccount(scope: CoroutineScope, context: Context) {
Log.d("AppState", "initWithAccount")
val accountService: AccountService = AccountServiceImpl() val accountService: AccountService = AccountServiceImpl()
// Declare resp outside the try-catch block
var resp: UserAuth? = null
// 获取用户认证信息 // 获取用户认证信息
val resp = accountService.getMyAccount() // 在 IO 线程池中异步执行 getAccount()
// 更新必要的用户信息 withContext(Dispatchers.IO) {
val calendar: Calendar = Calendar.getInstance() try {
val tz: TimeZone = calendar.timeZone resp = accountService.getMyAccount()
val offsetInMillis: Int = tz.rawOffset // 账户有效 - No need to explicitly set a flag here
accountService.updateUserExtra( } catch (e: Exception) {
Utils.getCurrentLanguage(), // 处理异常,例如记录日志、显示错误信息等
// 时区偏移量单位是秒 // 账户无效 - resp will remain null
offsetInMillis / 1000,
tz.displayName
)
// 设置当前登录用户 ID
UserId = resp.id
// 注册 JPush
Messaging.registerDevice(scope, context)
// 注册 Trtc
val config = V2TIMSDKConfig()
config.logLevel = V2TIMSDKConfig.V2TIM_LOG_INFO
config.logListener = object : V2TIMLogListener() {
override fun onLog(logLevel: Int, logContent: String) {
Log.d("V2TIMLogListener", logContent)
} }
} }
val appConfig = accountService.getAppConfig()
V2TIMManager.getInstance().initSDK(context, appConfig.trtcAppId, config) // 根据 isAccountValidate 的值来决定后续操作
try { if (resp != null) {
val sign = accountService.getMyTrtcSign() AppStore.updateLoginState(true)
loginToTrtc(sign.userId, sign.sig) // ... 账户有效时的操作,例如更新用户信息、注册 JPush 等 ...
updateTrtcUserProfile() // 更新必要的用户信息
// 登录成功后启动TrtcService val calendar: Calendar = Calendar.getInstance()
context.startService( val tz: TimeZone = calendar.timeZone
Intent(context, TrtcService::class.java) val offsetInMillis: Int = tz.rawOffset
accountService.updateUserExtra(
Utils.getCurrentLanguage(),
// 时区偏移量单位是秒
offsetInMillis / 1000,
tz.displayName
) )
} catch (e: Exception) { // 设置当前登录用户 ID
e.printStackTrace() UserId = resp?.id // Access id from the userAuth parameter
// 初始化 JPushManager
JPushManager.init(context)
// 注册 JPush
Messaging.registerDevice(scope, context)
// 注册 Trtc
val config = V2TIMSDKConfig()
config.logLevel = V2TIMSDKConfig.V2TIM_LOG_INFO
config.logListener = object : V2TIMLogListener() {
override fun onLog(logLevel: Int, logContent: String) {
Log.d("V2TIMLogListener", logContent)
}
}
val appConfig = accountService.getAppConfig()
V2TIMManager.getInstance().initSDK(context, appConfig.trtcAppId, config)
try {
val sign = accountService.getMyTrtcSign()
loginToTrtc(sign.userId, sign.sig)
updateTrtcUserProfile()
// 登录成功后启动TrtcService
context.startService(
Intent(context, TrtcService::class.java)
)
} catch (e: Exception) {
e.printStackTrace()
}
} else {
// ... 账户无效时的操作 ...
AppStore.updateLoginState(false)
} }
} }

View File

@@ -0,0 +1,24 @@
package com.aiosman.riderpro
import android.content.Context
import cn.jiguang.api.utils.JCollectionAuth
import cn.jpush.android.api.JPushInterface
object JPushManager {
private var initialized = false
fun init(context: Context) {
if (!initialized) {
JPushInterface.setDebugMode(true)
// 调整点一初始化代码前增加setAuth调用
JCollectionAuth.setAuth(context, true)
JPushInterface.init(context)
initialized = true
}
}
fun getRegistrationID(context: Context): String {
init(context) // 确保 JPush 已经初始化
return JPushInterface.getRegistrationID(context)
}
}

View File

@@ -69,106 +69,92 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// 监听应用生命周期 // 监听应用生命周期
ProcessLifecycleOwner.get().lifecycle.addObserver(MainActivityLifecycleObserver()) ProcessLifecycleOwner.get().lifecycle.addObserver(MainActivityLifecycleObserver())
// 创建通知渠道 // 创建通知渠道
createNotificationChannel() createNotificationChannel()
// 沉浸式状态栏 // 沉浸式状态栏
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
// 初始化 Places SDK
// 初始化 Firebase Analytics
// analytics = Firebase.analytics
// 请求通知权限 // 请求通知权限
askNotificationPermission() askNotificationPermission()
// 加载一些本地化的配置 // 加载一些本地化的配置
AppStore.init(this) AppStore.init(this)
JPushInterface.setDebugMode(true);
// 调整点一初始化代码前增加setAuth调用
JCollectionAuth.setAuth(this, true)
JPushInterface.init(this)
enableEdgeToEdge() enableEdgeToEdge()
// 初始化腾讯云通信 SDK setContent {
// 根据登录状态决定启动页面
val startDestination = if (AppStore.isLoggedIn) {
scope.launch { NavigationRoute.Index.route
// 检查是否有登录态 } else {
val isAccountValidate = getAccount() NavigationRoute.Login.route
var startDestination = NavigationRoute.Login.route
// 如果有登录态,且记住登录状态,且账号有效,则初始化 FCM下一步进入首页
if (AppStore.token != null && AppStore.rememberMe && isAccountValidate) {
AppState.initWithAccount(scope, this@MainActivity)
startDestination = NavigationRoute.Index.route
} }
setContent { Navigation(startDestination) { navController ->
Navigation(startDestination) { navController -> // 处理带有 postId 的通知点击
// 处理带有 postId 的通知点击 val postId = intent.getStringExtra("POST_ID")
val postId = intent.getStringExtra("POST_ID") var commentId = intent.getStringExtra("COMMENT_ID")
var commentId = intent.getStringExtra("COMMENT_ID") val action = intent.getStringExtra("ACTION")
val action = intent.getStringExtra("ACTION") if (action == "newFollow") {
if (action == "newFollow") { navController.navigate(NavigationRoute.Followers.route)
navController.navigate(NavigationRoute.Followers.route) return@Navigation
return@Navigation }
} if (action == "followCount") {
if (action == "followCount") { navController.navigate(NavigationRoute.Followers.route)
navController.navigate(NavigationRoute.Followers.route) return@Navigation
return@Navigation }
} if (action == "TRTC_NEW_MESSAGE") {
if (action == "TRTC_NEW_MESSAGE") { val userService: UserService = UserServiceImpl()
val userService:UserService = UserServiceImpl() val sender = intent.getStringExtra("SENDER")
val sender = intent.getStringExtra("SENDER") sender?.let {
sender?.let { scope.launch {
scope.launch { try {
try { val profile = userService.getUserProfileByTrtcUserId(it)
val profile = userService.getUserProfileByTrtcUserId(it) navController.navigate(
navController.navigate(NavigationRoute.Chat.route.replace( NavigationRoute.Chat.route.replace(
"{id}", "{id}",
profile.id.toString() profile.id.toString()
)) )
}catch (e:Exception){ )
e.printStackTrace() } catch (e: Exception) {
} e.printStackTrace()
} }
} }
return@Navigation
}
if (commentId == null) {
commentId = "0"
}
if (postId != null) {
Log.d("MainActivity", "Navigation to Post$postId")
navController.navigateToPost(
id = postId.toInt(),
highlightCommentId = commentId.toInt(),
initImagePagerIndex = 0
)
}
// 处理分享过来的图片
if (intent?.action == Intent.ACTION_SEND || intent?.action == Intent.ACTION_SEND_MULTIPLE) {
val imageUris: List<Uri>? = if (intent.action == Intent.ACTION_SEND) {
listOf(intent.getParcelableExtra(Intent.EXTRA_STREAM)!!)
} else {
intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM)
}
NewPostViewModel.asNewPostWithImageUris(imageUris!!.map { it.toString() })
navController.navigate(NavigationRoute.NewPost.route)
} }
return@Navigation
} }
} if (commentId == null) {
commentId = "0"
}
if (postId != null) {
Log.d("MainActivity", "Navigation to Post$postId")
navController.navigateToPost(
id = postId.toInt(),
highlightCommentId = commentId.toInt(),
initImagePagerIndex = 0
)
}
// 处理分享过来的图片
if (intent?.action == Intent.ACTION_SEND || intent?.action == Intent.ACTION_SEND_MULTIPLE) {
val imageUris: List<Uri>? = if (intent.action == Intent.ACTION_SEND) {
listOf(intent.getParcelableExtra(Intent.EXTRA_STREAM)!!)
} else {
intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM)
}
NewPostViewModel.asNewPostWithImageUris(imageUris!!.map { it.toString() })
navController.navigate(NavigationRoute.NewPost.route)
}
}
} }
} }
/** /**
* 请求通知权限 * 请求通知权限
*/ */

View File

@@ -24,7 +24,7 @@ object Messaging {
fun registerJpush(scope: CoroutineScope, context: Context) { fun registerJpush(scope: CoroutineScope, context: Context) {
val accountService: AccountService = AccountServiceImpl() val accountService: AccountService = AccountServiceImpl()
val regId = JPushInterface.getRegistrationID(context) val regId = JPushManager.getRegistrationID(context)
scope.launch { scope.launch {
accountService.registerMessageChannel(client = "jpush", identifier = regId) accountService.registerMessageChannel(client = "jpush", identifier = regId)
} }
@@ -32,7 +32,7 @@ object Messaging {
private suspend fun unregisterJpush(context: Context) { private suspend fun unregisterJpush(context: Context) {
val accountService: AccountService = AccountServiceImpl() val accountService: AccountService = AccountServiceImpl()
val regId = JPushInterface.getRegistrationID(context) val regId = JPushManager.getRegistrationID(context)
accountService.unregisterMessageChannel(client = "jpush", identifier = regId) accountService.unregisterMessageChannel(client = "jpush", identifier = regId)
} }

View File

@@ -1,5 +1,6 @@
package com.aiosman.riderpro.data package com.aiosman.riderpro.data
import android.util.Log
import com.aiosman.riderpro.AppState import com.aiosman.riderpro.AppState
import com.aiosman.riderpro.data.api.ApiClient import com.aiosman.riderpro.data.api.ApiClient
import com.aiosman.riderpro.data.api.AppConfig import com.aiosman.riderpro.data.api.AppConfig
@@ -411,6 +412,7 @@ class AccountServiceImpl : AccountService {
password = password, password = password,
captcha = captchaInfo, captcha = captchaInfo,
)) ))
Log.d("login", resp.toString())
if (!resp.isSuccessful) { if (!resp.isSuccessful) {
parseErrorResponse(resp.errorBody())?.let { parseErrorResponse(resp.errorBody())?.let {
throw it.toServiceException() throw it.toServiceException()

View File

@@ -14,6 +14,11 @@ object AppStore {
var rememberMe: Boolean = false var rememberMe: Boolean = false
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
lateinit var googleSignInOptions: GoogleSignInOptions lateinit var googleSignInOptions: GoogleSignInOptions
var isLoggedIn: Boolean = false
private set
fun init(context: Context) { fun init(context: Context) {
sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
this.loadData() this.loadData()
@@ -25,6 +30,13 @@ object AppStore {
googleSignInOptions = gso googleSignInOptions = gso
} }
fun updateLoginState(isLoggedIn: Boolean) { // 添加更新 isLoggedIn 的方法
this.isLoggedIn = isLoggedIn
sharedPreferences.edit().apply {
putBoolean("isLoggedIn", isLoggedIn)
}.apply()
}
suspend fun saveData() { suspend fun saveData() {
// shared preferences // shared preferences
sharedPreferences.edit().apply { sharedPreferences.edit().apply {
@@ -37,5 +49,6 @@ object AppStore {
// shared preferences // shared preferences
token = sharedPreferences.getString("token", null) token = sharedPreferences.getString("token", null)
rememberMe = sharedPreferences.getBoolean("rememberMe", false) rememberMe = sharedPreferences.getBoolean("rememberMe", false)
isLoggedIn = sharedPreferences.getBoolean("isLoggedIn", false)
} }
} }

View File

@@ -344,7 +344,7 @@ fun ChatSelfItem(item: ChatItem) {
max = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 250.dp else 150.dp) max = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 250.dp else 150.dp)
) )
.clip(RoundedCornerShape(8.dp)) .clip(RoundedCornerShape(8.dp))
.background(Color(0xFF000000)) .background(Color(0xFF007FFF))
.padding( .padding(
vertical = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 8.dp else 0.dp), vertical = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 8.dp else 0.dp),
horizontal = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 16.dp else 0.dp) horizontal = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 16.dp else 0.dp)

View File

@@ -1,5 +1,6 @@
package com.aiosman.riderpro.ui.index package com.aiosman.riderpro.ui.index
import android.util.Log
import androidx.compose.animation.animateColorAsState import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
@@ -26,11 +27,14 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.aiosman.riderpro.AppState
import com.aiosman.riderpro.LocalNavController import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.ui.NavigationRoute import com.aiosman.riderpro.ui.NavigationRoute
import com.aiosman.riderpro.ui.index.tabs.add.AddPage import com.aiosman.riderpro.ui.index.tabs.add.AddPage
import com.aiosman.riderpro.ui.index.tabs.message.MessageListViewModel
import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen
import com.aiosman.riderpro.ui.index.tabs.moment.MomentsList import com.aiosman.riderpro.ui.index.tabs.moment.MomentsList
import com.aiosman.riderpro.ui.index.tabs.profile.ProfileWrap import com.aiosman.riderpro.ui.index.tabs.profile.ProfileWrap
@@ -48,6 +52,7 @@ fun IndexScreen() {
val navigationBarHeight = with(LocalDensity.current) { val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp() WindowInsets.navigationBars.getBottom(this).toDp()
} }
val context = LocalContext.current
val navController = LocalNavController.current val navController = LocalNavController.current
val item = listOf( val item = listOf(
NavigationItem.Home, NavigationItem.Home,
@@ -62,6 +67,11 @@ fun IndexScreen() {
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(Color.Transparent) systemUiController.setNavigationBarColor(Color.Transparent)
Log.d("IndexScreen", "IndexScreen: ")
coroutineScope.launch {
AppState.initWithAccount(coroutineScope, context)
MessageListViewModel.initData(context)
}
} }
Scaffold( Scaffold(
bottomBar = { bottomBar = {

View File

@@ -64,7 +64,6 @@ fun NotificationsScreen() {
}) })
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(Color.Transparent) systemUiController.setNavigationBarColor(Color.Transparent)
MessageListViewModel.initData(context)
} }
Column( Column(
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()

View File

@@ -1,5 +1,6 @@
package com.aiosman.riderpro.ui.login package com.aiosman.riderpro.ui.login
import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -98,6 +99,7 @@ fun UserAuthScreen() {
if (!validateForm()) { if (!validateForm()) {
return return
} }
Log.d("UserAuthScreen", "onLogin: $captchaInfo")
scope.launch { scope.launch {
try { try {
// 检查是否需要验证码 // 检查是否需要验证码
@@ -106,8 +108,13 @@ fun UserAuthScreen() {
return@launch return@launch
} }
// 获取用户凭证 // 获取用户凭证
Log.d("UserAuthScreen", "loginUserWithPassword")
Log.d("UserAuthScreen", "email: $email")
Log.d("UserAuthScreen", "password: $password")
val authResp = accountService.loginUserWithPassword(email, password, captchaInfo) val authResp = accountService.loginUserWithPassword(email, password, captchaInfo)
if (authResp.token != null) { if (authResp.token != null) {
Log.d("UserAuthScreen", "authResp.token: ${authResp.token}")
AppStore.updateLoginState(true)
AppStore.apply { AppStore.apply {
token = authResp.token token = authResp.token
this.rememberMe = rememberMe this.rememberMe = rememberMe