| | |
| | | |
| | | implementation 'com.github.castorflex:SmoothProgressBar:1.1.0' |
| | | |
| | | api 'com.tencent.mm.opensdk:wechat-sdk-android:+' |
| | | // api 'com.tencent.mm.opensdk:wechat-sdk-android:+' |
| | | implementation("com.tencent.mm.opensdk:wechat-sdk-android:6.8.28") |
| | | |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 通知权限请求 |
| | | private val notificationPermissionRequest = |
| | | private val notificationPermissionRequest = |
| | | registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> |
| | | if (isGranted) { |
| | | // 权限已授予 |
| | |
| | | |
| | | // 重置提醒计划并检查是否有错过的提醒 |
| | | resetReminders() |
| | | |
| | | |
| | | // 开始权限请求流程 |
| | | startPermissionsFlow() |
| | | } |
| | | |
| | | override fun onResume() { |
| | | super.onResume() |
| | | |
| | | |
| | | // 每次恢复活动时检查短信权限 |
| | | checkAndHandleSmsPermissions(showDialog = false) |
| | | } |
| | | |
| | | |
| | | // 权限请求主流程 |
| | | private fun startPermissionsFlow() { |
| | | // 先请求通知权限,再请求短信权限 |
| | | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { |
| | | // Android 13+ 需要通知权限 |
| | | if (ContextCompat.checkSelfPermission( |
| | | this, |
| | | this, |
| | | Manifest.permission.POST_NOTIFICATIONS |
| | | ) != PackageManager.PERMISSION_GRANTED |
| | | ) { |
| | |
| | | requestSmsPermissions() |
| | | } |
| | | } |
| | | |
| | | |
| | | // 请求短信权限 |
| | | private fun requestSmsPermissions() { |
| | | if (!hasSmsPermissions()) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 检查并处理短信权限(可选是否显示对话框) |
| | | private fun checkAndHandleSmsPermissions(showDialog: Boolean = true) { |
| | | if (!hasSmsPermissions()) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 检查是否有短信权限 |
| | | private fun hasSmsPermissions(): Boolean { |
| | | return ContextCompat.checkSelfPermission( |
| | | this, Manifest.permission.RECEIVE_SMS |
| | | ) == PackageManager.PERMISSION_GRANTED && |
| | | ContextCompat.checkSelfPermission( |
| | | this, Manifest.permission.READ_SMS |
| | | ) == PackageManager.PERMISSION_GRANTED |
| | | ) == PackageManager.PERMISSION_GRANTED && |
| | | ContextCompat.checkSelfPermission( |
| | | this, Manifest.permission.READ_SMS |
| | | ) == PackageManager.PERMISSION_GRANTED |
| | | } |
| | | |
| | | |
| | | // 显示短信权限解释对话框 |
| | | private fun showSmsPermissionExplanationDialog() { |
| | | AlertDialog.Builder(this) |
| | |
| | | .setCancelable(false) |
| | | .show() |
| | | } |
| | | |
| | | |
| | | // 提供给外部调用的请求通知权限方法 |
| | | fun requestNotificationPermission() { |
| | | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { |
| | | // 判断是否已经有通知权限 |
| | | if (ContextCompat.checkSelfPermission( |
| | | this, |
| | | this, |
| | | Manifest.permission.POST_NOTIFICATIONS |
| | | ) != PackageManager.PERMISSION_GRANTED |
| | | ) { |
| | |
| | | private fun registerSmsReceiver() { |
| | | // 确保不重复注册 |
| | | if (smsReceiver != null) return |
| | | |
| | | |
| | | Log.d("SMS_DEBUG", "MainActivity注册短信接收器") |
| | | smsReceiver = SmsReceiver() |
| | | val filter = IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION) |
| | |
| | | private fun setupCheckBoxes() { |
| | | // 全选分类按钮逻辑 |
| | | binding.tvSelectAll.setOnClickListener { |
| | | val shouldCheck = !(binding.checkBoxExpress.isChecked && binding.checkBoxFinance.isChecked && |
| | | binding.checkBoxIncome.isChecked && binding.checkBoxFlight.isChecked && binding.checkBoxTrain.isChecked) |
| | | |
| | | val shouldCheck = !(binding.checkBoxExpress.isChecked && binding.checkBoxFinance.isChecked && binding.checkBoxIncome.isChecked ) |
| | | // binding.checkBoxFlight.isChecked && binding.checkBoxTrain.isChecked) |
| | | |
| | | |
| | | binding.checkBoxExpress.isChecked = shouldCheck |
| | | binding.checkBoxFinance.isChecked = shouldCheck |
| | | binding.checkBoxIncome.isChecked = shouldCheck |
| | | binding.checkBoxFlight.isChecked = shouldCheck |
| | | binding.checkBoxTrain.isChecked = shouldCheck |
| | | // binding.checkBoxFlight.isChecked = shouldCheck |
| | | // binding.checkBoxTrain.isChecked = shouldCheck |
| | | } |
| | | |
| | | // 全选提醒方式按钮逻辑 |
| | |
| | | private fun disableVipCategories() { |
| | | binding.apply { |
| | | checkBoxIncome.isEnabled = false |
| | | checkBoxFlight.isEnabled = false |
| | | checkBoxTrain.isEnabled = false |
| | | // checkBoxFlight.isEnabled = false |
| | | // checkBoxTrain.isEnabled = false |
| | | } |
| | | } |
| | | |
| | | private fun enableAllCategories() { |
| | | binding.apply { |
| | | checkBoxIncome.isEnabled = true |
| | | checkBoxFlight.isEnabled = true |
| | | checkBoxTrain.isEnabled = true |
| | | // checkBoxFlight.isEnabled = true |
| | | // checkBoxTrain.isEnabled = true |
| | | } |
| | | } |
| | | |
| | |
| | | checkBoxExpress.isChecked = reminders.any { it.categoryName == "快递" } |
| | | checkBoxFinance.isChecked = reminders.any { it.categoryName == "还款" } |
| | | checkBoxIncome.isChecked = reminders.any { it.categoryName == "收入" } |
| | | checkBoxFlight.isChecked = reminders.any { it.categoryName == "航班" } |
| | | checkBoxTrain.isChecked = reminders.any { it.categoryName == "火车票" } |
| | | // checkBoxFlight.isChecked = reminders.any { it.categoryName == "航班" } |
| | | // checkBoxTrain.isChecked = reminders.any { it.categoryName == "火车票" } |
| | | |
| | | // 检查是否有通知方法设置 |
| | | checkBoxPhone.isChecked = reminders.any { it.notificationMethod == "PHONE" } |
| | |
| | | binding.checkBoxExpress.setOnCheckedChangeListener { _, _ -> } |
| | | binding.checkBoxFinance.setOnCheckedChangeListener { _, _ -> } |
| | | binding.checkBoxIncome.setOnCheckedChangeListener { _, _ -> } |
| | | binding.checkBoxFlight.setOnCheckedChangeListener { _, _ -> } |
| | | binding.checkBoxTrain.setOnCheckedChangeListener { _, _ -> } |
| | | // binding.checkBoxFlight.setOnCheckedChangeListener { _, _ -> } |
| | | // binding.checkBoxTrain.setOnCheckedChangeListener { _, _ -> } |
| | | } |
| | | |
| | | private fun saveSettings() { |
| | |
| | | if (checkBoxExpress.isChecked) selectedCategories.add(CategoryConfig(1, "快递", 1, true)) |
| | | if (checkBoxFinance.isChecked) selectedCategories.add(CategoryConfig(2, "还款", 2, true)) |
| | | if (checkBoxIncome.isChecked) selectedCategories.add(CategoryConfig(3, "收入", 3, true)) |
| | | if (checkBoxFlight.isChecked) selectedCategories.add(CategoryConfig(4, "航班", 4, true)) |
| | | if (checkBoxTrain.isChecked) selectedCategories.add(CategoryConfig(5, "火车票", 5, true)) |
| | | // if (checkBoxFlight.isChecked) selectedCategories.add(CategoryConfig(4, "航班", 4, true)) |
| | | // if (checkBoxTrain.isChecked) selectedCategories.add(CategoryConfig(5, "火车票", 5, true)) |
| | | } |
| | | |
| | | if (selectedCategories.isEmpty()) { |
| | |
| | | stationName.contains("妈妈") -> R.drawable.express_mama |
| | | stationName.contains("小兵") -> R.drawable.express_xiaobing |
| | | stationName.contains("蓝店") -> R.drawable.express_landian |
| | | stationName.contains("丰巢") -> R.drawable.express_fengchao |
| | | else -> R.drawable.express_normal |
| | | } |
| | | |
| | |
| | | companyName.contains("韵达") -> R.drawable.express_package_yunda |
| | | companyName.contains("圆通") -> R.drawable.express_package_yuantong |
| | | companyName.contains("申通") -> R.drawable.express_package_shentong |
| | | companyName.contains("中通") -> R.drawable.express_package_zhongtong |
| | | companyName.contains("邮政") || companyName.contains("ems") -> R.drawable.express_package_youzheng |
| | | companyName.contains("极兔") -> R.drawable.express_package_jitu |
| | | companyName.contains("丰巢") -> R.drawable.express_fengchao |
| | | else -> R.drawable.express_normal |
| | | } |
| | | |
| | |
| | | companyName.contains("韵达") -> R.drawable.express_package_yunda |
| | | companyName.contains("圆通") -> R.drawable.express_package_yuantong |
| | | companyName.contains("申通") -> R.drawable.express_package_shentong |
| | | companyName.contains("中通") -> R.drawable.express_package_zhongtong |
| | | companyName.contains("邮政") || companyName.contains("ems") -> R.drawable.express_package_youzheng |
| | | companyName.contains("极兔") -> R.drawable.express_package_jitu |
| | | companyName.contains("丰巢") -> R.drawable.express_fengchao |
| | | else -> R.drawable.express_normal |
| | | } |
| | | |
| | |
| | | companyName.contains("韵达") -> R.drawable.express_package_yunda |
| | | companyName.contains("圆通") -> R.drawable.express_package_yuantong |
| | | companyName.contains("申通") -> R.drawable.express_package_shentong |
| | | companyName.contains("中通") -> R.drawable.express_package_zhongtong |
| | | companyName.contains("邮政") || companyName.contains("ems") -> R.drawable.express_package_youzheng |
| | | companyName.contains("极兔") -> R.drawable.express_package_jitu |
| | | else -> R.drawable.express_normal |
| | |
| | | import android.view.ViewGroup |
| | | import android.widget.TextView |
| | | import androidx.recyclerview.widget.RecyclerView |
| | | import com.bumptech.glide.Glide |
| | | import com.example.firstapp.R |
| | | import com.example.firstapp.entity.InvitationRecord |
| | | import com.example.firstapp.utils.Log |
| | | import com.google.android.material.imageview.ShapeableImageView |
| | | |
| | | |
| | | class InvitationAdapter( |
| | |
| | | override fun onBindViewHolder(holder: InvitationViewHolder, position: Int) { |
| | | val record = data[position % data.size] // 使用取模实现循环 |
| | | holder.message.text = "${record.userName}邀请好友,${record.reward}" |
| | | // 头像读取 |
| | | // 假设 record.avatarUrl 是网络头像 URL |
| | | Glide.with(holder.itemView.context) |
| | | .load(record.cover) // 网络图片的 URL |
| | | .placeholder(R.drawable.avatar) // 加载中的占位图 |
| | | .circleCrop() // 将图片裁剪成圆形 |
| | | .into(holder.avatar) |
| | | |
| | | } |
| | | |
| | |
| | | |
| | | class InvitationViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { |
| | | val message: TextView = itemView.findViewById(R.id.message) |
| | | val avatar: ShapeableImageView = itemView.findViewById(R.id.invite_success_avatar) |
| | | } |
| | | } |
| | |
| | | WHERE category = :category |
| | | AND code = :code |
| | | AND substr(createTime, 1, 10) = substr(:dateString, 1, 10) |
| | | ANd pickup = '0' |
| | | ORDER BY createTime DESC |
| | | LIMIT 1 |
| | | """) |
| | | fun queryByTypeAndCodeAndDate(category: String, code: String, dateString: String): Code? |
| | |
| | | //通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 |
| | | @ColumnInfo(name = "call_type", defaultValue = "0") var callType: Int = 0, |
| | | @ColumnInfo(name = "time") var time: Date = Date(), |
| | | @ColumnInfo(name = "sms_timestamp", defaultValue = "0") var smsTimestamp: Long = 0, |
| | | ) : Parcelable { |
| | | |
| | | val simImageId: Int |
| | |
| | | |
| | | |
| | | class SmsReceiver : BroadcastReceiver() { |
| | | |
| | | // 添加一个静态同步锁对象 |
| | | companion object { |
| | | private val syncLock = Any() |
| | | } |
| | | // 安全防护关键词数组 |
| | | private var securityKeywordsList = emptyList<String>() |
| | | |
| | |
| | | val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) |
| | | val createtime = sdf.format(date) |
| | | |
| | | // 根据不同类型处理数据 |
| | | when (response.data.category) { |
| | | "快递" -> { |
| | | val code = CodeUtils.createExpressCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | post = response.data.details.post, |
| | | company = response.data.details.company, |
| | | pickupCode = response.data.details.pickupCode, |
| | | address = response.data.details.address, |
| | | time = response.data.details.time |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | // 使用同步块处理保存操作 |
| | | synchronized(syncLock) { |
| | | // 根据不同类型处理数据 |
| | | when (response.data.category) { |
| | | "快递" -> { |
| | | val code = CodeUtils.createExpressCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | post = response.data.details.post, |
| | | company = response.data.details.company, |
| | | pickupCode = response.data.details.pickupCode, |
| | | address = response.data.details.address, |
| | | time = response.data.details.time |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | |
| | | "还款" -> { |
| | | val code = CodeUtils.createRepaymentCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | type = response.data.details.type, |
| | | bank = response.data.details.bank, |
| | | amount = response.data.details.amount, |
| | | date = response.data.details.date, |
| | | address = response.data.details.address, |
| | | minAmount = response.data.details.min_amount, |
| | | number = response.data.details.number |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | "还款" -> { |
| | | val code = CodeUtils.createRepaymentCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | type = response.data.details.type, |
| | | bank = response.data.details.bank, |
| | | amount = response.data.details.amount, |
| | | date = response.data.details.date, |
| | | address = response.data.details.address, |
| | | minAmount = response.data.details.min_amount, |
| | | number = response.data.details.number |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | |
| | | "收入" -> { |
| | | val code = CodeUtils.createIncomeCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | bank = response.data.details.bank, |
| | | amount = response.data.details.amount, |
| | | datetime = response.data.details.datetime, |
| | | address = response.data.details.address, |
| | | balance = response.data.details.balance |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | "收入" -> { |
| | | val code = CodeUtils.createIncomeCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | bank = response.data.details.bank, |
| | | amount = response.data.details.amount, |
| | | datetime = response.data.details.datetime, |
| | | address = response.data.details.address, |
| | | balance = response.data.details.balance |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | |
| | | "航班" -> { |
| | | val code = CodeUtils.createFlightCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | company = response.data.details.company, |
| | | start = response.data.details.start, |
| | | end = response.data.details.end, |
| | | seat = response.data.details.seat, |
| | | time = response.data.details.time, |
| | | address = response.data.details.address |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | "航班" -> { |
| | | val code = CodeUtils.createFlightCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | company = response.data.details.company, |
| | | start = response.data.details.start, |
| | | end = response.data.details.end, |
| | | seat = response.data.details.seat, |
| | | time = response.data.details.time, |
| | | address = response.data.details.address |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | |
| | | "火车票" -> { |
| | | val code = CodeUtils.createTrainTicketCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | company = response.data.details.company, |
| | | seat = response.data.details.seat, |
| | | time = response.data.details.time, |
| | | address = response.data.details.address, |
| | | trips = response.data.details.trips |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | "火车票" -> { |
| | | val code = CodeUtils.createTrainTicketCode( |
| | | msgId = msgId, |
| | | createTime = createtime, |
| | | company = response.data.details.company, |
| | | seat = response.data.details.seat, |
| | | time = response.data.details.time, |
| | | address = response.data.details.address, |
| | | trips = response.data.details.trips |
| | | ) |
| | | CodeUtils.saveCode(code) |
| | | } |
| | | |
| | | else -> {} |
| | | } |
| | | } |
| | | |
| | | // 发送广播通知数据已更新 |
| | | val updateIntent = Intent("com.example.firstapp.DATA_UPDATED") |
| | | context.sendBroadcast(updateIntent) |
| | |
| | | // 其他标签点击事件需要检查会员状态 |
| | | val memberOnlyTabs = mapOf( |
| | | tabIncome to { homeViewModel.loadIncomeData() }, |
| | | tabFlight to { homeViewModel.loadFlightData() }, |
| | | tabTrain to { homeViewModel.loadTrainData() } |
| | | // tabFlight to { homeViewModel.loadFlightData() }, |
| | | // tabTrain to { homeViewModel.loadTrainData() } |
| | | ) |
| | | |
| | | memberOnlyTabs.forEach { (tab, loadAction) -> |
| | |
| | | hideAllRecyclers() |
| | | when (tab) { |
| | | tabIncome -> incomeRecycler.visibility = View.VISIBLE |
| | | tabFlight -> flightRecycler.visibility = View.VISIBLE |
| | | tabTrain -> trainRecycler.visibility = View.VISIBLE |
| | | // tabFlight -> flightRecycler.visibility = View.VISIBLE |
| | | // tabTrain -> trainRecycler.visibility = View.VISIBLE |
| | | } |
| | | updateTabStyles(tab) |
| | | loadAction() |
| | |
| | | |
| | | private fun updateTabStyles(selectedTab: UnderlineTextView) { |
| | | binding.apply { |
| | | val tabs = listOf(tabExpress, tabFinance, tabIncome, tabFlight, tabTrain) |
| | | // val tabs = listOf(tabExpress, tabFinance, tabIncome, tabFlight, tabTrain) |
| | | val tabs = listOf(tabExpress, tabFinance, tabIncome) |
| | | tabs.forEach { tab -> |
| | | // 设置文字颜色为黑色或灰色 |
| | | tab.setTextColor(ContextCompat.getColor(requireContext(), |
| | |
| | | tabExpress.visibility = View.GONE |
| | | tabFinance.visibility = View.GONE |
| | | tabIncome.visibility = View.GONE |
| | | tabFlight.visibility = View.GONE |
| | | tabTrain.visibility = View.GONE |
| | | // tabFlight.visibility = View.GONE |
| | | // tabTrain.visibility = View.GONE |
| | | |
| | | // 获取用户信息判断是否是会员 |
| | | val savedPhone = PreferencesManager.getPhone() |
| | |
| | | tabIncome.visibility = if (category.isEnabled) View.VISIBLE else View.GONE |
| | | if (categories.indexOf(category) == 0 && category.isEnabled) tabIncome.performClick() |
| | | } |
| | | "航班" -> { |
| | | tabFlight.visibility = if (category.isEnabled) View.VISIBLE else View.GONE |
| | | if (categories.indexOf(category) == 0 && category.isEnabled) tabFlight.performClick() |
| | | } |
| | | "火车票" -> { |
| | | tabTrain.visibility = if (category.isEnabled) View.VISIBLE else View.GONE |
| | | if (categories.indexOf(category) == 0 && category.isEnabled) tabTrain.performClick() |
| | | } |
| | | // "航班" -> { |
| | | // tabFlight.visibility = if (category.isEnabled) View.VISIBLE else View.GONE |
| | | // if (categories.indexOf(category) == 0 && category.isEnabled) tabFlight.performClick() |
| | | // } |
| | | // "火车票" -> { |
| | | // tabTrain.visibility = if (category.isEnabled) View.VISIBLE else View.GONE |
| | | // if (categories.indexOf(category) == 0 && category.isEnabled) tabTrain.performClick() |
| | | // } |
| | | } |
| | | } |
| | | } |
| | |
| | | CategoryConfig(1, "快递", 0, true), |
| | | CategoryConfig(2, "还款", 1, true), |
| | | CategoryConfig(3, "收入", 2, true), |
| | | CategoryConfig(4, "航班", 3, true), |
| | | CategoryConfig(5, "火车票", 4, true) |
| | | // CategoryConfig(4, "航班", 3, true), |
| | | // CategoryConfig(5, "火车票", 4, true) |
| | | ) |
| | | } |
| | | |
| | |
| | | private val binding get() = _binding!! |
| | | |
| | | // 默认值 |
| | | private val DEFAULT_XIAOHONGSHU_URL = "https://www.xiaohongshu.com/user/profile/64978d5c000000001001ee26" |
| | | private val DEFAULT_EMAIL = "support@example.com" |
| | | private val DEFAULT_SHARE_TEXT = "推荐一个很棒的应用给你!\n下载地址:https://oia.xiaohongshu.com/oia" |
| | | private val DEFAULT_XIAOHONGSHU_URL = "https://www.xiaohongshu.com/user/profile/5812f5507fc5b818ce813383" |
| | | private val DEFAULT_EMAIL = "yuy@cloudroam.com.cn" |
| | | private val DEFAULT_SHARE_TEXT = "推荐一个很棒的应用给你!\n下载地址:http://14.103.144.28:8888/" |
| | | |
| | | // 存储从接口获取的值 |
| | | private var xiaohongshuUrl = "" |
| | |
| | | binding.btnRenew.setOnClickListener { |
| | | // Toast.makeText(context, "VIP续费功能开发中", Toast.LENGTH_SHORT).show() |
| | | // 跳转到vipActivity |
| | | val intent = Intent(requireContext(), VipActivity::class.java) |
| | | startActivity(intent) |
| | | //2025-04-24 取消续费跳转操作 |
| | | // val intent = Intent(requireContext(), VipActivity::class.java) |
| | | // startActivity(intent) |
| | | Toast.makeText(context, "免费体验,无需续费", Toast.LENGTH_SHORT).show() |
| | | } |
| | | |
| | | binding.cardVip.setOnClickListener { |
| | | // Toast.makeText(context, "VIP续费功能开发中", Toast.LENGTH_SHORT).show() |
| | | // 跳转到vipActivity |
| | | val intent = Intent(requireContext(), VipActivity::class.java) |
| | | startActivity(intent) |
| | | // val intent = Intent(requireContext(), VipActivity::class.java) |
| | | // startActivity(intent) |
| | | Toast.makeText(context, "免费体验,无需续费", Toast.LENGTH_SHORT).show() |
| | | } |
| | | |
| | | // 设置按钮点击 |
| | |
| | | object CodeUtils { |
| | | private const val TAG = "CodeUtils" |
| | | |
| | | private val lock = Any() |
| | | |
| | | /** |
| | | * 保存code到数据库,如果已存在则跳过 |
| | | * @param code 要保存的code对象 |
| | | * @return Boolean 是否成功保存 |
| | | */ |
| | | fun saveCode(code: Code): Boolean { |
| | | // 检查必要字段是否为空 |
| | | if (code.oneLevel.isEmpty() || code.code.isEmpty()) { |
| | | Log.d(TAG, "保存失败:必要字段为空") |
| | | return false |
| | | } |
| | | synchronized(lock) { |
| | | // 检查必要字段是否为空 |
| | | if (code.oneLevel.isEmpty() || code.code.isEmpty()) { |
| | | Log.d(TAG, "保存失败:必要字段为空") |
| | | return false |
| | | } |
| | | |
| | | // 检查是否已存在相同记录 |
| | | val existingCode = Core.code.queryByTypeAndCodeAndDate( |
| | | code.category, |
| | | code.code, |
| | | code.createTime |
| | | ) |
| | | // 检查是否已存在相同记录 |
| | | val existingCode = Core.code.queryByTypeAndCodeAndDate( |
| | | code.category, |
| | | code.code, |
| | | code.createTime |
| | | ) |
| | | |
| | | return if (existingCode == null) { |
| | | try { |
| | | Core.code.insert(code) |
| | | Log.d(TAG, "成功保存${code.category}记录: ${code.code}") |
| | | true |
| | | } catch (e: Exception) { |
| | | Log.e(TAG, "保存${code.category}记录失败: ${e.message}") |
| | | return if (existingCode == null) { |
| | | try { |
| | | Core.code.insert(code) |
| | | Log.d(TAG, "成功保存${code.category}记录: ${code.code}") |
| | | true |
| | | } catch (e: Exception) { |
| | | Log.e(TAG, "保存${code.category}记录失败: ${e.message}") |
| | | false |
| | | } |
| | | } else { |
| | | Log.d(TAG, "发现重复${code.category}记录,跳过保存: ${code.code}") |
| | | false |
| | | } |
| | | } else { |
| | | Log.d(TAG, "发现重复${code.category}记录,跳过保存: ${code.code}") |
| | | false |
| | | } |
| | | } |
| | | |
| | |
| | | remarks = trips ?: "" |
| | | ) |
| | | } |
| | | } |
| | | } |
对比新文件 |
| | |
| | | <vector xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:width="48dp" |
| | | android:height="48dp" |
| | | android:viewportWidth="1024" |
| | | android:viewportHeight="1024"> |
| | | <path |
| | | android:pathData="M308,158.7l-204,353.4 203.9,353.3h408l204,-353.3L715.9,158.7z" |
| | | android:fillColor="#F1C22E"/> |
| | | <path |
| | | android:pathData="M679.6,710.9A259.1,259.1 0,0 1,512 772.2a259.1,259.1 0,0 1,-167.6 -61.3zM748.4,620.6c-9.8,21.2 -22.3,40.9 -37.1,58.6L312.7,679.2a260.1,260.1 0,0 1,-37.1 -58.6zM771.6,527.9c-1.3,21.1 -5,41.6 -11,61L263.4,588.9a259.3,259.3 0,0 1,-11 -61zM760.8,435.9c5.8,19.2 9.6,39.4 10.8,60.3h-243.7v-60.3zM496.2,435.9v60.3L252.4,496.3c1.3,-20.9 4.9,-41.1 10.8,-60.3h233zM496.2,343.9v60.3L275.3,404.3c10,-21.9 22.9,-42.2 38.3,-60.3h182.6zM710.4,343.9c15.4,18.1 28.3,38.4 38.3,60.3h-220.8L527.9,343.9zM496.2,252.5L496.2,312.3L345.4,312.3a258.9,258.9 0,0 1,150.7 -59.8zM527.9,252.5c57.2,3.4 109.4,25.3 150.7,59.8h-150.7z" |
| | | android:fillColor="#231F20"/> |
| | | </vector> |
对比新文件 |
| | |
| | | <vector xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:width="48dp" |
| | | android:height="48dp" |
| | | android:viewportWidth="1024" |
| | | android:viewportHeight="1024"> |
| | | <path |
| | | android:pathData="M0,512a512,512 0,1 0,1024 0,512 512,0 0,0 -1024,0z" |
| | | android:fillColor="#007AFE"/> |
| | | <path |
| | | android:pathData="M762.8,520.1c-20.8,9.2 -43.4,13.8 -66.1,13.6 -23.9,0 -43.5,-4.5 -58.9,-13.5h125zM800.5,496l-0.3,0.3a160.5,160.5 0,0 1,-20.1 14.7L625.2,510.9a74.4,74.4 0,0 1,-12.5 -14.7l187.9,-0.3zM497,496l-7.3,15L400,510.9l7.3,-15h89.7zM707.9,471.8c2.9,0.2 5.6,0.2 8.4,0h107.2c-4.1,5.3 -8.6,10.2 -13.2,15h-203a89.1,89.1 0,0 1,-5.5 -15h106.1zM839.6,447.6c-2.8,5.2 -5.9,10.2 -9.2,14.9h-84.1a54.8,54.8 0,0 0,9.3 -6.9c2.8,-2.5 5.2,-5.2 7.6,-8.1h76.5zM520.3,447.6l-7.2,14.9h-89.6l7.2,-14.9h89.6zM674.9,447.6c0.8,3.1 2,5.9 3.4,8.3a25.7,25.7 0,0 0,5.3 6.7h-83.7a113,113 0,0 1,-1.5 -15h76.5zM851,423.4c-1.9,5.1 -4.1,10.1 -6.6,15h-74.8c3,-4.8 5.7,-9.8 8,-15h73.2zM532.1,423.4l-7.3,15L435.2,438.4l7.3,-15h89.6zM672.6,423.4a87,87 0,0 0,0.5 15h-74.9c0.1,-4.8 0.5,-9.8 1.1,-15h73.3zM859.1,399.2c-1.4,5.1 -3,10.1 -4.7,15h-72.8c1.8,-4.7 3.4,-9.7 4.9,-15h72.6zM676.4,399.2a139.8,139.8 0,0 0,-2.9 15h-72.7c0.8,-4.9 1.8,-9.8 3,-15h72.6,-0.1zM543.7,399.2l-7.2,15L447,414.2l7.3,-15h89.5zM864.5,375a252.6,252.6 0,0 1,-3 15h-72.6a148.5,148.5 0,0 0,2.7 -15h73zM683.7,375a167.4,167.4 0,0 0,-5 15L606.2,390c1.4,-5.1 3,-10.1 4.6,-15h73zM555.5,375l-7.3,15L458.8,390l7.3,-15h89.5zM866.9,350.9c-0.1,5 -0.5,9.9 -1.1,14.9h-73.5c0.1,-5 0,-10 -0.5,-15h75.1zM567.1,350.9l-7.2,14.9L470.5,365.8l7.3,-15h89.4zM696,350.9c-3.1,4.8 -5.9,9.7 -8.3,14.9h-73.4c2,-5.1 4.3,-10.1 6.7,-15h75.1zM865.2,326.6c0.8,4.8 1.3,9.8 1.5,15h-76.4a24.3,24.3 0,0 0,-3.6 -8,33.6 33.6,0 0,0 -6.8,-7h85.3zM578.9,326.6l-7.3,15L482.2,341.6l7.2,-15h89.5,-0.1zM719.7,326.6a51.3,51.3 0,0 0,-10.1 7.9c-2.4,2.3 -4.6,4.6 -6.7,7.1h-77.1c2.9,-5.2 5.9,-10.2 9.2,-15h84.6zM857.4,302.4c2.3,4.7 4.1,9.7 5.6,15L404,317.4l7.3,-15h446.2zM677,278.3l-4.4,8.9c4.3,-3.2 8.7,-6.1 13.2,-8.9h153.4c5,4.3 9.3,9.3 13,15L415.7,293.3l7.3,-15h254.1v-0.1zM403.8,317.9L254.8,471.9h164.1l89.8,-0.2 -7.3,15h-89.6l-16.2,33.4h89.7l-6.6,13.5L135,533.7l29.8,-61.7L314.2,318L210.1,318L239.5,256h448.2l-6.3,13L427.4,269l-23.6,48.9v0.1zM768.2,256c23.5,0 42.8,4.4 58.1,13h-122.9c20.5,-8.8 42.5,-13.2 64.9,-13L768.2,256zM673.5,605.2l-7.3,29.6h9.8c30.1,0 30.2,3.8 24.7,26.1l-6.6,26.5h9.5l-4.6,18.6h-39.7c4,12 12.6,29.2 28.9,48.1 -5.4,21.2 -5.6,22 -6.2,24.2 -21.6,-18.8 -31,-37.1 -42.2,-57 -14.2,29.2 -29.2,53.2 -64.8,56.8l2.2,-9.2c15.4,-12.1 29.5,-27.4 43.6,-62.9h-28.4l4.6,-18.6h29.2l8.3,-33.9h-29.7l4.5,-18.8 29.7,0.2 7.3,-29.5h27.2zM602.2,606l-10.8,43.5 4.9,-2.9s5.4,11.3 8,16.3c7,13.8 -4.5,20.7 -4.5,20.7l-11.3,6.5 -4.4,-10.8 -22.4,92 -0.7,3.1 -1,3.9h-25.1l42.1,-172.3h25.1zM258.5,605.8l-7.5,28.8h48.1c24.9,0 16.3,18.1 16.3,18.1l-12.5,48.1 -8.8,33.8L266.2,734.7l3.3,-13 0.4,-1.2 0.1,-0.3h-41.2l-14.8,57.4L186.4,777.7l14.8,-57.4h-41.5c-0.1,1 -0.9,2.8 -3.7,14.4L128,734.7l25.9,-99.9h69.5l7.4,-28.8h27.6zM372.6,673.9l-17.3,66.4c4.4,9.8 14.1,14.6 31.8,14.6l39.5,0.6h7.3c19.1,-0.2 48.9,-0.7 48.9,-0.7l-5.9,22.7 -97.8,-0.7a64.4,64.4 0,0 1,-25.5 -4.9,32.4 32.4,0 0,1 -14.2,-12.4l-28.7,17.9 7.1,-27.3 10.2,-10.3 15.4,-59.5h-7.5l6,-23.2h17.2s18.2,-1.8 13.4,16.9zM759.4,673.9l-17.3,66.4c4.5,9.8 14.2,14.6 31.9,14.6l39.5,0.6h7.4l12.4,-0.2 8.7,-0.1 27.8,-0.4 -5.8,22.7 -97.8,-0.7a64.8,64.8 0,0 1,-25.6 -4.9,32.4 32.4,0 0,1 -14.2,-12.4l-28.6,17.9 7.1,-27.3 10.1,-10.3 15.4,-59.5h-7.5l6.1,-23.2h17s18.2,-1.8 13.4,16.9zM521.4,606.2l-5.2,20.2 -41.6,20.3h20.6c17.5,0 11.6,16.4 11.6,16.4l-17.4,67.1c-5,19.6 -19.8,17.3 -19.8,17.3h-17.2l4.2,-16.3h5.1l4.1,-16.1h-18.2l-8.9,34.2h-27.3l8.9,-34.2h-19.6l-8.3,31.9h-27.2l25.9,-100.2h39.1l-18.9,-11.8 11.6,-10.4h-26l4.7,-18.4h119.8v0.1zM827.7,605.6l8.7,15.2h11l14.1,-15.3h25.6l-13.5,15.3h9.8s16,-1.9 11.9,14l-9.5,36.7h-44.2l-3.5,13.4h28.6s15.7,-0.2 11.4,16.2c-2.4,9.1 -5,19.6 -7.3,28.2 -4.3,16.6 -15.6,17.9 -17.4,18h-22.7l4.2,-16.3h7.9l7.2,-27.4h-16.8l-11.8,45.5h-27.3l7.3,-27.8 -49.2,24.5 5,-19.3 48.8,-22.8h-42.8l13.1,-50.7h42.8l3.5,-13.4h-42.8l4.8,-18.7h22.8l-8.4,-15.3h28.6zM559.9,644.6l-19.6,81.2h-24.9l20,-81.2h24.5zM472.7,688.7h-18.2l-2.8,10.8h18.3l2.8,-10.8zM427.1,688.7L407.6,688.7l-2.8,10.8h19.5l2.8,-10.8zM286.3,657.2h-41.2l-10.3,39.9h41.1l10.4,-39.9zM217.6,657.2h-41.6l-10.3,39.9h41.5l10.4,-39.9h0.1zM662,653.4l-8.5,34h16.6l8.2,-33.9h-16.3v-0.1zM814.3,671.6h-15.4l-3.6,13.4h15.5l3.5,-13.4zM433.9,662.4h-19.6l-2.8,10.8h19.6l2.8,-10.8zM479.5,662.4h-18.3l-2.8,10.8h18.3l2.8,-10.8zM866.7,639.5h-16.7l-3.6,13.4h16.9l3.5,-13.4zM759.8,606s5.5,11.2 8,16.2c7,13.8 -4.5,20.7 -4.5,20.7l-11.4,6.5 -13,-31.7 20.8,-11.8zM373,606s5.4,11.2 8,16.2c7,13.8 -4.5,20.7 -4.5,20.7l-11.3,6.5 -13,-31.7 20.8,-11.8zM486.4,624.4L429.4,624.4l24.8,15.8 32.3,-15.8z" |
| | | android:fillColor="#FFFFFF"/> |
| | | </vector> |
| | |
| | | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="60dp" |
| | | xmlns:app="http://schemas.android.com/apk/res-auto" |
| | | android:minHeight="60dp" |
| | | android:gravity="center_vertical" |
| | | android:orientation="horizontal" |
| | | android:padding="8dp"> |
| | | |
| | | <de.hdodenhof.circleimageview.CircleImageView |
| | | android:id="@+id/avatar" |
| | | android:layout_width="40dp" |
| | | android:layout_height="40dp" |
| | | <!-- <de.hdodenhof.circleimageview.CircleImageView--> |
| | | <!-- android:id="@+id/invite_success_avatar"--> |
| | | <!-- android:layout_width="40dp"--> |
| | | <!-- android:layout_height="40dp"--> |
| | | <!-- android:src="@drawable/avatar"--> |
| | | <!-- android:paddingLeft="10dp" />--> |
| | | |
| | | <com.google.android.material.imageview.ShapeableImageView |
| | | android:id="@+id/invite_success_avatar" |
| | | android:layout_width="30dp" |
| | | android:layout_height="30dp" |
| | | android:layout_marginLeft="10dp" |
| | | android:scaleType="centerCrop" |
| | | android:src="@drawable/avatar" |
| | | android:paddingLeft="10dp" /> |
| | | app:shapeAppearance="@style/CircleImage" |
| | | /> |
| | | |
| | | <TextView |
| | | android:id="@+id/message" |
| | |
| | | |
| | | </LinearLayout> |
| | | |
| | | <LinearLayout |
| | | android:layout_width="0dp" |
| | | android:layout_height="wrap_content" |
| | | android:layout_weight="1" |
| | | android:orientation="horizontal"> |
| | | <!-- <LinearLayout--> |
| | | <!-- android:layout_width="0dp"--> |
| | | <!-- android:layout_height="wrap_content"--> |
| | | <!-- android:layout_weight="1"--> |
| | | <!-- android:orientation="horizontal">--> |
| | | |
| | | <CheckBox |
| | | android:id="@+id/checkBoxFlight" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" /> |
| | | <!-- <CheckBox--> |
| | | <!-- android:id="@+id/checkBoxFlight"--> |
| | | <!-- android:layout_width="wrap_content"--> |
| | | <!-- android:layout_height="wrap_content" />--> |
| | | |
| | | <TextView |
| | | android:layout_width="0dp" |
| | | android:layout_height="wrap_content" |
| | | android:layout_weight="1" |
| | | android:text="航班" |
| | | android:textColor="#000000" |
| | | android:textSize="14sp" /> |
| | | <!-- <TextView--> |
| | | <!-- android:layout_width="0dp"--> |
| | | <!-- android:layout_height="wrap_content"--> |
| | | <!-- android:layout_weight="1"--> |
| | | <!-- android:text="航班"--> |
| | | <!-- android:textColor="#000000"--> |
| | | <!-- android:textSize="14sp" />--> |
| | | |
| | | |
| | | </LinearLayout> |
| | | <!-- </LinearLayout>--> |
| | | </LinearLayout> |
| | | |
| | | <!-- 第二行1个 --> |
| | | <LinearLayout |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginTop="8dp" |
| | | android:orientation="horizontal"> |
| | | <!-- <LinearLayout--> |
| | | <!-- android:layout_width="match_parent"--> |
| | | <!-- android:layout_height="wrap_content"--> |
| | | <!-- android:layout_marginTop="8dp"--> |
| | | <!-- android:orientation="horizontal">--> |
| | | |
| | | <LinearLayout |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:orientation="horizontal"> |
| | | <!-- <LinearLayout--> |
| | | <!-- android:layout_width="wrap_content"--> |
| | | <!-- android:layout_height="wrap_content"--> |
| | | <!-- android:orientation="horizontal">--> |
| | | |
| | | <CheckBox |
| | | android:id="@+id/checkBoxTrain" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" /> |
| | | <!-- <CheckBox--> |
| | | <!-- android:id="@+id/checkBoxTrain"--> |
| | | <!-- android:layout_width="wrap_content"--> |
| | | <!-- android:layout_height="wrap_content" />--> |
| | | |
| | | <TextView |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:text="火车票" |
| | | android:textColor="#000000" |
| | | android:textSize="14sp" /> |
| | | <!-- <TextView--> |
| | | <!-- android:layout_width="wrap_content"--> |
| | | <!-- android:layout_height="wrap_content"--> |
| | | <!-- android:text="火车票"--> |
| | | <!-- android:textColor="#000000"--> |
| | | <!-- android:textSize="14sp" />--> |
| | | |
| | | |
| | | </LinearLayout> |
| | | </LinearLayout> |
| | | <!-- </LinearLayout>--> |
| | | <!-- </LinearLayout>--> |
| | | |
| | | <!-- 选择提醒方式部分 --> |
| | | <LinearLayout |
| | |
| | | android:singleLine="true" |
| | | android:ellipsize="end" /> |
| | | |
| | | <com.example.firstapp.view.UnderlineTextView |
| | | android:id="@+id/tabFlight" |
| | | android:layout_width="0dp" |
| | | android:layout_height="match_parent" |
| | | android:layout_weight="1" |
| | | android:gravity="center" |
| | | android:padding="4dp" |
| | | android:text="航班" |
| | | android:textSize="14sp" |
| | | android:singleLine="true" |
| | | android:ellipsize="end" /> |
| | | <!-- <com.example.firstapp.view.UnderlineTextView--> |
| | | <!-- android:id="@+id/tabFlight"--> |
| | | <!-- android:layout_width="0dp"--> |
| | | <!-- android:layout_height="match_parent"--> |
| | | <!-- android:layout_weight="1"--> |
| | | <!-- android:gravity="center"--> |
| | | <!-- android:padding="4dp"--> |
| | | <!-- android:text="航班"--> |
| | | <!-- android:textSize="14sp"--> |
| | | <!-- android:singleLine="true"--> |
| | | <!-- android:ellipsize="end" />--> |
| | | |
| | | <com.example.firstapp.view.UnderlineTextView |
| | | android:id="@+id/tabTrain" |
| | | android:layout_width="0dp" |
| | | android:layout_height="match_parent" |
| | | android:layout_weight="1" |
| | | android:gravity="center" |
| | | android:padding="4dp" |
| | | android:text="火车票" |
| | | android:textSize="14sp" |
| | | android:singleLine="true" |
| | | android:ellipsize="end" /> |
| | | <!-- <com.example.firstapp.view.UnderlineTextView--> |
| | | <!-- android:id="@+id/tabTrain"--> |
| | | <!-- android:layout_width="0dp"--> |
| | | <!-- android:layout_height="match_parent"--> |
| | | <!-- android:layout_weight="1"--> |
| | | <!-- android:gravity="center"--> |
| | | <!-- android:padding="4dp"--> |
| | | <!-- android:text="火车票"--> |
| | | <!-- android:textSize="14sp"--> |
| | | <!-- android:singleLine="true"--> |
| | | <!-- android:ellipsize="end" />--> |
| | | </LinearLayout> |
| | | |
| | | <!-- 右侧图标区域 --> |