diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index b268ef3..00284f6 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,6 +4,14 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index e236b7d..7e8cd7e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ef303cd..fdda7e7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -95,4 +95,7 @@ dependencies { // implementation(libs.adapter.coroutines) implementation("androidx.work:work-runtime-ktx:2.8.1") + + implementation(libs.core) + implementation(libs.android.core) } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b1b297d..d9c064b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -21,11 +21,13 @@ android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" - android:icon="@mipmap/ic_launcher512" + android:icon="@mipmap/ic_logo512" android:label="@string/app_name" - android:roundIcon="@mipmap/ic_launcher512" + android:roundIcon="@mipmap/ic_logo512" android:supportsRtl="true" android:theme="@style/Theme.SmartPlateCabinet" + android:networkSecurityConfig="@xml/network_security_config" + android:usesCleartextTraffic="true" tools:targetApi="31"> + android:launchMode="singleTask"/> + diff --git a/app/src/main/java/com/sw/platecabinet/GlobalData.kt b/app/src/main/java/com/sw/platecabinet/GlobalData.kt index f26018b..cb1b81f 100644 --- a/app/src/main/java/com/sw/platecabinet/GlobalData.kt +++ b/app/src/main/java/com/sw/platecabinet/GlobalData.kt @@ -29,6 +29,17 @@ object GlobalData { var appId = "Hkz1rBk6PZXbS8KwKr67K2eZtsz8bRoMHLg64bUdgCZj" var sdkKey = "AabXs3sHM8UhhE7oCGf4LVMLrdkGb1nJNksbjjTdVt7k" var activeKey = "085F-118G-Q391-53YL" + + /** + * 具体业务baseurl + */ + var appBaseUrl: String = "" + + /** + * 设备id + */ + var deviceId: String = "" + var restId: String = "" } /** @@ -45,6 +56,7 @@ object Constants { * key */ object GlobalKey { + const val KEY_EQUIPMENT_INFO = "equipmentInfo" const val KEY_TOKEN = "tokenKey" const val KEY_FIRST_RUN = "firstRun" const val KEY_USER_INFO = "userInfoKey" diff --git a/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt new file mode 100644 index 0000000..e7e9575 --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt @@ -0,0 +1,72 @@ +package com.sw.platecabinet.activity + +import android.content.Intent +import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope +import com.sw.plate.utils.AppUtil +import com.sw.platecabinet.GlobalData +import com.sw.platecabinet.databinding.ActivityDeviceInitBinding +import com.sw.platecabinet.databinding.ItemTitleTimeBinding +import com.sw.platecabinet.utils.QRCodeUtil +import com.sw.platecabinet.viewmodel.DeviceViewModel +import kotlinx.coroutines.launch +import timber.log.Timber +import kotlin.getValue + +/** + * 设备初始化界面 + */ +class DeviceInitActivity : BaseActivity() { + + private val deviceViewModel by viewModels() + + override fun inflateViewBinding(): ActivityDeviceInitBinding { + return ActivityDeviceInitBinding.inflate(layoutInflater) + } + + override fun inflateTitleBinding(): ItemTitleTimeBinding? { + return null + } + + override fun initialize() { + var deviceId = AppUtil.getUDID(this) + deviceId = "6ce7cd59-b875-38b2-b73d-88a570be3212" + GlobalData.deviceId = deviceId + val isSuccess = deviceViewModel.checkEquipmentInfo() + if (isSuccess) { + goLoginActivity() + return + } + binding.ivQrCode.setImageBitmap( + QRCodeUtil.generateQRCode( + content = GlobalData.deviceId, + size = 200 + ) + ) + binding.btnInit.setOnClickListener { + deviceViewModel.getDeviceToken() + } + } + + override fun registerDataChange() { + super.registerDataChange() + lifecycleScope.launch { + deviceViewModel.deviceInfoResult.collect { it -> + if (it == true) { + goLoginActivity() + } + } + } + } + + private fun goLoginActivity() { + val intent = Intent(this, LoginByFaceActivity::class.java) + startActivity(intent) + finish() + } + + override fun onLeftDoubleClick() { + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/model/response/ApiResponse.kt b/app/src/main/java/com/sw/platecabinet/model/response/ApiResponse.kt index 3258796..113835a 100644 --- a/app/src/main/java/com/sw/platecabinet/model/response/ApiResponse.kt +++ b/app/src/main/java/com/sw/platecabinet/model/response/ApiResponse.kt @@ -4,7 +4,8 @@ data class ApiResponse( val code: Int, val success: Boolean? = false, val msg: String? = "", - val data: T? = null + val data: T? = null, + val result: T? = null, ) { fun isSuccess(): Boolean = code == 200 } diff --git a/app/src/main/java/com/sw/platecabinet/model/response/EquipmentInfo.kt b/app/src/main/java/com/sw/platecabinet/model/response/EquipmentInfo.kt new file mode 100644 index 0000000..4d85533 --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/model/response/EquipmentInfo.kt @@ -0,0 +1,72 @@ +package com.sw.platecabinet.model.response + + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import kotlinx.parcelize.Parcelize + +@Parcelize +data class EquipmentInfo( + @SerializedName("appPackageLocalUrl") + val appPackageLocalUrl: String? = "", + @SerializedName("appPackageUrl") + val appPackageUrl: String? = "", + @SerializedName("arcsoftActiveKey") + val arcsoftActiveKey: String? = "", + @SerializedName("arcsoftAppId") + val arcsoftAppId: String? = "", + @SerializedName("arcsoftSdkKey") + val arcsoftSdkKey: String? = "", + @SerializedName("arrayCross") + val arrayCross: Int? = 0, + @SerializedName("arrayMode") + val arrayMode: String? = "", + @SerializedName("arrayVertical") + val arrayVertical: Int? = 0, + @SerializedName("canteenId") + val canteenId: String? = "", + @SerializedName("canteenName") + val canteenName: String? = "", + @SerializedName("clientServerIp") + val clientServerIp: String? = "", + @SerializedName("createBy") + val createBy: String? = "", + @SerializedName("createTime") + val createTime: String? = "", + @SerializedName("customerName") + val customerName: String? = "", + @SerializedName("equipmentCode") + val equipmentCode: String? = "", + @SerializedName("equipmentName") + val equipmentName: String? = "", + @SerializedName("equipmentName_dictText") + val equipmentNameDictText: String? = "", + @SerializedName("id") + val id: String? = "", + @SerializedName("isSync") + val isSync: Int? = 0, + @SerializedName("mqName") + val mqName: String? = "", + @SerializedName("mqPassword") + val mqPassword: String? = "", + @SerializedName("orgCode") + val orgCode: String? = "", + @SerializedName("owningTrack") + val owningTrack: Int? = 0, + @SerializedName("owningTrackOrder") + val owningTrackOrder: Int? = 0, + @SerializedName("screenHtml") + val screenHtml: String? = "", + @SerializedName("serviceRequestAddress") + val serviceRequestAddress: String? = "", + @SerializedName("status") + val status: Int? = 0, + @SerializedName("sysOrgCode") + val sysOrgCode: String? = "", + @SerializedName("updateBy") + val updateBy: String? = "", + @SerializedName("updateTime") + val updateTime: String? = "", + @SerializedName("zhstServerIp") + val zhstServerIp: String? = "" +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt b/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt index 9785b37..34dc5e1 100644 --- a/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt +++ b/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt @@ -12,6 +12,7 @@ import java.util.concurrent.TimeUnit object ApiClient { private const val BASE_URL = "https://vip.shuziweidao.com" + private const val DEVICE_BASE_URL = "http://device.shuziweidao.com:8889/" // private const val BASE_URL = "http://192.168.1.8:9092" private const val TIME_OUT = 30L // 超时时间(秒) @@ -33,7 +34,7 @@ object ApiClient { .build() private val retrofit = Retrofit.Builder() - .baseUrl(BASE_URL) + .baseUrl(DEVICE_BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) // .addCallAdapterFactory(CoroutineCallAdapterFactory()) // 协程适配器 diff --git a/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt b/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt index 37e9beb..bd58353 100644 --- a/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt +++ b/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt @@ -1,25 +1,48 @@ package com.sw.platecabinet.network.api +import com.sw.platecabinet.GlobalData import com.sw.platecabinet.model.request.BindParam import com.sw.platecabinet.model.request.EquipmentParam import com.sw.platecabinet.model.request.LoginParam import com.sw.platecabinet.model.request.SearchParam import com.sw.platecabinet.model.response.ApiResponse +import com.sw.platecabinet.model.response.EquipmentInfo import com.sw.platecabinet.model.response.EquipmentUserInfo import com.sw.platecabinet.model.response.SearchResult import com.sw.platecabinet.model.response.UserFaceModel import retrofit2.http.Body import retrofit2.http.GET +import retrofit2.http.Header import retrofit2.http.POST import retrofit2.http.Query +import retrofit2.http.Url interface ApiService { + /** + * device获取token + */ + @GET("sys/getEquipmentToken") + suspend fun getDeviceToken( + @Query("qrcodeId") qrcodeId: String, + @Query("appVersion") appVersion: String = GlobalData.appVersion + ): ApiResponse + + /** + *获取配置信息 + */ + @GET("equipment/stEquipment/queryByEquipmentCode") + suspend fun getDeviceInfo( + @Query("equipmentCode") equipmentCode: String, + @Query("appVersion") appVersion: String = GlobalData.appVersion, + @Header("X-Access-Token") token: String + ): ApiResponse /** * 生成token */ - @GET("/shuwei-zhct/scales/generateToken") + @GET//("/shuwei-zhct/scales/generateToken") suspend fun generateToken( + @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/scales/generateToken", @Query("deviceId") deviceId: String, @Query("appVersion") appVersion: String, @Query("equipmentCode") equipmentCode: String @@ -28,8 +51,9 @@ interface ApiService { /** * 获取人脸数据 */ - @GET("/shuwei-zhct/scales/getUserFaceCache") + @GET//("/shuwei-zhct/scales/getUserFaceCache") suspend fun getUserFaceCache( + @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/scales/getUserFaceCache", @Query("appVersion") appVersion: String, @Query("equipmentCode") equipmentCode: String ): ApiResponse> @@ -37,38 +61,56 @@ interface ApiService { /** * 餐盘用户信息获取 */ - @POST("/shuwei-zhct/swEquipmentRelUser/equipmentBoxLogin") - suspend fun equipmentBoxLogin(@Body param: LoginParam): ApiResponse + @POST//("/shuwei-zhct/swEquipmentRelUser/equipmentBoxLogin") + suspend fun equipmentBoxLogin( + @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/swEquipmentRelUser/equipmentBoxLogin", + @Body param: LoginParam + ): ApiResponse /** * 餐盘用户信息列表查询 */ - @POST("/shuwei-zhct/swEquipmentRelUser/list") - suspend fun getEquipmentList(@Body param: EquipmentParam): ApiResponse> + @POST//("/shuwei-zhct/swEquipmentRelUser/list") + suspend fun getEquipmentList( + @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/swEquipmentRelUser/list", + @Body param: EquipmentParam + ): ApiResponse> /** * 餐盘用户信息绑定解绑 */ - @POST("/shuwei-zhct/swEquipmentRelUser/addOrEdit") - suspend fun bindEquipment(@Body param: BindParam): ApiResponse + @POST//("/shuwei-zhct/swEquipmentRelUser/addOrEdit") + suspend fun bindEquipment( + @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/swEquipmentRelUser/addOrEdit", + @Body param: BindParam + ): ApiResponse /** * 用户信息模糊搜索 */ - @POST("/shuwei-user/swclientUserInfoShop/selectList") - suspend fun searchUser(@Body param: SearchParam): ApiResponse + @POST//("/shuwei-user/swclientUserInfoShop/selectList") + suspend fun searchUser( + @Url url: String = "${GlobalData.appBaseUrl}/shuwei-user/swclientUserInfoShop/selectList", + @Body param: SearchParam + ): ApiResponse /** * 通过餐盘号获取信息 */ - @POST("/shuwei-zhct/swEquipmentRelUser/findByPlateNumber") - suspend fun findByPlateNumber(@Body param: BindParam): ApiResponse + @POST//("/shuwei-zhct/swEquipmentRelUser/findByPlateNumber") + suspend fun findByPlateNumber( + @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/swEquipmentRelUser/findByPlateNumber", + @Body param: BindParam + ): ApiResponse /** * 获取人脸增量数据 * * @param timeDate 时间戳(毫秒级) */ - @GET("/shuwei-zhct/scales/getHeartbeatInterface") - suspend fun getHeartbeatInterface(@Query("timeDate") timeDate: Long): ApiResponse> + @GET//("/shuwei-zhct/scales/getHeartbeatInterface") + suspend fun getHeartbeatInterface( + @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/scales/getHeartbeatInterface", + @Query("timeDate") timeDate: Long + ): ApiResponse> } \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt b/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt index b512884..e23addd 100644 --- a/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt +++ b/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt @@ -6,6 +6,7 @@ import com.sw.platecabinet.model.request.EquipmentParam import com.sw.platecabinet.model.request.LoginParam import com.sw.platecabinet.model.request.SearchParam import com.sw.platecabinet.model.response.ApiResponse +import com.sw.platecabinet.model.response.EquipmentInfo import com.sw.platecabinet.model.response.EquipmentUserInfo import com.sw.platecabinet.model.response.SearchResult import com.sw.platecabinet.model.response.UserFaceModel @@ -17,15 +18,39 @@ import com.sw.platecabinet.network.api.ApiService class RemoteRepository constructor( private val apiService: ApiService ) : BaseRepository() { + + /** + * 生成token + */ + suspend fun getDeviceToken(qrcodeId: String): ApiResponse { + return safeApiCall { + apiService.getDeviceToken( + qrcodeId + ) + } + } + + /** + * 获取设备信息 + */ + suspend fun getDeviceInfo(equipmentCode: String, token: String): ApiResponse { + return safeApiCall { + apiService.getDeviceInfo( + equipmentCode, + token = token + ) + } + } + /** * 生成token */ suspend fun generateToken(deviceId: String): ApiResponse { return safeApiCall { apiService.generateToken( - deviceId, - GlobalData.appVersion, - GlobalData.globalEquipmentCode + deviceId = deviceId, + appVersion = GlobalData.appVersion, + equipmentCode = GlobalData.globalEquipmentCode ) } } @@ -36,8 +61,8 @@ class RemoteRepository constructor( suspend fun getUserFaceCache(): ApiResponse> { return safeApiCall { apiService.getUserFaceCache( - GlobalData.appVersion, - GlobalData.globalEquipmentCode + appVersion = GlobalData.appVersion, + equipmentCode = GlobalData.globalEquipmentCode ) } } @@ -46,35 +71,35 @@ class RemoteRepository constructor( * 登录 */ suspend fun equipmentBoxLogin(param: LoginParam): ApiResponse { - return safeApiCall { apiService.equipmentBoxLogin(param) } + return safeApiCall { apiService.equipmentBoxLogin(param = param) } } /** * 获取设备绑定用户列表 */ suspend fun getEquipmentList(param: EquipmentParam): ApiResponse> { - return safeApiCall { apiService.getEquipmentList(param) } + return safeApiCall { apiService.getEquipmentList(param = param) } } /** * 餐盘用户信息绑定解绑 */ suspend fun bindEquipment(param: BindParam): ApiResponse { - return safeApiCall { apiService.bindEquipment(param) } + return safeApiCall { apiService.bindEquipment(param = param) } } /** * 用户信息模糊搜索 */ suspend fun searchUser(param: SearchParam): ApiResponse { - return safeApiCall { apiService.searchUser(param) } + return safeApiCall { apiService.searchUser(param = param) } } /** * 通过餐盘编号获取绑定信息 */ suspend fun findByPlateNumber(param: BindParam): ApiResponse { - return safeApiCall { apiService.findByPlateNumber(param) } + return safeApiCall { apiService.findByPlateNumber(param = param) } } /** @@ -83,6 +108,6 @@ class RemoteRepository constructor( * @param timeDate 时间戳(毫秒级) */ suspend fun getHeartbeatInterface(timeDate: Long): ApiResponse> { - return safeApiCall { apiService.getHeartbeatInterface(timeDate) } + return safeApiCall { apiService.getHeartbeatInterface(timeDate = timeDate) } } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/utils/QRCodeUtil.kt b/app/src/main/java/com/sw/platecabinet/utils/QRCodeUtil.kt new file mode 100644 index 0000000..5ddbc01 --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/utils/QRCodeUtil.kt @@ -0,0 +1,103 @@ +package com.sw.platecabinet.utils + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Color +import com.google.zxing.BarcodeFormat +import com.google.zxing.EncodeHintType +import com.google.zxing.WriterException +import com.google.zxing.common.BitMatrix +import com.google.zxing.qrcode.QRCodeWriter +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel +import kotlin.apply +import kotlin.ranges.until +import kotlin.text.isEmpty + +/** + * 二维码生成工具类 + */ +object QRCodeUtil { + + /** + * 生成二维码(默认大小) + * @param content 二维码内容 + * @return 生成的二维码Bitmap + */ + @JvmOverloads + fun generateQRCode(content: String, size: Int = 500): Bitmap? { + return generateQRCode(content, size, Color.BLACK, Color.WHITE) + } + + /** + * 生成二维码(自定义颜色) + * @param content 二维码内容 + * @param size 二维码边长(像素) + * @param colorCode 二维码颜色 + * @param backgroundColor 背景颜色 + * @return 生成的二维码Bitmap + */ + fun generateQRCode( + content: String, + size: Int, + colorCode: Int, + backgroundColor: Int + ): Bitmap? { + if (content.isEmpty()) { + return null + } + + return try { + val hints = mutableMapOf().apply { + put(EncodeHintType.CHARACTER_SET, "UTF-8") + put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H) // 纠错级别 + put(EncodeHintType.MARGIN, 1) // 边距 + } + + val bitMatrix = QRCodeWriter().encode( + content, + BarcodeFormat.QR_CODE, + size, + size, + hints + ) + + val pixels = IntArray(size * size).apply { + for (y in 0 until size) { + for (x in 0 until size) { + this[y * size + x] = if (bitMatrix.get(x, y)) colorCode else backgroundColor + } + } + } + + Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888).apply { + setPixels(pixels, 0, size, 0, 0, size, size) + } + + } catch (e: WriterException) { + e.printStackTrace() + null + } + } + + /** + * 生成带Logo的二维码 + * @param content 二维码内容 + * @param size 二维码边长(像素) + * @param logo Logo Bitmap + * @return 带Logo的二维码Bitmap + */ + fun generateQRCodeWithLogo(content: String, size: Int, logo: Bitmap?): Bitmap? { + val qrCode = generateQRCode(content, size) ?: return null + logo ?: return qrCode + + val logoSize = size / 5 // Logo大小约为二维码的1/5 + val scaledLogo = Bitmap.createScaledBitmap(logo, logoSize, logoSize, false) + + val offset = (size - logoSize) / 2 + return Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888).apply { + val canvas = Canvas(this) + canvas.drawBitmap(qrCode, 0f, 0f, null) + canvas.drawBitmap(scaledLogo, offset.toFloat(), offset.toFloat(), null) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt index 9051b83..771c484 100644 --- a/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt +++ b/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt @@ -3,7 +3,9 @@ package com.sw.platecabinet.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sw.plate.utils.ToastUtils +import com.sw.platecabinet.GlobalData import com.sw.platecabinet.model.response.ApiResponse +import com.sw.platecabinet.model.response.EquipmentInfo import com.sw.platecabinet.network.ApiClient import com.sw.platecabinet.repository.RemoteRepository import kotlinx.coroutines.flow.MutableStateFlow @@ -62,4 +64,12 @@ abstract class BaseViewModel() : ViewModel() { fun handleError(exception: Exception) { Timber.d("handleError ${exception.message}") } + + fun parseEquipmentInfo(equipmentInfo: EquipmentInfo) { + GlobalData.appBaseUrl = equipmentInfo.appPackageUrl!! + GlobalData.sdkKey = equipmentInfo.arcsoftSdkKey!! + GlobalData.appId = equipmentInfo.arcsoftAppId!! +// GlobalData.activeKey = equipmentInfo.arcsoftActiveKey!! + GlobalData.restId = equipmentInfo.canteenId!! + } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/DeviceViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/DeviceViewModel.kt new file mode 100644 index 0000000..e31fde6 --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/viewmodel/DeviceViewModel.kt @@ -0,0 +1,68 @@ +package com.sw.platecabinet.viewmodel + +import com.sw.inbound.utils.GsonUtils +import com.sw.inbound.utils.SPUtil +import com.sw.platecabinet.GlobalData +import com.sw.platecabinet.GlobalKey +import com.sw.platecabinet.model.response.EquipmentInfo +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import timber.log.Timber +import kotlin.jvm.java + +/** + * 初始化的viewmodel + */ +class DeviceViewModel : BaseViewModel() { + private val _deviceInfoResult = MutableStateFlow(null) + val deviceInfoResult: StateFlow = _deviceInfoResult + + /** + * 获取token + */ + fun getDeviceToken(deviceId: String = GlobalData.deviceId) { + launchWithLoading { + val response = repository.getDeviceToken(deviceId) + if (parseResponse(response)) { + val response1 = repository.getDeviceInfo(deviceId, response.result!!) + + if (parseResponse(response1)) { + val equipmentInfo = response1.result + if (equipmentInfo == null) return@launchWithLoading + try { + parseEquipmentInfo(equipmentInfo) + SPUtil.getInstance() + .put(GlobalKey.KEY_EQUIPMENT_INFO, GsonUtils.toJson(equipmentInfo)) + _deviceInfoResult.value = true + } catch (e: Exception) { + Timber.e(e) + } + } + } + } + } + + /** + * 检查缓存数据 + */ + fun checkEquipmentInfo(): Boolean { + val equipmentInfoStr = SPUtil.getInstance().get(GlobalKey.KEY_EQUIPMENT_INFO, "") + if (equipmentInfoStr == null) { + Timber.e("获取缓存设备信息失败") + return false + } + val equipmentInfo = + GsonUtils.fromJson(equipmentInfoStr, EquipmentInfo::class.java) + if (equipmentInfo == null) { + Timber.e("解析缓存设备信息失败") + return false + } + try { + parseEquipmentInfo(equipmentInfo) + return true + } catch (e: Exception) { + Timber.e(e) + return false + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_init_button.xml b/app/src/main/res/drawable/bg_init_button.xml new file mode 100644 index 0000000..71ff7c1 --- /dev/null +++ b/app/src/main/res/drawable/bg_init_button.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_splash.xml b/app/src/main/res/drawable/bg_splash.xml new file mode 100644 index 0000000..df638a7 --- /dev/null +++ b/app/src/main/res/drawable/bg_splash.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/img_init.png b/app/src/main/res/drawable/img_init.png new file mode 100644 index 0000000..e8d0844 Binary files /dev/null and b/app/src/main/res/drawable/img_init.png differ diff --git a/app/src/main/res/layout/activity_device_init.xml b/app/src/main/res/layout/activity_device_init.xml new file mode 100644 index 0000000..940dd59 --- /dev/null +++ b/app/src/main/res/layout/activity_device_init.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_title_time.xml b/app/src/main/res/layout/item_title_time.xml index f77b81c..a67784e 100644 --- a/app/src/main/res/layout/item_title_time.xml +++ b/app/src/main/res/layout/item_title_time.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="40dp" android:paddingHorizontal="24dp"> \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher512.png b/app/src/main/res/mipmap-xxxhdpi/ic_logo512.png similarity index 100% rename from app/src/main/res/mipmap-xxxhdpi/ic_launcher512.png rename to app/src/main/res/mipmap-xxxhdpi/ic_logo512.png diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 2209f65..3877414 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -3,5 +3,6 @@ \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 9b2b5a5..b37dab8 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -4,6 +4,7 @@ true false false + @drawable/bg_splash