2024-06-22 04:25:20 +08:00
|
|
|
|
package com.aiosman.riderpro
|
|
|
|
|
|
|
2024-09-06 20:08:51 +08:00
|
|
|
|
import android.Manifest
|
2024-10-26 06:02:30 +08:00
|
|
|
|
import android.app.AlertDialog
|
|
|
|
|
|
import android.app.DownloadManager
|
2024-09-06 20:08:51 +08:00
|
|
|
|
import android.app.NotificationChannel
|
|
|
|
|
|
import android.app.NotificationManager
|
|
|
|
|
|
import android.content.Context
|
2024-09-17 16:06:27 +08:00
|
|
|
|
import android.content.Intent
|
2024-10-26 06:02:30 +08:00
|
|
|
|
import android.content.IntentFilter
|
2024-09-06 20:08:51 +08:00
|
|
|
|
import android.content.pm.PackageManager
|
2024-09-17 16:06:27 +08:00
|
|
|
|
import android.net.Uri
|
2024-09-06 20:08:51 +08:00
|
|
|
|
import android.os.Build
|
2024-06-22 04:25:20 +08:00
|
|
|
|
import android.os.Bundle
|
2024-10-26 06:02:30 +08:00
|
|
|
|
import android.os.Environment
|
2024-09-06 20:08:51 +08:00
|
|
|
|
import android.util.Log
|
2024-06-22 04:25:20 +08:00
|
|
|
|
import androidx.activity.ComponentActivity
|
|
|
|
|
|
import androidx.activity.compose.setContent
|
|
|
|
|
|
import androidx.activity.enableEdgeToEdge
|
2024-09-05 22:04:41 +08:00
|
|
|
|
import androidx.activity.result.contract.ActivityResultContracts
|
2024-10-26 06:02:30 +08:00
|
|
|
|
import androidx.annotation.RequiresApi
|
2024-07-20 16:06:37 +08:00
|
|
|
|
import androidx.compose.animation.AnimatedContentScope
|
|
|
|
|
|
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
|
|
|
|
|
import androidx.compose.animation.SharedTransitionScope
|
2024-10-24 23:53:51 +08:00
|
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
2024-07-12 23:37:21 +08:00
|
|
|
|
import androidx.compose.runtime.compositionLocalOf
|
2024-10-24 23:53:51 +08:00
|
|
|
|
import androidx.compose.ui.graphics.Color
|
2024-09-05 22:04:41 +08:00
|
|
|
|
import androidx.core.content.ContextCompat
|
2024-07-13 17:41:51 +08:00
|
|
|
|
import androidx.core.view.WindowCompat
|
2024-09-06 20:08:51 +08:00
|
|
|
|
import androidx.lifecycle.ProcessLifecycleOwner
|
2024-10-26 06:02:30 +08:00
|
|
|
|
import androidx.lifecycle.lifecycleScope
|
2024-06-22 04:25:20 +08:00
|
|
|
|
import androidx.navigation.NavHostController
|
2024-09-18 17:03:26 +08:00
|
|
|
|
import cn.jiguang.api.utils.JCollectionAuth
|
|
|
|
|
|
import cn.jpush.android.api.JPushInterface
|
2024-07-31 14:50:55 +08:00
|
|
|
|
import com.aiosman.riderpro.data.AccountService
|
2024-08-23 18:31:14 +08:00
|
|
|
|
import com.aiosman.riderpro.data.AccountServiceImpl
|
2024-10-11 16:51:51 +08:00
|
|
|
|
import com.aiosman.riderpro.data.UserService
|
|
|
|
|
|
import com.aiosman.riderpro.data.UserServiceImpl
|
2024-10-26 06:02:30 +08:00
|
|
|
|
import com.aiosman.riderpro.model.ApkInstallReceiver
|
|
|
|
|
|
import com.aiosman.riderpro.model.UpdateInfo
|
2024-07-23 15:25:00 +08:00
|
|
|
|
import com.aiosman.riderpro.ui.Navigation
|
2024-07-30 16:57:25 +08:00
|
|
|
|
import com.aiosman.riderpro.ui.NavigationRoute
|
2024-09-22 15:35:42 +08:00
|
|
|
|
import com.aiosman.riderpro.ui.navigateToPost
|
2024-09-17 16:06:27 +08:00
|
|
|
|
import com.aiosman.riderpro.ui.post.NewPostViewModel
|
2024-10-24 23:53:51 +08:00
|
|
|
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
2024-09-01 16:59:11 +08:00
|
|
|
|
import com.google.firebase.analytics.FirebaseAnalytics
|
2024-10-26 06:02:30 +08:00
|
|
|
|
import com.google.gson.Gson
|
2024-07-30 16:57:25 +08:00
|
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
|
|
import kotlinx.coroutines.launch
|
2024-10-26 06:02:30 +08:00
|
|
|
|
import kotlinx.coroutines.withContext
|
|
|
|
|
|
import okhttp3.OkHttpClient
|
|
|
|
|
|
import okhttp3.Request
|
2024-06-22 04:25:20 +08:00
|
|
|
|
|
2024-09-23 23:47:16 +08:00
|
|
|
|
|
2024-06-22 04:25:20 +08:00
|
|
|
|
class MainActivity : ComponentActivity() {
|
2024-09-05 22:04:41 +08:00
|
|
|
|
// Firebase Analytics
|
2024-09-01 16:59:11 +08:00
|
|
|
|
private lateinit var analytics: FirebaseAnalytics
|
2024-07-30 16:57:25 +08:00
|
|
|
|
private val scope = CoroutineScope(Dispatchers.Main)
|
2024-10-26 06:02:30 +08:00
|
|
|
|
val context = this
|
|
|
|
|
|
private val apkInstallReceiver = ApkInstallReceiver()
|
2024-09-08 21:46:44 +08:00
|
|
|
|
|
2024-09-05 22:04:41 +08:00
|
|
|
|
// 请求通知权限
|
|
|
|
|
|
private val requestPermissionLauncher = registerForActivityResult(
|
|
|
|
|
|
ActivityResultContracts.RequestPermission(),
|
|
|
|
|
|
) { isGranted: Boolean ->
|
|
|
|
|
|
if (isGranted) {
|
|
|
|
|
|
// FCM SDK (and your app) can post notifications.
|
|
|
|
|
|
} else {
|
2024-09-23 23:47:16 +08:00
|
|
|
|
|
2024-09-05 22:04:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-26 06:02:30 +08:00
|
|
|
|
@RequiresApi(Build.VERSION_CODES.P)
|
|
|
|
|
|
fun getVersionCode(context: Context): Int {
|
|
|
|
|
|
val packageManager = context.packageManager
|
|
|
|
|
|
val packageInfo = packageManager.getPackageInfo(context.packageName,0)
|
|
|
|
|
|
return packageInfo.longVersionCode.toInt()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@RequiresApi(Build.VERSION_CODES.P)
|
|
|
|
|
|
private fun checkUpdate() {
|
|
|
|
|
|
lifecycleScope.launch(Dispatchers.IO) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
val client = OkHttpClient()
|
|
|
|
|
|
val request = Request.Builder()
|
|
|
|
|
|
.url("https://rider-pro.aiosman.com/beta_api/static/update/beta/version.json")
|
|
|
|
|
|
.build()
|
|
|
|
|
|
val response = client.newCall(request).execute()
|
|
|
|
|
|
|
|
|
|
|
|
if (response.isSuccessful) {
|
|
|
|
|
|
val responseBody = response.body?.string()
|
|
|
|
|
|
val updateInfo = Gson().fromJson(responseBody, UpdateInfo::class.java)
|
|
|
|
|
|
|
|
|
|
|
|
val versionCode = getVersionCode(context)
|
|
|
|
|
|
// 检查是否有新版本
|
|
|
|
|
|
Log.d("MainActivity", "Current version code: $versionCode")
|
|
|
|
|
|
Log.d("MainActivity", "Server version code: ${updateInfo.versionCode}")
|
|
|
|
|
|
if (updateInfo.versionCode > versionCode) {
|
|
|
|
|
|
withContext(Dispatchers.Main) {
|
|
|
|
|
|
showUpdateDialog(updateInfo)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
// 处理网络请求失败
|
|
|
|
|
|
e.printStackTrace()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun showUpdateDialog(updateInfo: UpdateInfo) {
|
|
|
|
|
|
val builder = AlertDialog.Builder(this)
|
|
|
|
|
|
builder.setTitle("发现新版本 v${updateInfo.versionName}")
|
|
|
|
|
|
builder.setMessage(updateInfo.updateContent)
|
|
|
|
|
|
builder.setPositiveButton("立即更新") { dialog, _ ->
|
|
|
|
|
|
|
|
|
|
|
|
downloadApk(updateInfo.downloadUrl,updateInfo.versionName)
|
|
|
|
|
|
dialog.dismiss()
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!updateInfo.forceUpdate) {
|
|
|
|
|
|
builder.setNegativeButton("稍后再说") { dialog, _ ->
|
|
|
|
|
|
dialog.dismiss()
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
builder.setCancelable(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
builder.show()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun downloadApk(downloadUrl: String,versionName: String) {
|
|
|
|
|
|
// 使用 DownloadManager 下载 APK 文件
|
|
|
|
|
|
val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
|
|
|
|
|
|
val request = DownloadManager.Request(Uri.parse(downloadUrl))
|
|
|
|
|
|
val apkFileName = "RiderPro_v${versionName.replace(".","_")}.apk"
|
|
|
|
|
|
request.setMimeType("application/vnd.android.package-archive") // 添加这行代码
|
|
|
|
|
|
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkFileName)
|
|
|
|
|
|
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
|
|
|
|
|
val downloadId = downloadManager.enqueue(request)
|
|
|
|
|
|
Log.d("MainActivity", "Download enqueued with ID: $downloadId")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-05 22:04:41 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取账号信息
|
|
|
|
|
|
*/
|
2024-09-06 17:43:43 +08:00
|
|
|
|
private suspend fun getAccount(): Boolean {
|
2024-08-23 18:31:14 +08:00
|
|
|
|
val accountService: AccountService = AccountServiceImpl()
|
2024-08-11 17:15:17 +08:00
|
|
|
|
try {
|
|
|
|
|
|
val resp = accountService.getMyAccount()
|
|
|
|
|
|
return true
|
2024-08-13 22:32:27 +08:00
|
|
|
|
} catch (e: Exception) {
|
2024-08-11 17:15:17 +08:00
|
|
|
|
return false
|
|
|
|
|
|
}
|
2024-07-30 16:57:25 +08:00
|
|
|
|
}
|
2024-08-11 17:15:17 +08:00
|
|
|
|
|
2024-10-26 06:02:30 +08:00
|
|
|
|
@RequiresApi(Build.VERSION_CODES.P)
|
2024-06-22 04:25:20 +08:00
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
|
|
super.onCreate(savedInstanceState)
|
2024-09-05 22:04:41 +08:00
|
|
|
|
// 监听应用生命周期
|
|
|
|
|
|
ProcessLifecycleOwner.get().lifecycle.addObserver(MainActivityLifecycleObserver())
|
|
|
|
|
|
// 创建通知渠道
|
|
|
|
|
|
createNotificationChannel()
|
|
|
|
|
|
// 沉浸式状态栏
|
2024-07-13 17:41:51 +08:00
|
|
|
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
2024-09-05 22:04:41 +08:00
|
|
|
|
// 初始化 Places SDK
|
2024-09-22 20:02:58 +08:00
|
|
|
|
|
2024-09-05 22:04:41 +08:00
|
|
|
|
// 初始化 Firebase Analytics
|
2024-09-18 17:03:26 +08:00
|
|
|
|
// analytics = Firebase.analytics
|
2024-09-05 22:04:41 +08:00
|
|
|
|
// 请求通知权限
|
|
|
|
|
|
askNotificationPermission()
|
|
|
|
|
|
// 加载一些本地化的配置
|
2024-07-30 16:57:25 +08:00
|
|
|
|
AppStore.init(this)
|
2024-09-01 16:59:11 +08:00
|
|
|
|
|
2024-09-18 17:03:26 +08:00
|
|
|
|
JPushInterface.setDebugMode(true);
|
|
|
|
|
|
|
|
|
|
|
|
// 调整点一:初始化代码前增加setAuth调用
|
|
|
|
|
|
JCollectionAuth.setAuth(this, true)
|
|
|
|
|
|
|
|
|
|
|
|
JPushInterface.init(this)
|
|
|
|
|
|
|
2024-10-24 23:53:51 +08:00
|
|
|
|
if (AppState.darkMode) {
|
|
|
|
|
|
window.decorView.setBackgroundColor(android.graphics.Color.BLACK)
|
|
|
|
|
|
}
|
2024-06-22 04:25:20 +08:00
|
|
|
|
enableEdgeToEdge()
|
2024-07-30 16:57:25 +08:00
|
|
|
|
|
2024-10-26 06:02:30 +08:00
|
|
|
|
// 注册广播接收器
|
|
|
|
|
|
val intentFilter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
|
|
|
|
|
|
registerReceiver(apkInstallReceiver, intentFilter, RECEIVER_NOT_EXPORTED)
|
|
|
|
|
|
|
|
|
|
|
|
checkUpdate()
|
|
|
|
|
|
|
2024-09-23 23:47:16 +08:00
|
|
|
|
// 初始化腾讯云通信 SDK
|
2024-09-18 17:03:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
2024-07-30 16:57:25 +08:00
|
|
|
|
scope.launch {
|
2024-09-05 22:04:41 +08:00
|
|
|
|
// 检查是否有登录态
|
2024-08-11 17:15:17 +08:00
|
|
|
|
val isAccountValidate = getAccount()
|
2024-07-30 16:57:25 +08:00
|
|
|
|
var startDestination = NavigationRoute.Login.route
|
2024-09-05 22:04:41 +08:00
|
|
|
|
// 如果有登录态,且记住登录状态,且账号有效,则初始化 FCM,下一步进入首页
|
2024-08-11 17:15:17 +08:00
|
|
|
|
if (AppStore.token != null && AppStore.rememberMe && isAccountValidate) {
|
2024-09-23 23:47:16 +08:00
|
|
|
|
AppState.initWithAccount(scope, this@MainActivity)
|
2024-07-30 16:57:25 +08:00
|
|
|
|
startDestination = NavigationRoute.Index.route
|
|
|
|
|
|
}
|
2024-09-23 23:47:16 +08:00
|
|
|
|
|
2024-07-30 16:57:25 +08:00
|
|
|
|
setContent {
|
2024-10-24 23:53:51 +08:00
|
|
|
|
|
2024-09-05 22:04:41 +08:00
|
|
|
|
Navigation(startDestination) { navController ->
|
|
|
|
|
|
// 处理带有 postId 的通知点击
|
|
|
|
|
|
val postId = intent.getStringExtra("POST_ID")
|
2024-09-20 17:10:54 +08:00
|
|
|
|
var commentId = intent.getStringExtra("COMMENT_ID")
|
2024-10-11 16:51:51 +08:00
|
|
|
|
val action = intent.getStringExtra("ACTION")
|
2024-09-20 17:10:54 +08:00
|
|
|
|
if (action == "newFollow") {
|
|
|
|
|
|
navController.navigate(NavigationRoute.Followers.route)
|
|
|
|
|
|
return@Navigation
|
|
|
|
|
|
}
|
2024-09-22 15:35:42 +08:00
|
|
|
|
if (action == "followCount") {
|
|
|
|
|
|
navController.navigate(NavigationRoute.Followers.route)
|
|
|
|
|
|
return@Navigation
|
|
|
|
|
|
}
|
2024-10-11 16:51:51 +08:00
|
|
|
|
if (action == "TRTC_NEW_MESSAGE") {
|
|
|
|
|
|
val userService:UserService = UserServiceImpl()
|
|
|
|
|
|
val sender = intent.getStringExtra("SENDER")
|
|
|
|
|
|
sender?.let {
|
|
|
|
|
|
scope.launch {
|
|
|
|
|
|
try {
|
|
|
|
|
|
val profile = userService.getUserProfileByTrtcUserId(it)
|
|
|
|
|
|
navController.navigate(NavigationRoute.Chat.route.replace(
|
|
|
|
|
|
"{id}",
|
|
|
|
|
|
profile.id.toString()
|
|
|
|
|
|
))
|
|
|
|
|
|
}catch (e:Exception){
|
|
|
|
|
|
e.printStackTrace()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return@Navigation
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-20 17:10:54 +08:00
|
|
|
|
if (commentId == null) {
|
|
|
|
|
|
commentId = "0"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-05 22:04:41 +08:00
|
|
|
|
if (postId != null) {
|
|
|
|
|
|
Log.d("MainActivity", "Navigation to Post$postId")
|
2024-09-22 15:35:42 +08:00
|
|
|
|
navController.navigateToPost(
|
|
|
|
|
|
id = postId.toInt(),
|
|
|
|
|
|
highlightCommentId = commentId.toInt(),
|
|
|
|
|
|
initImagePagerIndex = 0
|
2024-09-14 23:27:44 +08:00
|
|
|
|
)
|
2024-09-05 22:04:41 +08:00
|
|
|
|
}
|
2024-09-17 16:06:27 +08:00
|
|
|
|
// 处理分享过来的图片
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2024-09-05 22:04:41 +08:00
|
|
|
|
}
|
2024-09-14 23:27:44 +08:00
|
|
|
|
|
2024-07-30 16:57:25 +08:00
|
|
|
|
}
|
2024-09-05 22:04:41 +08:00
|
|
|
|
|
2024-06-22 04:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-05 22:04:41 +08:00
|
|
|
|
|
2024-10-26 06:02:30 +08:00
|
|
|
|
override fun onDestroy() {
|
|
|
|
|
|
super.onDestroy()
|
|
|
|
|
|
// 取消注册广播接收器
|
|
|
|
|
|
unregisterReceiver(apkInstallReceiver)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-05 22:04:41 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 请求通知权限
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun askNotificationPermission() {
|
|
|
|
|
|
// This is only necessary for API level >= 33 (TIRAMISU)
|
|
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
|
|
|
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
|
|
|
|
|
|
PackageManager.PERMISSION_GRANTED
|
|
|
|
|
|
) {
|
|
|
|
|
|
// FCM SDK (and your app) can post notifications.
|
|
|
|
|
|
} else if (shouldShowRequestPermissionRationale(android.Manifest.permission.POST_NOTIFICATIONS)) {
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// Directly ask for the permission
|
|
|
|
|
|
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 创建通知渠道
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun createNotificationChannel() {
|
|
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
|
|
val channelId = ConstVars.MOMENT_LIKE_CHANNEL_ID
|
|
|
|
|
|
val channelName = ConstVars.MOMENT_LIKE_CHANNEL_NAME
|
|
|
|
|
|
val channel =
|
|
|
|
|
|
NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)
|
|
|
|
|
|
val notificationManager =
|
|
|
|
|
|
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
|
|
|
|
notificationManager.createNotificationChannel(channel)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-22 04:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-12 23:37:21 +08:00
|
|
|
|
val LocalNavController = compositionLocalOf<NavHostController> {
|
|
|
|
|
|
error("NavController not provided")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-20 16:06:37 +08:00
|
|
|
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
|
|
|
|
|
val LocalSharedTransitionScope = compositionLocalOf<SharedTransitionScope> {
|
|
|
|
|
|
error("SharedTransitionScope not provided")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
val LocalAnimatedContentScope = compositionLocalOf<AnimatedContentScope> {
|
|
|
|
|
|
error("AnimatedContentScope not provided")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-14 17:14:05 +08:00
|
|
|
|
|
2024-10-26 06:02:30 +08:00
|
|
|
|
|