diff --git a/app/src/main/java/com/shuwei/dish/match/base/BaseActivity.kt b/app/src/main/java/com/shuwei/dish/match/base/BaseActivity.kt index 25f23a5..c57d5f0 100644 --- a/app/src/main/java/com/shuwei/dish/match/base/BaseActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/base/BaseActivity.kt @@ -35,18 +35,8 @@ import kotlin.getValue open class BaseActivity : AppCompatActivity() { private lateinit var binding: ActivityBaseBinding - private var launcher: ActivityResultLauncher? = null - private var launchCallback: ((Intent?) -> Unit)? = null - public fun launch(cls: Class<*>, launchCallback: (Intent?) -> Unit) { - this.launchCallback = launchCallback - launcher?.launch(Intent(this, cls)) - } - public fun launch(intent: Intent, launchCallback: (Intent?) -> Unit) { - this.launchCallback = launchCallback - launcher?.launch(intent) - } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -57,12 +47,6 @@ open class BaseActivity : AppCompatActivity() { } setContentView(binding.root) statusBarDarkFont(enable = false) - launcher = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == RESULT_OK) { - launchCallback?.invoke(result.data) - } - } // window.setDecorFitsSystemWindows(false) // 启用 Edge-to-Edge // window.insetsController?.apply { @@ -95,8 +79,7 @@ open class BaseActivity : AppCompatActivity() { fun statusBarDarkFont(enable: Boolean) { //window.decorView.systemUiVisibility = if (enable) View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR else 0 val color = ContextCompat.getColor( - this, - if (enable) R.color.black else R.color.white + this, if (enable) R.color.black else R.color.white ) binding.tvLeftTime.setTextColor(color) binding.tvRightTime.setTextColor(color) @@ -161,8 +144,11 @@ open class BaseActivity : AppCompatActivity() { handler.removeCallbacks(updateTask) } - fun showLoading() { - Loading.show(this) + fun showLoading(msg: String = "加载中……") { + Loading.show( + context = this, + message = msg + ) } fun dismissLoading() { @@ -193,4 +179,52 @@ open class BaseActivity : AppCompatActivity() { netViewModel.querySeasoningList(param, onSuccess, onFailure) } + + private var permissionCallback: ((isGranted: Boolean) -> Unit)? = null + private var activityCallback: ((intent: Intent?) -> Unit)? = null + + fun requestMultiplePermissions( + permissions: Array, + callback: (isGranted: Boolean) -> Unit + ) { + this.permissionCallback = callback + requestMultiplePermissionsLauncher.launch(permissions) + } + + fun requestPermission(permission: String, callback: (isGranted: Boolean) -> Unit) { + this.permissionCallback = callback + requestPermissionLauncher.launch(permission) + } + + val requestMultiplePermissionsLauncher = registerForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) { permissions -> + var isGranted = true + permissions.entries.forEach { + if (!it.value) { + isGranted = false + } + } + permissionCallback?.invoke(isGranted) + } + + // 权限请求回调 + val requestPermissionLauncher = registerForActivityResult( + ActivityResultContracts.RequestPermission() + ) { isGranted -> + permissionCallback?.invoke(isGranted) + } + + fun startActivity(intent: Intent, callback: (Intent?) -> Unit) { + this.activityCallback = callback + startActivityLauncher.launch(intent) + } + + // activity页面返回的回调 + private val startActivityLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + activityCallback?.invoke(it.data) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/shuwei/dish/match/dialog/LoadingDialog.kt b/app/src/main/java/com/shuwei/dish/match/dialog/LoadingDialog.kt index 99ccb78..d004dcb 100644 --- a/app/src/main/java/com/shuwei/dish/match/dialog/LoadingDialog.kt +++ b/app/src/main/java/com/shuwei/dish/match/dialog/LoadingDialog.kt @@ -13,14 +13,22 @@ object Loading { private var dialog: LoadingDialog? = null - fun show(context: Context) { + fun isShowing(): Boolean { + return dialog != null && dialog!!.isShowing + } + + fun updateContent(content: String) { + if (isShowing().not()) return + dialog!!.updateContent(content) + } + + fun show(context: Context, message: String = "加载中……", onDismiss: () -> Unit = {}) { try { if (dialog?.isShowing == true) { dialog?.dismiss() } - if (dialog == null) { - dialog = LoadingDialog(context) + dialog = LoadingDialog(context = context, message = message, onDismiss = onDismiss) } dialog?.show() } catch (e: Exception) { @@ -45,11 +53,14 @@ object Loading { class LoadingDialog( context: Context, - message: String = "加载中……", - private var onDismiss: () -> Unit = {} + message: String, + private var onDismiss: () -> Unit ) : Dialog(context, R.style.LoadingDialog) { + private val binding: DialogLoadingBinding by lazy { + DialogLoadingBinding.inflate(LayoutInflater.from(context)) + } + init { - val binding = DialogLoadingBinding.inflate(LayoutInflater.from(context)) binding.tvMessage.text = message setContentView(binding.root) setCancelable(true) @@ -64,6 +75,10 @@ class LoadingDialog( onDismiss() } } + + fun updateContent(content: String) { + binding.tvMessage.text = content + } } //class LoadingDialog3( diff --git a/app/src/main/java/com/shuwei/dish/match/net/ApiRequest.kt b/app/src/main/java/com/shuwei/dish/match/net/ApiRequest.kt index c3a205c..09bf890 100644 --- a/app/src/main/java/com/shuwei/dish/match/net/ApiRequest.kt +++ b/app/src/main/java/com/shuwei/dish/match/net/ApiRequest.kt @@ -1,5 +1,6 @@ package com.shuwei.dish.match.net +import com.google.gson.JsonSyntaxException import com.shuwei.dish.match.utils.ext.toJsonString import com.shuwei.dish.match.utils.ext.toObject import com.shuwei.dish.match.utils.ext.toType @@ -60,10 +61,10 @@ suspend fun request( onFailure("-1", apiException.errorMsg) return } - if (response?.isSuccess() == true) { + if (response.isSuccess()) { onSuccess(response.data as T) } else { - onFailure(response?.code ?: "-1", response?.msg ?: "") + onFailure(response.code, response.msg ?: "") } } @@ -77,6 +78,11 @@ fun getApiException(e: Exception): ApiException { return when (e) { is HttpException -> httpException2ApiException(e) + is JsonSyntaxException -> ApiException( + ErrorType.NETWORK_ERROR, + errorMsg = "服务器响应异常,请稍后重试" + ) + is UnknownHostException -> ApiException( ErrorType.NETWORK_ERROR, errorMsg = "网络未连接,请检查网络" @@ -108,10 +114,15 @@ fun getApiException(e: Exception): ApiException { fun httpException2ApiException(e: HttpException): ApiException { val body = e.response()?.errorBody()?.string() - val codeMsg: CodeMsg? = body?.toObject() + val codeMsg: CodeMsg? = try { + body?.toObject() + } catch (ex: Exception) { + null + } return ApiException( ErrorType.NETWORK_ERROR, - errorMsg = codeMsg?.msg ?: "" + errorMsg = if (codeMsg == null) "数据解析异常(${e.code()})" + else codeMsg.msg ?: "服务器错误(${e.code()})" ) } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt index 8be4951..ad555c1 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/DishSamplingActivity.kt @@ -238,8 +238,8 @@ class DishSamplingActivity : BaseActivity() { } val food = FoodRecord() binding.etInputDish.let { - if (it.tag!=null && it.tag.toString() == it.text.toString()) { - food.foodId = foodId + if (it.tag != null && it.tag.toString() == it.text.toString()) { + food.foodId = foodId } } food.foodName = showFoodName @@ -259,17 +259,16 @@ class DishSamplingActivity : BaseActivity() { } private fun jumpSearch(v: View) { - launch(Intent(this, FoodSearchActivity::class.java).apply { + val intent = Intent(this, FoodSearchActivity::class.java).apply { putExtra(FoodSearchActivity.FOOD_NAME, binding.etInputDish.text.toString().trim()) - }) { intent -> - intent?.let { - foodId = it.getStringExtra(FoodSearchActivity.FOOD_ID) - foodName = it.getStringExtra(FoodSearchActivity.FOOD_NAME) - binding.etInputDish.run { - setText(foodName) - tag = foodName - setSelection(text.length) - } + } + startActivity(intent) { + foodId = it?.getStringExtra(FoodSearchActivity.FOOD_ID) + foodName = it?.getStringExtra(FoodSearchActivity.FOOD_NAME) + binding.etInputDish.run { + setText(foodName) + tag = foodName + setSelection(text.length) } } KeyboardUtil.hideKeyboard(v.context, v) diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt index 79a81a7..ccd073b 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt @@ -1,12 +1,12 @@ package com.shuwei.dish.match.ui import android.Manifest +import android.annotation.SuppressLint import android.content.pm.PackageManager import android.net.Uri import android.os.Build import android.os.Bundle import android.view.ViewGroup -import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import androidx.core.graphics.toColorInt import androidx.fragment.app.Fragment @@ -23,7 +23,6 @@ import com.shuwei.dish.match.utils.ext.dp import com.shuwei.dish.match.utils.ext.gone import com.shuwei.dish.match.utils.ext.toast import com.shuwei.dish.match.utils.ext.visible -import kotlin.text.replace /** * 设置Activity @@ -41,18 +40,6 @@ class SettingActivity : BaseActivity() { } private lateinit var previewView: PreviewView - // 权限申请 - private val requestPermissionLauncher = - registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> - if (isGranted) { - // 权限已授予,显示 CollectFragment - showFragment(fragmentList[1]) - } else { - // 权限被拒绝 - toast("暂无相机权限,无法使用菜品采集功能") - } - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivitySettingBinding.inflate(layoutInflater) @@ -138,22 +125,31 @@ class SettingActivity : BaseActivity() { /** * 检查相机权限并显示 CollectFragment */ + @SuppressLint("ObsoleteSdkInt") private fun checkCameraPermissionAndShowFragment() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (ContextCompat.checkSelfPermission( - this, - Manifest.permission.CAMERA - ) == PackageManager.PERMISSION_GRANTED - ) { - // 权限已授予,直接显示 Fragment - showFragment(fragmentList[1]) - } else { - // 权限未授予,申请权限 - requestPermissionLauncher.launch(Manifest.permission.CAMERA) - } - } else { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // Android 6.0 以下,直接显示 Fragment showFragment(fragmentList[1]) + return + } + if (ContextCompat.checkSelfPermission( + this, + Manifest.permission.CAMERA + ) == PackageManager.PERMISSION_GRANTED + ) { + // 权限已授予,直接显示 Fragment + showFragment(fragmentList[1]) + } else { + // 权限未授予,申请权限 + requestPermission(Manifest.permission.CAMERA) { isGranted -> + if (isGranted) { + // 权限已授予,显示 CollectFragment + showFragment(fragmentList[1]) + } else { + // 权限被拒绝 + toast("暂无相机权限,无法使用菜品采集功能") + } + } } } diff --git a/app/src/main/java/com/shuwei/dish/match/ui/fragment/CollectFragment.kt b/app/src/main/java/com/shuwei/dish/match/ui/fragment/CollectFragment.kt index 803b40d..2bc5621 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/fragment/CollectFragment.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/fragment/CollectFragment.kt @@ -2,9 +2,9 @@ package com.shuwei.dish.match.ui.fragment import android.annotation.SuppressLint import android.content.Context -import android.content.Intent import android.graphics.Bitmap import android.net.Uri +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -15,19 +15,16 @@ import com.shuwei.dish.match.R import com.shuwei.dish.match.adapter.FoodCollectionAdapter import com.shuwei.dish.match.base.BaseFragment import com.shuwei.dish.match.databinding.FragmentCollectBinding +import com.shuwei.dish.match.dialog.Loading import com.shuwei.dish.match.objbox.FoodCollectionBean import com.shuwei.dish.match.objbox.FoodModule -import com.shuwei.dish.match.objbox.ObjectBox import com.shuwei.dish.match.ui.SettingActivity import com.shuwei.dish.match.utils.BitmapSaver import com.shuwei.dish.match.utils.Debouncer import com.shuwei.dish.match.utils.ImageUtil +import com.shuwei.dish.match.utils.LogSaveUtil import com.shuwei.dish.match.utils.ext.clickWithDebounce import com.shuwei.dish.match.utils.ext.toast -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody @SuppressLint("NotifyDataSetChanged") class CollectFragment : BaseFragment() { @@ -46,7 +43,7 @@ class CollectFragment : BaseFragment() { } } -// private val searchFoodList = mutableListOf() + // private val searchFoodList = mutableListOf() // private var settingActivity: SettingActivity? = null // private var checkedItem: FoodInfo? = null // private val searchFoodAdapter by lazy { @@ -96,7 +93,7 @@ class CollectFragment : BaseFragment() { if (index == -1) { toast("每次只允许保存${MAX_COUNT}条数据") hideWaitingDialog() - rerurn@cameraCallback + rerurn@ cameraCallback } activity?.runOnUiThread { foodCollectionList[index].let { @@ -268,7 +265,7 @@ class CollectFragment : BaseFragment() { // //} // runBlocking { // activity?.runOnUiThread { -// showWaitingDialog2("图片上传中$count/$totalFileCount") +// showWaitingDialog("图片上传中$count/$totalFileCount") // } // val foodList = batch.mapIndexed { index, it -> // Food( @@ -351,9 +348,21 @@ class CollectFragment : BaseFragment() { binding.llCameraFlag.visibility = View.VISIBLE } - private fun log(msg: String) {} - private fun searchByFoodName(name: String, block:(String)-> Unit) {} - private fun hideWaitingDialog() {} - private fun showWaitingDialog(msg: String) {} - private fun showWaitingDialog2(msg: String) {} + private fun log(msg: String) { + Log.d(TAG, "log: $msg") + LogSaveUtil.saveLogFile(msg) + } + + private fun searchByFoodName(name: String, block: (String) -> Unit) {} + private fun hideWaitingDialog() { + settingActivity.dismissLoading() + } + + private fun showWaitingDialog(msg: String) { + if (Loading.isShowing()) { + Loading.updateContent(msg) + return + } + settingActivity.showLoading(msg) + } } \ No newline at end of file