增加初始化功能
This commit is contained in:
@@ -55,6 +55,8 @@ dependencies {
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.material)
|
||||
implementation(libs.android.core)
|
||||
implementation(libs.core)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.USB_PERMISSION" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission
|
||||
@@ -16,15 +18,15 @@
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:icon="@mipmap/ic_logo512"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:roundIcon="@mipmap/ic_logo512"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.IntelligentShelves"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
android:name=".HomeActivity"
|
||||
android:name=".InitActivity"
|
||||
android:exported="true"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="DiscouragedApi,LockedOrientationActivity">
|
||||
@@ -34,6 +36,9 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".HomeActivity"
|
||||
android:screenOrientation="portrait"/>
|
||||
<activity
|
||||
android:name=".ShelfActivity"
|
||||
android:screenOrientation="portrait"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.shuwei.intelligent.shelves
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.SharedPreferences
|
||||
import com.shuwei.intelligent.shelves.utils.BootReceiver
|
||||
|
||||
/**
|
||||
@@ -10,14 +12,8 @@ import com.shuwei.intelligent.shelves.utils.BootReceiver
|
||||
* @date: 2022-04-26
|
||||
*/
|
||||
class App : Application() {
|
||||
|
||||
//从接口获取
|
||||
var accessToken: String = ""
|
||||
//"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjYW50ZWVuSWQiOiIiLCJ0eXBlIjoiNiIsInVzZXJJZCI6IjE2NzgyMjY1NTI5MzE1NDkxODYifQ.CQmbELpqT6QzvVCgCeirwvSvPp8Mhft_h6b1Af574Co"
|
||||
|
||||
var deviceId:String = ""
|
||||
var canteenId:String = ""
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
app = this
|
||||
@@ -27,9 +23,26 @@ class App : Application() {
|
||||
|
||||
companion object {
|
||||
private lateinit var app: App
|
||||
var canteenId = "0"
|
||||
var appVersion = "1"
|
||||
var configUrl = ""
|
||||
|
||||
//从接口获取
|
||||
var accessToken: String = ""
|
||||
|
||||
var deviceId: String = ""
|
||||
@Volatile
|
||||
private var sharedPref: SharedPreferences? = null
|
||||
|
||||
fun getInstance(): App {
|
||||
return app
|
||||
}
|
||||
fun getSharedPref(): SharedPreferences? {
|
||||
if (sharedPref != null) {
|
||||
return sharedPref
|
||||
}
|
||||
sharedPref = app.getSharedPreferences("sp_intelligent_shelves", Context.MODE_PRIVATE)
|
||||
return sharedPref
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,20 +133,20 @@ class HomeActivity : BaseActivity() {
|
||||
}
|
||||
TaskManager.startTask()
|
||||
|
||||
var androidId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
|
||||
// androidId = "d0e7a2d5f25c775c"
|
||||
Log.d(TAG, "onCreate: androidId=${androidId}")
|
||||
if (androidId == "65e1012638f78260" || androidId == "40f89e91ee40611d") {
|
||||
androidId = "d0e7a2d5f25c775c"
|
||||
}
|
||||
App.getInstance().deviceId = androidId
|
||||
//"53babf69-0d2f-3875-a649-f2e12f80ad4c1"
|
||||
|
||||
val swDpValue = resources?.configuration?.smallestScreenWidthDp
|
||||
Log.d(TAG, "onCreate: swDpValue=$swDpValue")
|
||||
// var androidId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
|
||||
//// androidId = "d0e7a2d5f25c775c"
|
||||
// Log.d(TAG, "onCreate: androidId=${androidId}")
|
||||
// if (androidId == "65e1012638f78260" || androidId == "40f89e91ee40611d") {
|
||||
// androidId = "d0e7a2d5f25c775c"
|
||||
// }
|
||||
// App.deviceId = androidId
|
||||
// //"53babf69-0d2f-3875-a649-f2e12f80ad4c1"
|
||||
//
|
||||
// val swDpValue = resources?.configuration?.smallestScreenWidthDp
|
||||
// Log.d(TAG, "onCreate: swDpValue=$swDpValue")
|
||||
|
||||
|
||||
viewModel.getAccessToken(App.getInstance().deviceId)
|
||||
viewModel.getAccessToken(App.deviceId)
|
||||
|
||||
// repeat(100) {
|
||||
// lifecycleScope.launch {
|
||||
@@ -183,9 +183,9 @@ class HomeActivity : BaseActivity() {
|
||||
private fun getTokenSuccess(data: RespData<*>) {
|
||||
Log.d(TAG, "getTokenSuccess: $data")
|
||||
data.result?.let {
|
||||
App.getInstance().accessToken = it.toString()
|
||||
App.accessToken = it.toString()
|
||||
//UIUtils.toast(it.toString())
|
||||
viewModel.getShelfList(deviceId = App.getInstance().deviceId)
|
||||
viewModel.getShelfList(deviceId = App.deviceId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ class HomeActivity : BaseActivity() {
|
||||
loadEmptyView()
|
||||
return
|
||||
}
|
||||
App.getInstance().canteenId = data.result.canteenId
|
||||
App.canteenId = data.result.canteenId
|
||||
val tempList = data.result.containerGoodsList
|
||||
if (tempList.isNullOrEmpty()) {
|
||||
loadEmptyView()
|
||||
@@ -215,8 +215,8 @@ class HomeActivity : BaseActivity() {
|
||||
val subList01 = tempList.subList(0, 5)
|
||||
val subList02 = tempList.subList(5, 10)
|
||||
repeat(5) { index ->
|
||||
list.add(subList01[index].also { it.deviceId = App.getInstance().deviceId })
|
||||
list.add(subList02[index].also { it.deviceId = App.getInstance().deviceId })
|
||||
list.add(subList01[index].also { it.deviceId = App.deviceId })
|
||||
list.add(subList02[index].also { it.deviceId = App.deviceId })
|
||||
}
|
||||
shelfAdapter.notifyDataSetChanged()
|
||||
}
|
||||
@@ -491,7 +491,7 @@ class HomeActivity : BaseActivity() {
|
||||
binding.include?.let {
|
||||
it.root.visible()
|
||||
it.root.setOnClickListener {
|
||||
viewModel.getAccessToken(App.getInstance().deviceId)
|
||||
viewModel.getAccessToken(App.deviceId)
|
||||
}
|
||||
it.ivEmptyIcon.setImageResource(R.drawable.ic_empty_white)
|
||||
it.tvEmptyContent.setTextColor(Color.WHITE)
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
package com.shuwei.intelligent.shelves
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import androidx.activity.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.shuwei.intelligent.shelves.base.BaseActivity
|
||||
import com.shuwei.intelligent.shelves.databinding.ActivityInitBinding
|
||||
import com.shuwei.intelligent.shelves.model.DeviceConfigInfo
|
||||
import com.shuwei.intelligent.shelves.net.NetViewModel
|
||||
import com.shuwei.intelligent.shelves.net.UiState
|
||||
import com.shuwei.intelligent.shelves.net.UrlConfig
|
||||
import com.shuwei.intelligent.shelves.utils.AppUtil
|
||||
import com.shuwei.intelligent.shelves.utils.QRCodeUtil
|
||||
import com.shuwei.intelligent.shelves.utils.SpTool
|
||||
import com.shuwei.intelligent.shelves.utils.ext.dp
|
||||
import com.shuwei.intelligent.shelves.utils.ext.invisible
|
||||
import com.shuwei.intelligent.shelves.utils.ext.startActivity
|
||||
import com.shuwei.intelligent.shelves.utils.ext.toJsonString
|
||||
import com.shuwei.intelligent.shelves.utils.ext.toObject
|
||||
import com.shuwei.intelligent.shelves.utils.ext.toast
|
||||
import com.shuwei.intelligent.shelves.utils.ext.visible
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.getValue
|
||||
import kotlin.jvm.java
|
||||
import kotlin.ranges.downTo
|
||||
import kotlin.text.isBlank
|
||||
import kotlin.to
|
||||
|
||||
class InitActivity : BaseActivity() {
|
||||
companion object {
|
||||
const val TAG = "InitActivity"
|
||||
}
|
||||
|
||||
private lateinit var binding: ActivityInitBinding
|
||||
|
||||
private val viewModel: NetViewModel by viewModels()
|
||||
|
||||
@SuppressLint("HardwareIds")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityInitBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
// 获取 ANDROID_ID
|
||||
val androidId =
|
||||
Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
|
||||
App.deviceId = androidId
|
||||
SpTool.put(SpTool.DEVICE_ID, androidId)
|
||||
App.configUrl = UrlConfig.BASE_URL
|
||||
App.canteenId = "0"
|
||||
|
||||
// var deviceId = AppUtil.getUDID(this)
|
||||
// Log.d(TAG, "onCreate: deviceId=$deviceId")
|
||||
//// deviceId = "39a7abdd06b3c7ab"
|
||||
//// deviceId = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e"
|
||||
// App.deviceId = deviceId
|
||||
//
|
||||
// SpTool.put(SpTool.DEVICE_ID, deviceId)
|
||||
// val deviceConfigCache = SpTool.getString(SpTool.DEVICE_CONFIG_CACHE)
|
||||
// val checkResult = checkConfigData(deviceConfigCache)
|
||||
// if (checkResult.not()) {
|
||||
// binding.ivQrCode.visible()
|
||||
// binding.btnInit.visible()
|
||||
// //进行初始化操作
|
||||
// initConfig()
|
||||
// return
|
||||
// }
|
||||
binding.ivQrCode.invisible()
|
||||
binding.btnInit.invisible()
|
||||
|
||||
countDown()
|
||||
}
|
||||
|
||||
private fun countDown() {
|
||||
lifecycleScope.launch {
|
||||
flow {
|
||||
(2 downTo 1).forEach {
|
||||
delay(1000)
|
||||
emit(it)
|
||||
}
|
||||
}.collect {
|
||||
// 倒计时结束执行跳转
|
||||
if (it == 1) {
|
||||
startActivity<HomeActivity>()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initConfig() {
|
||||
binding.ivQrCode.setImageBitmap(
|
||||
QRCodeUtil.generateQRCode(
|
||||
content = App.deviceId,
|
||||
size = 200.dp
|
||||
)
|
||||
)
|
||||
binding.btnInit.setOnClickListener {
|
||||
viewModel.getDeviceToken(App.deviceId)
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||
launch {
|
||||
viewModel.getDeviceTokenUiState.collect { state ->
|
||||
when (state) {
|
||||
is UiState.Loading -> {}
|
||||
is UiState.Success<*> -> {
|
||||
state.data.result?.let { deviceToken ->
|
||||
Log.d(TAG, "initConfig: $deviceToken")
|
||||
viewModel.getDeviceConfig(
|
||||
deviceId = App.deviceId,
|
||||
deviceToken = deviceToken.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
is UiState.Error -> toast(state.msg)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
launch {
|
||||
viewModel.getDeviceConfigUiState.collect { state ->
|
||||
when (state) {
|
||||
is UiState.Loading -> {}
|
||||
is UiState.Success<*> -> {
|
||||
state.data.result?.let {
|
||||
if (it is DeviceConfigInfo) {
|
||||
SpTool.put(SpTool.DEVICE_CONFIG_CACHE, it.toJsonString())
|
||||
App.configUrl = it.appPackageUrl?:""
|
||||
App.canteenId = it.canteenId?:""
|
||||
|
||||
startActivity<HomeActivity>()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
is UiState.Error -> toast(message = state.msg)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkConfigData(data: String): Boolean {
|
||||
if (data.isBlank()) {
|
||||
return false
|
||||
}
|
||||
val config = data.toObject<DeviceConfigInfo?>()
|
||||
if (config == null) {
|
||||
return false
|
||||
}
|
||||
App.configUrl = config.appPackageUrl?:""
|
||||
App.canteenId = config.canteenId?:""
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -202,7 +202,7 @@ class ShelfActivity : BaseActivity() {
|
||||
|
||||
private fun getGoodsList() {
|
||||
viewModel.getGoodsList(
|
||||
canteenId = App.getInstance().canteenId,
|
||||
canteenId = App.canteenId,
|
||||
goodsName = binding.etInputFood.text.trim().toString(),
|
||||
pageNo = pageNo,
|
||||
pageSize = PAGE_SIZE
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.shuwei.intelligent.shelves.model
|
||||
|
||||
class DeviceConfigInfo {
|
||||
var appPackageUrl:String? = null
|
||||
var canteenId:String? = null
|
||||
}
|
||||
@@ -1,31 +1,66 @@
|
||||
package com.shuwei.intelligent.shelves.net
|
||||
|
||||
import com.shuwei.intelligent.shelves.App
|
||||
import com.shuwei.intelligent.shelves.model.DeviceConfigInfo
|
||||
import com.shuwei.intelligent.shelves.model.GoodsRecord
|
||||
import com.shuwei.intelligent.shelves.model.ShelfBody
|
||||
import com.shuwei.intelligent.shelves.model.ShelfResult
|
||||
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 = App.appVersion
|
||||
): RespData<String>
|
||||
|
||||
@GET(UrlConfig.GET_ACCESS_TOKEN)
|
||||
suspend fun getAccessToken(@Query("qrcodeId") qrcodeId: String): RespData<String?>
|
||||
/**
|
||||
*获取配置信息
|
||||
*/
|
||||
@GET("/equipment/stEquipment/queryByEquipmentCode")
|
||||
suspend fun getDeviceInfo(
|
||||
@Query("equipmentCode") equipmentCode: String,
|
||||
@Query("appVersion") appVersion: String = App.appVersion,
|
||||
@Header("X-Access-Token") token: String
|
||||
): RespData<DeviceConfigInfo>
|
||||
|
||||
@GET(UrlConfig.GET_SHELF_LIST)
|
||||
suspend fun getShelfList(@Query("deviceId") deviceId: String): RespData<ShelfResult>
|
||||
@GET
|
||||
suspend fun getAccessToken(
|
||||
@Url url: String = UrlConfig.GET_ACCESS_TOKEN,
|
||||
@Query("qrcodeId") qrcodeId: String,
|
||||
@Query("x-access-token") token: String = App.accessToken
|
||||
): RespData<String?>
|
||||
|
||||
@GET(UrlConfig.GET_GOODS_LIST)
|
||||
@GET
|
||||
suspend fun getShelfList(
|
||||
@Url url: String = UrlConfig.GET_SHELF_LIST,
|
||||
@Query("deviceId") deviceId: String,
|
||||
@Query("x-access-token") token: String = App.accessToken
|
||||
): RespData<ShelfResult>
|
||||
|
||||
@GET
|
||||
suspend fun getGoodsList(
|
||||
@Url url: String = UrlConfig.GET_GOODS_LIST,
|
||||
@Query("canteenId") canteenId: String = "0",
|
||||
@Query("goodsName") goodsName: String? = null,
|
||||
@Query("pageNo") pageNo: Int = 1,
|
||||
@Query("pageSize") pageSize: Int = 50,
|
||||
@Query("x-access-token") token: String = App.accessToken
|
||||
): RespData<GoodsRecord>
|
||||
|
||||
|
||||
@POST(UrlConfig.SAVE_SHELF_GOODS_LIST)
|
||||
suspend fun saveShelfGoodsList(@Body body: ShelfBody): RespData<Any?>
|
||||
@POST
|
||||
suspend fun saveShelfGoodsList(
|
||||
@Url url: String = UrlConfig.SAVE_SHELF_GOODS_LIST,
|
||||
@Body body: ShelfBody,
|
||||
@Query("x-access-token") token: String = App.accessToken
|
||||
): RespData<Any?>
|
||||
|
||||
}
|
||||
@@ -16,7 +16,8 @@ import java.security.cert.X509Certificate
|
||||
import kotlin.apply
|
||||
|
||||
val apiService: ApiService = Retrofit.Builder()
|
||||
.baseUrl(UrlConfig.BASE_URL)
|
||||
// .baseUrl(UrlConfig.BASE_URL)
|
||||
.baseUrl(UrlConfig.DEVICE_BASE_URL)
|
||||
.client(HttpManager.instance.client)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
@@ -32,12 +33,12 @@ class HttpManager private constructor() {
|
||||
sslSocketFactory(createSSLSocketFactory(), TrustAllCerts())
|
||||
hostnameVerifier { _, _ -> true }
|
||||
addInterceptor(LoggingInterceptor())
|
||||
addInterceptor { chain ->
|
||||
val request = chain.request().newBuilder()
|
||||
.header("x-access-token", App.getInstance().accessToken)
|
||||
.build()
|
||||
chain.proceed(request)
|
||||
}
|
||||
// addInterceptor { chain ->
|
||||
// val request = chain.request().newBuilder()
|
||||
// .header("x-access-token", App.accessToken)
|
||||
// .build()
|
||||
// chain.proceed(request)
|
||||
// }
|
||||
}
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -32,11 +32,50 @@ class NetViewModel : ViewModel() {
|
||||
private val _getAccessTokenUiState = MutableStateFlow<UiState>(UiState.Initial)
|
||||
val getAccessTokenUiState: StateFlow<UiState> = _getAccessTokenUiState
|
||||
|
||||
private val _getDeviceTokenUiState = MutableStateFlow<UiState>(UiState.Initial)
|
||||
val getDeviceTokenUiState: StateFlow<UiState> = _getDeviceTokenUiState
|
||||
|
||||
private val _getDeviceConfigUiState = MutableStateFlow<UiState>(UiState.Initial)
|
||||
val getDeviceConfigUiState: StateFlow<UiState> = _getDeviceConfigUiState
|
||||
|
||||
|
||||
fun getDeviceToken(deviceId: String) {
|
||||
viewModelScope.launch {
|
||||
_getDeviceTokenUiState.value = UiState.Loading
|
||||
runCatching {
|
||||
val response = apiService.getDeviceToken(qrcodeId = deviceId)
|
||||
if (response.success) {
|
||||
_getDeviceTokenUiState.value = UiState.Success(response)
|
||||
} else {
|
||||
_getDeviceTokenUiState.value = UiState.Error(response.message ?: "请求失败")
|
||||
}
|
||||
}.onFailure {
|
||||
_getDeviceTokenUiState.value = UiState.Error(it.message ?: "请求异常")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getDeviceConfig(deviceId: String, deviceToken: String) {
|
||||
viewModelScope.launch {
|
||||
_getDeviceTokenUiState.value = UiState.Loading
|
||||
runCatching {
|
||||
val response = apiService.getDeviceInfo(equipmentCode = deviceId, token = deviceToken)
|
||||
if (response.success) {
|
||||
_getDeviceTokenUiState.value = UiState.Success(response)
|
||||
} else {
|
||||
_getDeviceTokenUiState.value = UiState.Error(response.message ?: "请求失败")
|
||||
}
|
||||
}.onFailure {
|
||||
_getDeviceTokenUiState.value = UiState.Error(it.message ?: "请求异常")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAccessToken(deviceId: String) {
|
||||
viewModelScope.launch {
|
||||
_getAccessTokenUiState.value = UiState.Loading
|
||||
runCatching {
|
||||
val response = apiService.getAccessToken(deviceId)
|
||||
val response = apiService.getAccessToken(qrcodeId = deviceId)
|
||||
if (response.success) {
|
||||
_getAccessTokenUiState.value = UiState.Success(response)
|
||||
} else {
|
||||
@@ -52,7 +91,7 @@ class NetViewModel : ViewModel() {
|
||||
viewModelScope.launch {
|
||||
_getShelfListUiState.value = UiState.Loading
|
||||
runCatching {
|
||||
val response = apiService.getShelfList(deviceId)
|
||||
val response = apiService.getShelfList(deviceId = deviceId)
|
||||
if (response.success) {
|
||||
_getShelfListUiState.value = UiState.Success(response)
|
||||
} else {
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
package com.shuwei.intelligent.shelves.net
|
||||
|
||||
import com.shuwei.intelligent.shelves.App
|
||||
|
||||
object UrlConfig {
|
||||
const val DEVICE_BASE_URL = "http://device.shuziweidao.com:8889"
|
||||
// /**
|
||||
// * device获取token
|
||||
// */
|
||||
// const val DEVICE_TOKEN = "${DEVICE_BASE_URL}/sys/getEquipmentToken"
|
||||
// /**
|
||||
// *获取配置信息
|
||||
// */
|
||||
// const val DEVICE_CONFIG = "${DEVICE_BASE_URL}/equipment/stEquipment/queryByEquipmentCode"
|
||||
|
||||
// const val BASE_URL = "http://192.168.1.3:9002"
|
||||
const val BASE_URL = "https://yyjk.shuziweidao.com/gateway/"
|
||||
const val GET_ACCESS_TOKEN = "restaurant/equipment/stEquipment/getEquipmentToken"
|
||||
const val GET_SHELF_LIST = "inventory/smartShelves/app/getShelvesListByDeviceId"
|
||||
const val GET_GOODS_LIST = "inventory/smartShelves/app/getGoodsPageList"
|
||||
const val SAVE_SHELF_GOODS_LIST = "inventory/smartShelves/app/saveShelvesGoodsList"
|
||||
const val BASE_URL = "https://yyjk.shuziweidao.com/gateway"
|
||||
var GET_ACCESS_TOKEN = "${App.configUrl}/restaurant/equipment/stEquipment/getEquipmentToken"
|
||||
var GET_SHELF_LIST = "${App.configUrl}/inventory/smartShelves/app/getShelvesListByDeviceId"
|
||||
var GET_GOODS_LIST = "${App.configUrl}/inventory/smartShelves/app/getGoodsPageList"
|
||||
var SAVE_SHELF_GOODS_LIST = "${App.configUrl}/inventory/smartShelves/app/saveShelvesGoodsList"
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -43,13 +43,13 @@ class SyncTask(appContext: Context, workerParams: WorkerParameters) :
|
||||
it.humidity = HomeActivity.showHumidity
|
||||
}
|
||||
val body = ShelfBody().also {
|
||||
it.deviceId = App.getInstance().deviceId
|
||||
it.canteenId = App.getInstance().canteenId
|
||||
it.deviceId = App.deviceId ?: ""
|
||||
it.canteenId = App.canteenId
|
||||
it.temperature = HomeActivity.showTemperatureC
|
||||
it.humidity = HomeActivity.showHumidity
|
||||
it.goodsList = submitList
|
||||
}
|
||||
val resp = apiService.saveShelfGoodsList(body)
|
||||
val resp = apiService.saveShelfGoodsList(body = body)
|
||||
Log.d(TAG, "performSync: body:${body.toJsonString()}")
|
||||
Log.d(TAG, "performSync: resp:${resp.toJsonString()}")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,751 @@
|
||||
package com.shuwei.intelligent.shelves.utils;
|
||||
|
||||
import static android.content.Context.TELEPHONY_SERVICE;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.NetworkInterface;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AppUtil {
|
||||
public static String getAppPackageName(Context context) {
|
||||
String packageName = "";
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
|
||||
packageName = pi.packageName;
|
||||
if (AppUtil.isEmpty(packageName)) {
|
||||
return "";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public static String getAppVersionName(Context context) {
|
||||
String versionName = "";
|
||||
// int versioncode=1;
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
|
||||
versionName = pi.versionName;
|
||||
// versioncode = pi.versionCode;表示更新了多少次
|
||||
if (versionName == null || versionName.length() <= 0) {
|
||||
return "";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return versionName;
|
||||
}
|
||||
|
||||
|
||||
public static int getAppVersionCode(Context context) {
|
||||
int versioncode = 1;
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
|
||||
versioncode = pi.versionCode;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return versioncode;
|
||||
}
|
||||
|
||||
//判断微信是否安装
|
||||
public static boolean isWeixinInstalled(Context context) {
|
||||
final PackageManager packageManager = context.getPackageManager();// 获取packagemanager
|
||||
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// 获取所有已安装程序的包信息
|
||||
if (pinfo != null) {
|
||||
for (int i = 0; i < pinfo.size(); i++) {
|
||||
String pn = pinfo.get(i).packageName;
|
||||
if (pn.equals("com.tencent.mm")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打电话
|
||||
* <p>
|
||||
* Intent.ACTION_DIAL Intent.ACTION_CALL
|
||||
*
|
||||
* @param context
|
||||
* @param mobile
|
||||
*/
|
||||
public static void callUp(Context context, String mobile) {
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"
|
||||
+ mobile));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备ID
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static String getDevId(Context context) {
|
||||
TelephonyManager TelephonyMgr = (TelephonyManager) context
|
||||
.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
return TelephonyMgr.getDeviceId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 姓名脱敏
|
||||
*
|
||||
* @param fullName
|
||||
* @return
|
||||
*/
|
||||
public static String desensitizedName(String fullName) {
|
||||
if (fullName == null || fullName.length() <= 1) {
|
||||
return fullName;
|
||||
}
|
||||
char[] nameArr = fullName.toCharArray();
|
||||
if (nameArr.length > 2) {
|
||||
for (int i = 1; i < nameArr.length - 1; i++) {
|
||||
nameArr[i] = '*';
|
||||
}
|
||||
} else {
|
||||
nameArr[1] = '*';
|
||||
}
|
||||
|
||||
return new String(nameArr);
|
||||
}
|
||||
|
||||
|
||||
public static String formatDateGetFull(String date) {
|
||||
if (isEmpty(date)) {
|
||||
return "";
|
||||
}
|
||||
Date d = new Date(Long.parseLong(date));
|
||||
SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
return dateFormat1.format(d);
|
||||
}
|
||||
|
||||
public static String formatDateGetCurrentTime() {
|
||||
Date d = new Date(System.currentTimeMillis());
|
||||
SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//.SSS
|
||||
return dateFormat1.format(d);
|
||||
}
|
||||
|
||||
|
||||
public static String formatDateGetFull(long date) {
|
||||
if (date == 0) {
|
||||
return "";
|
||||
}
|
||||
Date d = new Date(date);
|
||||
SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
return dateFormat1.format(d);
|
||||
}
|
||||
|
||||
public static String formatDateGetDay(long date) {
|
||||
if (date == 0) {
|
||||
return "";
|
||||
}
|
||||
Date d = new Date(date);
|
||||
SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return dateFormat1.format(d);
|
||||
}
|
||||
|
||||
public static boolean isEmpty(String s) {
|
||||
if (TextUtils.isEmpty(s) || s.trim().equals("null")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 格式化浮点型
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static String formatDouble(double data) {
|
||||
return new DecimalFormat("0.00").format(data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 格式化分钟
|
||||
*
|
||||
* @param minutes
|
||||
* @return
|
||||
*/
|
||||
public static String formatMinutes(int minutes) {
|
||||
int hour = minutes / 60;
|
||||
int minute = minutes % 60;
|
||||
if (hour > 0 && minute > 0) {
|
||||
return hour + "小时" + minute + "分钟";
|
||||
} else if (hour > 0) {
|
||||
return hour + "小时";
|
||||
} else {
|
||||
return minute + "分钟";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//com.fawan.news
|
||||
public static void goToMarket(Context context, String packageName) {
|
||||
Uri uri = Uri.parse("market://details?id=" + packageName);
|
||||
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
|
||||
try {
|
||||
context.startActivity(goToMarket);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* true为存在,false为不存在
|
||||
*
|
||||
* @param context
|
||||
* @param packageName
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInstallApp(Context context, String packageName) {
|
||||
try {
|
||||
context.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
|
||||
return true;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化float 保留两位小数
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static float formatFloat2(float data) {
|
||||
// DecimalFormat decimalFormat = new DecimalFormat("0.00");//构造方法的字符格式这里如果小数不足2位,会以0补足.
|
||||
// return decimalFormat.format(data);//返回字符串
|
||||
|
||||
int scale = 1;//设置位数
|
||||
int roundingMode = 4;//表示四舍五入,可以选择其他舍值方式,例如去尾,等等.
|
||||
BigDecimal bd = new BigDecimal((double) data);
|
||||
bd = bd.setScale(scale, roundingMode);
|
||||
data = bd.floatValue();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Android 6.0 之前(不包括6.0)获取mac地址
|
||||
* 必须的权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
|
||||
*
|
||||
* @param context * @return
|
||||
*/
|
||||
public static String getMacDefault(Context context) {
|
||||
String mac = "";
|
||||
if (context == null) {
|
||||
return mac;
|
||||
}
|
||||
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
WifiInfo info = null;
|
||||
try {
|
||||
info = wifi.getConnectionInfo();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
mac = info.getMacAddress();
|
||||
if (!TextUtils.isEmpty(mac)) {
|
||||
mac = mac.toUpperCase(Locale.ENGLISH);
|
||||
}
|
||||
return mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Android 6.0-Android 7.0 获取mac地址
|
||||
*/
|
||||
public static String getMacAddress() {
|
||||
String macSerial = null;
|
||||
String str = "";
|
||||
|
||||
try {
|
||||
Process pp = Runtime.getRuntime().exec("cat/sys/class/net/wlan0/address");
|
||||
InputStreamReader ir = new InputStreamReader(pp.getInputStream());
|
||||
LineNumberReader input = new LineNumberReader(ir);
|
||||
|
||||
while (null != str) {
|
||||
str = input.readLine();
|
||||
if (str != null) {
|
||||
macSerial = str.trim();//去空格
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// 赋予默认值
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return macSerial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Android 7.0之后获取Mac地址
|
||||
* 遍历循环所有的网络接口,找到接口是 wlan0
|
||||
* 必须的权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getMacFromHardware() {
|
||||
try {
|
||||
ArrayList<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
for (NetworkInterface nif : all) {
|
||||
if (!nif.getName().equals("wlan0"))
|
||||
continue;
|
||||
byte[] macBytes = nif.getHardwareAddress();
|
||||
if (macBytes == null) return "";
|
||||
StringBuilder res1 = new StringBuilder();
|
||||
for (Byte b : macBytes) {
|
||||
res1.append(String.format("%02X:", b));
|
||||
}
|
||||
if (!TextUtils.isEmpty(res1)) {
|
||||
res1.deleteCharAt(res1.length() - 1);
|
||||
}
|
||||
return res1.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取mac地址(适配所有Android版本)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getMac(Context context) {
|
||||
String mac = "";
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
mac = getMacDefault(context);
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
mac = getMacAddress();
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
mac = getMacFromHardware();
|
||||
}
|
||||
return mac;
|
||||
}
|
||||
|
||||
//把String转化为float
|
||||
public static double convertToFloat(String number, double defaultValue) {
|
||||
if (TextUtils.isEmpty(number)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(number);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取AndroidId
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static String getAndroidId(Context context) {
|
||||
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
return androidId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备唯一 UDID
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
public static String getUDID(Context context) {
|
||||
// String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
// L.e("androidID===" + androidID);
|
||||
// return androidID;
|
||||
String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
if (!androidID.equals("")) {
|
||||
try {
|
||||
if (!"9774d56d682e549c".equals(androidID)) {
|
||||
androidID = UUID.nameUUIDFromBytes(androidID.getBytes("utf8")).toString();
|
||||
} else {
|
||||
@SuppressLint("MissingPermission") final String deviceId = ((TelephonyManager) context.getSystemService(TELEPHONY_SERVICE)).getDeviceId();
|
||||
androidID = deviceId != null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")).toString() : UUID.randomUUID().toString();
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return androidID;
|
||||
}
|
||||
|
||||
//需要权限 android.permission.READ_PHONE_STATE
|
||||
TelephonyManager TelephonyMgr = (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE);
|
||||
String szImei = TelephonyMgr.getDeviceId();
|
||||
if (!szImei.equals("")) {
|
||||
return szImei;
|
||||
}
|
||||
|
||||
//需要权限 android.permission.ACCESS_WIFI_STATE
|
||||
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
|
||||
if (!m_szWLANMAC.equals("")) {
|
||||
return m_szWLANMAC;
|
||||
}
|
||||
|
||||
//需要权限 android.permission.BLUETOOTH
|
||||
BluetoothAdapter m_BluetoothAdapter = null;
|
||||
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
String m_szBTMAC = m_BluetoothAdapter.getAddress();
|
||||
if (!m_szBTMAC.equals("")) {
|
||||
return m_szBTMAC;
|
||||
}
|
||||
return getUniquePsuedoID();
|
||||
}
|
||||
|
||||
//获得 Psuedo ID
|
||||
public static String getUniquePsuedoID() {
|
||||
String serial = null;
|
||||
String m_szDevIDShort = "35" +
|
||||
Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +
|
||||
Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +
|
||||
Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +
|
||||
Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +
|
||||
Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +
|
||||
Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +
|
||||
Build.USER.length() % 10; //13 位
|
||||
try {
|
||||
serial = Build.class.getField("SERIAL").get(null).toString();
|
||||
//API>=9 使用serial号
|
||||
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
|
||||
} catch (Exception exception) {
|
||||
//serial需要一个初始化,随意值
|
||||
serial = "serial";
|
||||
}
|
||||
|
||||
//使用硬件信息拼凑出来的15位号码
|
||||
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
|
||||
}
|
||||
|
||||
public static String getCPUSerial() {
|
||||
String line = "";
|
||||
String TAG = "aaa";
|
||||
Log.e(TAG, " get_quck_Sn() ");
|
||||
Class<?> c = null;
|
||||
try {
|
||||
c = Class.forName("android.os.SystemProperties");
|
||||
|
||||
Method get = c.getMethod("get", String.class);
|
||||
line = (String) get.invoke(c, "ro.serialno");
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Log.e(TAG, " get_quck_Sn() " + line);
|
||||
System.out.println("设备串号" + line);
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断网络连接状态
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNetworkConnected(Context context) {
|
||||
if (context != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
|
||||
if (mNetworkInfo != null) {
|
||||
return mNetworkInfo.isAvailable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断WiFi连接状态
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static boolean isWifiConnected(Context context) {
|
||||
if (context != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mWiFiNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
if (mWiFiNetworkInfo != null) {
|
||||
return mWiFiNetworkInfo.isAvailable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断移动网络状态
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMobileConnected(Context context) {
|
||||
if (context != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mMobileNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
|
||||
if (mMobileNetworkInfo != null) {
|
||||
return mMobileNetworkInfo.isAvailable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取网络连接类型
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static int getConnectedType(Context context) {
|
||||
if (context != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
|
||||
if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
|
||||
return mNetworkInfo.getType();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字符的起始和结束索引提取子串
|
||||
*
|
||||
* @param input 原始字符串
|
||||
* @param startIndex 起始索引(包含,从0开始)
|
||||
* @param endIndex 结束索引(不包含)
|
||||
* @return 子串,若输入无效或索引越界则返回空字符串
|
||||
*/
|
||||
public static String getSubstringByIndices(String input, int startIndex, int endIndex) {
|
||||
if (input == null) {
|
||||
return "";
|
||||
}
|
||||
// 处理索引越界问题
|
||||
int safeStart = Math.max(startIndex, 0);
|
||||
int safeEnd = Math.min(endIndex, input.length());
|
||||
if (safeStart > safeEnd) {
|
||||
return "";
|
||||
}
|
||||
return input.substring(safeStart, safeEnd);
|
||||
}
|
||||
|
||||
public static String getSubstringByIndex(String input, int startIndex, int length) {
|
||||
if (input == null) {
|
||||
return "";
|
||||
}
|
||||
// 处理索引越界问题
|
||||
int safeStart = Math.max(startIndex, 0);
|
||||
int safeEnd = Math.min(startIndex + length, input.length());
|
||||
if (safeStart > safeEnd) {
|
||||
return "";
|
||||
}
|
||||
return input.substring(safeStart, safeEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 十进制转十六进制
|
||||
*
|
||||
* @param decimal
|
||||
* @return
|
||||
*/
|
||||
public static String decimalToHexWithPadding(int decimal, int padding) {
|
||||
// 将十进制转换为十六进制,并转换为字符串
|
||||
String hex = Integer.toHexString(decimal);
|
||||
|
||||
// 确保字符串长度为至少4位,不足部分前面补0
|
||||
while (hex.length() < padding) {
|
||||
hex = "0" + hex;
|
||||
}
|
||||
|
||||
return hex.toUpperCase(); // 返回大写形式的十六进制字符串
|
||||
}
|
||||
|
||||
/**
|
||||
* 十进制转二进制,且返回的二进制为至少7位数
|
||||
*
|
||||
* @param decimal
|
||||
* @return
|
||||
*/
|
||||
public static String decimalToBinary(int decimal) {
|
||||
// 如果输入为0,直接返回"0"
|
||||
if (decimal == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
StringBuilder binary = new StringBuilder();
|
||||
|
||||
// 除2取余法,将余数加入二进制字符串
|
||||
while (decimal > 0) {
|
||||
int remainder = decimal % 2;
|
||||
binary.insert(0, remainder);
|
||||
decimal = decimal / 2;
|
||||
}
|
||||
int length = binary.length();
|
||||
if (length < 7) {
|
||||
int padding = 7 - length;
|
||||
for (int i = 0; i < padding; i++) {
|
||||
binary.insert(0, '0');
|
||||
}
|
||||
}
|
||||
return binary.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将二进制字符串转换为十六进制字符串,每8位转换为两位十六进制,不足两位前面补零
|
||||
*
|
||||
* @param binaryStr 输入的二进制字符串(仅包含0和1)
|
||||
* @return 转换后的十六进制字符串
|
||||
* @throws IllegalArgumentException 如果输入不是有效的二进制字符串
|
||||
*/
|
||||
public static String binaryToHex(String binaryStr) {
|
||||
// 校验输入合法性
|
||||
if (binaryStr == null || !binaryStr.matches("[01]+")) {
|
||||
throw new IllegalArgumentException("Invalid binary string");
|
||||
}
|
||||
|
||||
// 补前导零使长度成为8的倍数
|
||||
int length = binaryStr.length();
|
||||
int padding = (8 - (length % 8)) % 8; // 计算需要补零的数量
|
||||
StringBuilder paddedBinary = new StringBuilder();
|
||||
for (int i = 0; i < padding; i++) {
|
||||
paddedBinary.append('0');
|
||||
}
|
||||
paddedBinary.append(binaryStr);
|
||||
|
||||
// 每8位转换为两位十六进制
|
||||
StringBuilder hexStr = new StringBuilder();
|
||||
for (int i = 0; i < paddedBinary.length(); i += 8) {
|
||||
String byteStr = paddedBinary.substring(i, i + 8);
|
||||
int decimalValue = Integer.parseInt(byteStr, 2);
|
||||
hexStr.append(String.format("%02X", decimalValue & 0xFF));
|
||||
}
|
||||
|
||||
return hexStr.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据校验 异或处理
|
||||
*/
|
||||
public static String getXor(String content) {
|
||||
int a = 0;
|
||||
for (int i = 0; i < content.length() / 2; i++) {
|
||||
a = a ^ Integer.parseInt(content.substring(i * 2, (i * 2) + 2), 16);
|
||||
}
|
||||
String result = Integer.toHexString(a).toUpperCase();
|
||||
if (result.length() == 1) {
|
||||
return "0" + result;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static double formatPersonInfo(String input, int startIndex, int length) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
// 处理索引越界问题
|
||||
int safeStart = Math.max(startIndex, 0);
|
||||
int safeEnd = Math.min(startIndex + length, input.length());
|
||||
if (safeStart > safeEnd) {
|
||||
return 0;
|
||||
}
|
||||
String result = input.substring(safeStart, safeEnd);
|
||||
double num = Integer.parseInt(result, 16);
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装apk
|
||||
*
|
||||
* @param activity
|
||||
* @param apkFile
|
||||
*/
|
||||
public static void installApk(Context activity, File apkFile) {
|
||||
//文件有所有者概念,现在是属于当前进程的,需要把这个文件暴露给系统安装程序(其他进程)去安装
|
||||
//因此,可能会存在权限问题,需要做下面的设置
|
||||
//如果文件是sdcard上的,就不需要这个操作了
|
||||
try {
|
||||
apkFile.setExecutable(true, false);
|
||||
apkFile.setReadable(true, false);
|
||||
apkFile.setWritable(true, false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
Uri uri;
|
||||
|
||||
//TODO N FileProvider
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
uri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileProvider", apkFile);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
// intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
} else {
|
||||
uri = Uri.fromFile(apkFile);
|
||||
}
|
||||
|
||||
intent.setDataAndType(uri, "application/vnd.android.package-archive");
|
||||
activity.startActivity(intent);
|
||||
|
||||
//TODO 0 INSTALL PERMISSION
|
||||
//在AndroidManifest中加入权限即可
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.shuwei.intelligent.shelves.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
|
||||
|
||||
|
||||
/**
|
||||
* 二维码生成工具类
|
||||
*/
|
||||
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<EncodeHintType, Any>().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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.shuwei.intelligent.shelves.utils
|
||||
|
||||
import com.shuwei.intelligent.shelves.App
|
||||
import com.shuwei.intelligent.shelves.utils.ext.put
|
||||
import kotlin.to
|
||||
|
||||
object SpTool {
|
||||
|
||||
const val DEVICE_CONFIG_CACHE = "deviceConfigCache"
|
||||
const val TOKEN = "token"
|
||||
const val LAUNCH_PAGE_TYPE = "launchPageType"
|
||||
const val DEVICE_ID = "deviceId"
|
||||
|
||||
val pref = App.getSharedPref()!!
|
||||
|
||||
fun put(key: String, value: Any) {
|
||||
pref.put(key to value)
|
||||
}
|
||||
|
||||
fun getInt(key: String, defValue: Int = 0): Int {
|
||||
return pref.getInt(key, defValue)
|
||||
}
|
||||
|
||||
fun getString(key: String, defValue: String? = ""): String {
|
||||
return pref.getString(key, defValue) ?: ""
|
||||
}
|
||||
|
||||
fun getBoolean(key: String, defValue: Boolean = false): Boolean {
|
||||
return pref.getBoolean(key, defValue)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#30000000">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
|
||||
<solid android:color="#ff08C6DC" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 999 KiB |
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="450dp"
|
||||
android:layout_height="450dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginStart="50dp"
|
||||
android:layout_marginTop="150dp"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:src="@drawable/img_init"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnInit"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="100dp"
|
||||
android:background="@drawable/bg_init_button"
|
||||
android:gravity="center"
|
||||
android:padding="10dp"
|
||||
android:text="设备初始化"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="visible"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivQrCode"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="200dp"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:layout_marginBottom="50dp"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@mipmap/ic_logo512" />
|
||||
|
||||
</LinearLayout>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">192.168.1.3</domain>
|
||||
<domain includeSubdomains="true">192.168.1.7</domain>
|
||||
</domain-config>
|
||||
<!-- <domain-config cleartextTrafficPermitted="true">-->
|
||||
<!-- <domain includeSubdomains="true">192.168.1.3</domain>-->
|
||||
<!-- <domain includeSubdomains="true">192.168.1.7</domain>-->
|
||||
<!-- </domain-config> -->
|
||||
<base-config cleartextTrafficPermitted="true" />
|
||||
</network-security-config>
|
||||
|
||||
@@ -8,8 +8,12 @@ junitVersion = "1.1.5"
|
||||
espressoCore = "3.5.1"
|
||||
appcompat = "1.6.1"
|
||||
material = "1.10.0"
|
||||
core = "3.4.1"
|
||||
androidCore = "3.3.0"
|
||||
|
||||
[libraries]
|
||||
android-core = { module = "com.google.zxing:android-core", version.ref = "androidCore" }
|
||||
core = { module = "com.google.zxing:core", version.ref = "core" }
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
|
||||
Reference in New Issue
Block a user