diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt deleted file mode 100644 index 274637f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt +++ /dev/null @@ -1,293 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation -import com.casic.br.operationsite.R -import com.casic.br.operationsite.callback.OnImageCompressListener -import com.casic.br.operationsite.databinding.ActivityUploadActivityBinding -import com.casic.br.operationsite.extensions.combineImagePath -import com.casic.br.operationsite.extensions.compressImage -import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.ImageModel -import com.casic.br.operationsite.model.UserDetailModel -import com.casic.br.operationsite.utils.GlideLoadEngine -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit -import com.casic.br.operationsite.vm.EventViewModel -import com.casic.br.operationsite.vm.UploadFileViewModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.luck.picture.lib.basic.PictureSelector -import com.luck.picture.lib.config.SelectMimeType -import com.luck.picture.lib.entity.LocalMedia -import com.luck.picture.lib.interfaces.OnResultCallbackListener -import com.pengxh.kt.lite.adapter.EditableImageAdapter -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.dp2px -import com.pengxh.kt.lite.extensions.getScreenWidth -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.timestampToCompleteDate -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialog -import com.pengxh.kt.lite.utils.SaveKeyValues -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch -import java.io.File - -class UploadEventActivity : KotlinBaseActivity() { - - private val kTag = "UploadEventActivity" - private lateinit var imageAdapter: EditableImageAdapter - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var eventViewModel: EventViewModel - private val context = this - private val marginOffset by lazy { 2.dp2px(this) } - private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 - private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private var mapLocation: AMapLocation? = null - - override fun initViewBinding(): ActivityUploadActivityBinding { - return ActivityUploadActivityBinding.inflate(layoutInflater) - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - - } - }) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.uploadPersonView.text = userDetail.name - binding.personNumberView.text = userDetail.phone - } - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val url = it.data.toString() - imagePaths.add(url) - recyclerViewImages.add(url.combineImagePath()) - imageAdapter.notifyDataSetChanged() - } - } - - eventViewModel = ViewModelProvider(this)[EventViewModel::class.java] - eventViewModel.resultModel.observe(this) { - if (it.code == 200) { - finish() - } - } - - //左右边距 - val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) - binding.addImageRecyclerView.addItemDecoration( - RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) - ) - binding.addImageRecyclerView.adapter = imageAdapter - } - - override fun onResume() { - super.onResume() - getCurrentLocation() - } - - override fun observeRequestState() { - uploadFileViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "图片上传中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - - eventViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "事件提交中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - } - - override fun initEvent() { - binding.locationImageView.setOnClickListener { getCurrentLocation() } - - imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { - override fun onAddImageClick() { - selectPicture() - } - - override fun onItemClick(position: Int) { - if (recyclerViewImages[position].isEmpty()) { - "图片加载失败,无法查看大图".show(context) - } else { - navigatePageTo(position, recyclerViewImages) - } - } - - override fun onItemLongClick(view: View?, position: Int) { - imagePaths.removeAt(position) - recyclerViewImages.removeAt(position) - imageAdapter.notifyDataSetChanged() - } - }) - - binding.siteEditView.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - - } - - override fun afterTextChanged(s: Editable?) { - val text = s.toString().trim() - binding.inputLengthView.text = String.format("${text.length}/100") - if (text.length > 100) { - binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) - "现场情况字符不能超过100个字符".show(context) - } else { - binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - - binding.uploadEventButton.setOnClickListener { - if (binding.eventNameView.text.isNullOrBlank()) { - "请输入事件名称".show(this) - return@setOnClickListener - } - - if (binding.siteEditView.text.isNullOrBlank()) { - "请输入事件简要描述".show(this) - return@setOnClickListener - } - - val imageModels = ArrayList() - imagePaths.forEach { url -> - imageModels.add(ImageModel("", "", url)) - } - - eventViewModel.addEvent( - this, - binding.eventNameView.text.toString(), - binding.personNumberView.text.toString(), - mapLocation?.longitude.toString(), - System.currentTimeMillis().timestampToCompleteDate(), - binding.siteEditView.text.toString(), - "", - binding.uploadPersonView.text.toString(), - imageModels.toTypedArray(), - mapLocation?.latitude.toString(), - ) - } - } - - private fun selectPicture() { - BottomActionSheet.Builder().setContext(this).setActionItemTitle(listOf("拍照", "相册")) - .setItemTextColor(R.color.mainThemeColor.convertColor(this)) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> { - PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return - } - analyticalSelectResults(result.first()) - } - - override fun onCancel() { - - } - }) - } - - 1 -> { - PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) - .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) - .setImageEngine(GlideLoadEngine.get) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } - } - } - - override fun onCancel() { - - } - }) - } - } - } - }).build().show() - } - - private fun getCurrentLocation() { - binding.eventLocationView.text = "定位中..." - LocationKit.getCurrentLocation(this, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - binding.eventLocationView.text = "定位失败" - binding.eventLocationView.setTextColor(R.color.redTextColor.convertColor(context)) - } else { - mapLocation = aMapLocation - binding.eventLocationView.text = aMapLocation.address - binding.eventLocationView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - } - - private fun analyticalSelectResults(result: LocalMedia) { - //压缩图片后上传 - result.realPath.compressImage(this, object : OnImageCompressListener { - override fun onSuccess(file: File) { - //上传图片 - uploadFileViewModel.uploadImage(context, file) - } - - override fun onError(e: Throwable) { - e.printStackTrace() - } - }) - } -} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt deleted file mode 100644 index 274637f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt +++ /dev/null @@ -1,293 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation -import com.casic.br.operationsite.R -import com.casic.br.operationsite.callback.OnImageCompressListener -import com.casic.br.operationsite.databinding.ActivityUploadActivityBinding -import com.casic.br.operationsite.extensions.combineImagePath -import com.casic.br.operationsite.extensions.compressImage -import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.ImageModel -import com.casic.br.operationsite.model.UserDetailModel -import com.casic.br.operationsite.utils.GlideLoadEngine -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit -import com.casic.br.operationsite.vm.EventViewModel -import com.casic.br.operationsite.vm.UploadFileViewModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.luck.picture.lib.basic.PictureSelector -import com.luck.picture.lib.config.SelectMimeType -import com.luck.picture.lib.entity.LocalMedia -import com.luck.picture.lib.interfaces.OnResultCallbackListener -import com.pengxh.kt.lite.adapter.EditableImageAdapter -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.dp2px -import com.pengxh.kt.lite.extensions.getScreenWidth -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.timestampToCompleteDate -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialog -import com.pengxh.kt.lite.utils.SaveKeyValues -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch -import java.io.File - -class UploadEventActivity : KotlinBaseActivity() { - - private val kTag = "UploadEventActivity" - private lateinit var imageAdapter: EditableImageAdapter - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var eventViewModel: EventViewModel - private val context = this - private val marginOffset by lazy { 2.dp2px(this) } - private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 - private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private var mapLocation: AMapLocation? = null - - override fun initViewBinding(): ActivityUploadActivityBinding { - return ActivityUploadActivityBinding.inflate(layoutInflater) - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - - } - }) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.uploadPersonView.text = userDetail.name - binding.personNumberView.text = userDetail.phone - } - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val url = it.data.toString() - imagePaths.add(url) - recyclerViewImages.add(url.combineImagePath()) - imageAdapter.notifyDataSetChanged() - } - } - - eventViewModel = ViewModelProvider(this)[EventViewModel::class.java] - eventViewModel.resultModel.observe(this) { - if (it.code == 200) { - finish() - } - } - - //左右边距 - val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) - binding.addImageRecyclerView.addItemDecoration( - RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) - ) - binding.addImageRecyclerView.adapter = imageAdapter - } - - override fun onResume() { - super.onResume() - getCurrentLocation() - } - - override fun observeRequestState() { - uploadFileViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "图片上传中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - - eventViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "事件提交中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - } - - override fun initEvent() { - binding.locationImageView.setOnClickListener { getCurrentLocation() } - - imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { - override fun onAddImageClick() { - selectPicture() - } - - override fun onItemClick(position: Int) { - if (recyclerViewImages[position].isEmpty()) { - "图片加载失败,无法查看大图".show(context) - } else { - navigatePageTo(position, recyclerViewImages) - } - } - - override fun onItemLongClick(view: View?, position: Int) { - imagePaths.removeAt(position) - recyclerViewImages.removeAt(position) - imageAdapter.notifyDataSetChanged() - } - }) - - binding.siteEditView.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - - } - - override fun afterTextChanged(s: Editable?) { - val text = s.toString().trim() - binding.inputLengthView.text = String.format("${text.length}/100") - if (text.length > 100) { - binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) - "现场情况字符不能超过100个字符".show(context) - } else { - binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - - binding.uploadEventButton.setOnClickListener { - if (binding.eventNameView.text.isNullOrBlank()) { - "请输入事件名称".show(this) - return@setOnClickListener - } - - if (binding.siteEditView.text.isNullOrBlank()) { - "请输入事件简要描述".show(this) - return@setOnClickListener - } - - val imageModels = ArrayList() - imagePaths.forEach { url -> - imageModels.add(ImageModel("", "", url)) - } - - eventViewModel.addEvent( - this, - binding.eventNameView.text.toString(), - binding.personNumberView.text.toString(), - mapLocation?.longitude.toString(), - System.currentTimeMillis().timestampToCompleteDate(), - binding.siteEditView.text.toString(), - "", - binding.uploadPersonView.text.toString(), - imageModels.toTypedArray(), - mapLocation?.latitude.toString(), - ) - } - } - - private fun selectPicture() { - BottomActionSheet.Builder().setContext(this).setActionItemTitle(listOf("拍照", "相册")) - .setItemTextColor(R.color.mainThemeColor.convertColor(this)) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> { - PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return - } - analyticalSelectResults(result.first()) - } - - override fun onCancel() { - - } - }) - } - - 1 -> { - PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) - .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) - .setImageEngine(GlideLoadEngine.get) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } - } - } - - override fun onCancel() { - - } - }) - } - } - } - }).build().show() - } - - private fun getCurrentLocation() { - binding.eventLocationView.text = "定位中..." - LocationKit.getCurrentLocation(this, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - binding.eventLocationView.text = "定位失败" - binding.eventLocationView.setTextColor(R.color.redTextColor.convertColor(context)) - } else { - mapLocation = aMapLocation - binding.eventLocationView.text = aMapLocation.address - binding.eventLocationView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - } - - private fun analyticalSelectResults(result: LocalMedia) { - //压缩图片后上传 - result.realPath.compressImage(this, object : OnImageCompressListener { - override fun onSuccess(file: File) { - //上传图片 - uploadFileViewModel.uploadImage(context, file) - } - - override fun onError(e: Throwable) { - e.printStackTrace() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt index 94d87d9..eb25cb8 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt @@ -337,10 +337,6 @@ navigatePageTo() } - binding.uploadMenuItem.setOnClickListener { - navigatePageTo() - } - binding.applyMenuItem.setOnClickListener { navigatePageTo() } diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt deleted file mode 100644 index 274637f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt +++ /dev/null @@ -1,293 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation -import com.casic.br.operationsite.R -import com.casic.br.operationsite.callback.OnImageCompressListener -import com.casic.br.operationsite.databinding.ActivityUploadActivityBinding -import com.casic.br.operationsite.extensions.combineImagePath -import com.casic.br.operationsite.extensions.compressImage -import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.ImageModel -import com.casic.br.operationsite.model.UserDetailModel -import com.casic.br.operationsite.utils.GlideLoadEngine -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit -import com.casic.br.operationsite.vm.EventViewModel -import com.casic.br.operationsite.vm.UploadFileViewModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.luck.picture.lib.basic.PictureSelector -import com.luck.picture.lib.config.SelectMimeType -import com.luck.picture.lib.entity.LocalMedia -import com.luck.picture.lib.interfaces.OnResultCallbackListener -import com.pengxh.kt.lite.adapter.EditableImageAdapter -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.dp2px -import com.pengxh.kt.lite.extensions.getScreenWidth -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.timestampToCompleteDate -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialog -import com.pengxh.kt.lite.utils.SaveKeyValues -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch -import java.io.File - -class UploadEventActivity : KotlinBaseActivity() { - - private val kTag = "UploadEventActivity" - private lateinit var imageAdapter: EditableImageAdapter - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var eventViewModel: EventViewModel - private val context = this - private val marginOffset by lazy { 2.dp2px(this) } - private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 - private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private var mapLocation: AMapLocation? = null - - override fun initViewBinding(): ActivityUploadActivityBinding { - return ActivityUploadActivityBinding.inflate(layoutInflater) - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - - } - }) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.uploadPersonView.text = userDetail.name - binding.personNumberView.text = userDetail.phone - } - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val url = it.data.toString() - imagePaths.add(url) - recyclerViewImages.add(url.combineImagePath()) - imageAdapter.notifyDataSetChanged() - } - } - - eventViewModel = ViewModelProvider(this)[EventViewModel::class.java] - eventViewModel.resultModel.observe(this) { - if (it.code == 200) { - finish() - } - } - - //左右边距 - val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) - binding.addImageRecyclerView.addItemDecoration( - RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) - ) - binding.addImageRecyclerView.adapter = imageAdapter - } - - override fun onResume() { - super.onResume() - getCurrentLocation() - } - - override fun observeRequestState() { - uploadFileViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "图片上传中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - - eventViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "事件提交中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - } - - override fun initEvent() { - binding.locationImageView.setOnClickListener { getCurrentLocation() } - - imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { - override fun onAddImageClick() { - selectPicture() - } - - override fun onItemClick(position: Int) { - if (recyclerViewImages[position].isEmpty()) { - "图片加载失败,无法查看大图".show(context) - } else { - navigatePageTo(position, recyclerViewImages) - } - } - - override fun onItemLongClick(view: View?, position: Int) { - imagePaths.removeAt(position) - recyclerViewImages.removeAt(position) - imageAdapter.notifyDataSetChanged() - } - }) - - binding.siteEditView.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - - } - - override fun afterTextChanged(s: Editable?) { - val text = s.toString().trim() - binding.inputLengthView.text = String.format("${text.length}/100") - if (text.length > 100) { - binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) - "现场情况字符不能超过100个字符".show(context) - } else { - binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - - binding.uploadEventButton.setOnClickListener { - if (binding.eventNameView.text.isNullOrBlank()) { - "请输入事件名称".show(this) - return@setOnClickListener - } - - if (binding.siteEditView.text.isNullOrBlank()) { - "请输入事件简要描述".show(this) - return@setOnClickListener - } - - val imageModels = ArrayList() - imagePaths.forEach { url -> - imageModels.add(ImageModel("", "", url)) - } - - eventViewModel.addEvent( - this, - binding.eventNameView.text.toString(), - binding.personNumberView.text.toString(), - mapLocation?.longitude.toString(), - System.currentTimeMillis().timestampToCompleteDate(), - binding.siteEditView.text.toString(), - "", - binding.uploadPersonView.text.toString(), - imageModels.toTypedArray(), - mapLocation?.latitude.toString(), - ) - } - } - - private fun selectPicture() { - BottomActionSheet.Builder().setContext(this).setActionItemTitle(listOf("拍照", "相册")) - .setItemTextColor(R.color.mainThemeColor.convertColor(this)) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> { - PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return - } - analyticalSelectResults(result.first()) - } - - override fun onCancel() { - - } - }) - } - - 1 -> { - PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) - .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) - .setImageEngine(GlideLoadEngine.get) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } - } - } - - override fun onCancel() { - - } - }) - } - } - } - }).build().show() - } - - private fun getCurrentLocation() { - binding.eventLocationView.text = "定位中..." - LocationKit.getCurrentLocation(this, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - binding.eventLocationView.text = "定位失败" - binding.eventLocationView.setTextColor(R.color.redTextColor.convertColor(context)) - } else { - mapLocation = aMapLocation - binding.eventLocationView.text = aMapLocation.address - binding.eventLocationView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - } - - private fun analyticalSelectResults(result: LocalMedia) { - //压缩图片后上传 - result.realPath.compressImage(this, object : OnImageCompressListener { - override fun onSuccess(file: File) { - //上传图片 - uploadFileViewModel.uploadImage(context, file) - } - - override fun onError(e: Throwable) { - e.printStackTrace() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt index 94d87d9..eb25cb8 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt @@ -337,10 +337,6 @@ navigatePageTo() } - binding.uploadMenuItem.setOnClickListener { - navigatePageTo() - } - binding.applyMenuItem.setOnClickListener { navigatePageTo() } diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt index bc8b866..10e9a26 100644 --- a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt @@ -1,6 +1,5 @@ package com.casic.br.operationsite.vm -import androidx.lifecycle.MutableLiveData import com.casic.br.operationsite.extensions.getResponseCode import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.retrofit.RetrofitServiceManager @@ -9,33 +8,28 @@ import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.SaveKeyValues class UserDetailViewModel : BaseViewModel() { private val gson = Gson() - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - fun getUserDetail() = launch({ + loadState.value = LoadState.Loading val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } + val responseCode = response.getResponseCode() + if (responseCode == 200) { + val userDetail = gson.fromJson( + response, object : TypeToken() {}.type + ) + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, userDetail.data.name) + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail } }, { + loadState.value = LoadState.Fail it.printStackTrace() }) } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt deleted file mode 100644 index 274637f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt +++ /dev/null @@ -1,293 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation -import com.casic.br.operationsite.R -import com.casic.br.operationsite.callback.OnImageCompressListener -import com.casic.br.operationsite.databinding.ActivityUploadActivityBinding -import com.casic.br.operationsite.extensions.combineImagePath -import com.casic.br.operationsite.extensions.compressImage -import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.ImageModel -import com.casic.br.operationsite.model.UserDetailModel -import com.casic.br.operationsite.utils.GlideLoadEngine -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit -import com.casic.br.operationsite.vm.EventViewModel -import com.casic.br.operationsite.vm.UploadFileViewModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.luck.picture.lib.basic.PictureSelector -import com.luck.picture.lib.config.SelectMimeType -import com.luck.picture.lib.entity.LocalMedia -import com.luck.picture.lib.interfaces.OnResultCallbackListener -import com.pengxh.kt.lite.adapter.EditableImageAdapter -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.dp2px -import com.pengxh.kt.lite.extensions.getScreenWidth -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.timestampToCompleteDate -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialog -import com.pengxh.kt.lite.utils.SaveKeyValues -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch -import java.io.File - -class UploadEventActivity : KotlinBaseActivity() { - - private val kTag = "UploadEventActivity" - private lateinit var imageAdapter: EditableImageAdapter - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var eventViewModel: EventViewModel - private val context = this - private val marginOffset by lazy { 2.dp2px(this) } - private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 - private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private var mapLocation: AMapLocation? = null - - override fun initViewBinding(): ActivityUploadActivityBinding { - return ActivityUploadActivityBinding.inflate(layoutInflater) - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - - } - }) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.uploadPersonView.text = userDetail.name - binding.personNumberView.text = userDetail.phone - } - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val url = it.data.toString() - imagePaths.add(url) - recyclerViewImages.add(url.combineImagePath()) - imageAdapter.notifyDataSetChanged() - } - } - - eventViewModel = ViewModelProvider(this)[EventViewModel::class.java] - eventViewModel.resultModel.observe(this) { - if (it.code == 200) { - finish() - } - } - - //左右边距 - val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) - binding.addImageRecyclerView.addItemDecoration( - RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) - ) - binding.addImageRecyclerView.adapter = imageAdapter - } - - override fun onResume() { - super.onResume() - getCurrentLocation() - } - - override fun observeRequestState() { - uploadFileViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "图片上传中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - - eventViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "事件提交中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - } - - override fun initEvent() { - binding.locationImageView.setOnClickListener { getCurrentLocation() } - - imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { - override fun onAddImageClick() { - selectPicture() - } - - override fun onItemClick(position: Int) { - if (recyclerViewImages[position].isEmpty()) { - "图片加载失败,无法查看大图".show(context) - } else { - navigatePageTo(position, recyclerViewImages) - } - } - - override fun onItemLongClick(view: View?, position: Int) { - imagePaths.removeAt(position) - recyclerViewImages.removeAt(position) - imageAdapter.notifyDataSetChanged() - } - }) - - binding.siteEditView.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - - } - - override fun afterTextChanged(s: Editable?) { - val text = s.toString().trim() - binding.inputLengthView.text = String.format("${text.length}/100") - if (text.length > 100) { - binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) - "现场情况字符不能超过100个字符".show(context) - } else { - binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - - binding.uploadEventButton.setOnClickListener { - if (binding.eventNameView.text.isNullOrBlank()) { - "请输入事件名称".show(this) - return@setOnClickListener - } - - if (binding.siteEditView.text.isNullOrBlank()) { - "请输入事件简要描述".show(this) - return@setOnClickListener - } - - val imageModels = ArrayList() - imagePaths.forEach { url -> - imageModels.add(ImageModel("", "", url)) - } - - eventViewModel.addEvent( - this, - binding.eventNameView.text.toString(), - binding.personNumberView.text.toString(), - mapLocation?.longitude.toString(), - System.currentTimeMillis().timestampToCompleteDate(), - binding.siteEditView.text.toString(), - "", - binding.uploadPersonView.text.toString(), - imageModels.toTypedArray(), - mapLocation?.latitude.toString(), - ) - } - } - - private fun selectPicture() { - BottomActionSheet.Builder().setContext(this).setActionItemTitle(listOf("拍照", "相册")) - .setItemTextColor(R.color.mainThemeColor.convertColor(this)) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> { - PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return - } - analyticalSelectResults(result.first()) - } - - override fun onCancel() { - - } - }) - } - - 1 -> { - PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) - .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) - .setImageEngine(GlideLoadEngine.get) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } - } - } - - override fun onCancel() { - - } - }) - } - } - } - }).build().show() - } - - private fun getCurrentLocation() { - binding.eventLocationView.text = "定位中..." - LocationKit.getCurrentLocation(this, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - binding.eventLocationView.text = "定位失败" - binding.eventLocationView.setTextColor(R.color.redTextColor.convertColor(context)) - } else { - mapLocation = aMapLocation - binding.eventLocationView.text = aMapLocation.address - binding.eventLocationView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - } - - private fun analyticalSelectResults(result: LocalMedia) { - //压缩图片后上传 - result.realPath.compressImage(this, object : OnImageCompressListener { - override fun onSuccess(file: File) { - //上传图片 - uploadFileViewModel.uploadImage(context, file) - } - - override fun onError(e: Throwable) { - e.printStackTrace() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt index 94d87d9..eb25cb8 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt @@ -337,10 +337,6 @@ navigatePageTo() } - binding.uploadMenuItem.setOnClickListener { - navigatePageTo() - } - binding.applyMenuItem.setOnClickListener { navigatePageTo() } diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt index bc8b866..10e9a26 100644 --- a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt @@ -1,6 +1,5 @@ package com.casic.br.operationsite.vm -import androidx.lifecycle.MutableLiveData import com.casic.br.operationsite.extensions.getResponseCode import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.retrofit.RetrofitServiceManager @@ -9,33 +8,28 @@ import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.SaveKeyValues class UserDetailViewModel : BaseViewModel() { private val gson = Gson() - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - fun getUserDetail() = launch({ + loadState.value = LoadState.Loading val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } + val responseCode = response.getResponseCode() + if (responseCode == 200) { + val userDetail = gson.fromJson( + response, object : TypeToken() {}.type + ) + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, userDetail.data.name) + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail } }, { + loadState.value = LoadState.Fail it.printStackTrace() }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt index 1bdbcb4..a7edb5c 100644 --- a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -20,7 +20,7 @@ import com.amap.api.services.geocoder.RegeocodeQuery import com.amap.api.services.geocoder.RegeocodeResult import com.casic.br.operationsite.R -import com.pengxh.kt.lite.extensions.breakLine +import com.pengxh.kt.lite.extensions.wrapLine class CenterMarkerView(private val context: Context, private var aMap: AMap) { private lateinit var centerMarker: Marker @@ -46,7 +46,7 @@ if (code == 1000) { //手动换行 val address = regeocodeResult.regeocodeAddress.formatAddress - locationView.text = address.breakLine(22) + locationView.text = address.wrapLine(22) } } diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt deleted file mode 100644 index 274637f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt +++ /dev/null @@ -1,293 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation -import com.casic.br.operationsite.R -import com.casic.br.operationsite.callback.OnImageCompressListener -import com.casic.br.operationsite.databinding.ActivityUploadActivityBinding -import com.casic.br.operationsite.extensions.combineImagePath -import com.casic.br.operationsite.extensions.compressImage -import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.ImageModel -import com.casic.br.operationsite.model.UserDetailModel -import com.casic.br.operationsite.utils.GlideLoadEngine -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit -import com.casic.br.operationsite.vm.EventViewModel -import com.casic.br.operationsite.vm.UploadFileViewModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.luck.picture.lib.basic.PictureSelector -import com.luck.picture.lib.config.SelectMimeType -import com.luck.picture.lib.entity.LocalMedia -import com.luck.picture.lib.interfaces.OnResultCallbackListener -import com.pengxh.kt.lite.adapter.EditableImageAdapter -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.dp2px -import com.pengxh.kt.lite.extensions.getScreenWidth -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.timestampToCompleteDate -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialog -import com.pengxh.kt.lite.utils.SaveKeyValues -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch -import java.io.File - -class UploadEventActivity : KotlinBaseActivity() { - - private val kTag = "UploadEventActivity" - private lateinit var imageAdapter: EditableImageAdapter - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var eventViewModel: EventViewModel - private val context = this - private val marginOffset by lazy { 2.dp2px(this) } - private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 - private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private var mapLocation: AMapLocation? = null - - override fun initViewBinding(): ActivityUploadActivityBinding { - return ActivityUploadActivityBinding.inflate(layoutInflater) - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - - } - }) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.uploadPersonView.text = userDetail.name - binding.personNumberView.text = userDetail.phone - } - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val url = it.data.toString() - imagePaths.add(url) - recyclerViewImages.add(url.combineImagePath()) - imageAdapter.notifyDataSetChanged() - } - } - - eventViewModel = ViewModelProvider(this)[EventViewModel::class.java] - eventViewModel.resultModel.observe(this) { - if (it.code == 200) { - finish() - } - } - - //左右边距 - val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) - binding.addImageRecyclerView.addItemDecoration( - RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) - ) - binding.addImageRecyclerView.adapter = imageAdapter - } - - override fun onResume() { - super.onResume() - getCurrentLocation() - } - - override fun observeRequestState() { - uploadFileViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "图片上传中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - - eventViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "事件提交中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - } - - override fun initEvent() { - binding.locationImageView.setOnClickListener { getCurrentLocation() } - - imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { - override fun onAddImageClick() { - selectPicture() - } - - override fun onItemClick(position: Int) { - if (recyclerViewImages[position].isEmpty()) { - "图片加载失败,无法查看大图".show(context) - } else { - navigatePageTo(position, recyclerViewImages) - } - } - - override fun onItemLongClick(view: View?, position: Int) { - imagePaths.removeAt(position) - recyclerViewImages.removeAt(position) - imageAdapter.notifyDataSetChanged() - } - }) - - binding.siteEditView.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - - } - - override fun afterTextChanged(s: Editable?) { - val text = s.toString().trim() - binding.inputLengthView.text = String.format("${text.length}/100") - if (text.length > 100) { - binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) - "现场情况字符不能超过100个字符".show(context) - } else { - binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - - binding.uploadEventButton.setOnClickListener { - if (binding.eventNameView.text.isNullOrBlank()) { - "请输入事件名称".show(this) - return@setOnClickListener - } - - if (binding.siteEditView.text.isNullOrBlank()) { - "请输入事件简要描述".show(this) - return@setOnClickListener - } - - val imageModels = ArrayList() - imagePaths.forEach { url -> - imageModels.add(ImageModel("", "", url)) - } - - eventViewModel.addEvent( - this, - binding.eventNameView.text.toString(), - binding.personNumberView.text.toString(), - mapLocation?.longitude.toString(), - System.currentTimeMillis().timestampToCompleteDate(), - binding.siteEditView.text.toString(), - "", - binding.uploadPersonView.text.toString(), - imageModels.toTypedArray(), - mapLocation?.latitude.toString(), - ) - } - } - - private fun selectPicture() { - BottomActionSheet.Builder().setContext(this).setActionItemTitle(listOf("拍照", "相册")) - .setItemTextColor(R.color.mainThemeColor.convertColor(this)) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> { - PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return - } - analyticalSelectResults(result.first()) - } - - override fun onCancel() { - - } - }) - } - - 1 -> { - PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) - .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) - .setImageEngine(GlideLoadEngine.get) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } - } - } - - override fun onCancel() { - - } - }) - } - } - } - }).build().show() - } - - private fun getCurrentLocation() { - binding.eventLocationView.text = "定位中..." - LocationKit.getCurrentLocation(this, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - binding.eventLocationView.text = "定位失败" - binding.eventLocationView.setTextColor(R.color.redTextColor.convertColor(context)) - } else { - mapLocation = aMapLocation - binding.eventLocationView.text = aMapLocation.address - binding.eventLocationView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - } - - private fun analyticalSelectResults(result: LocalMedia) { - //压缩图片后上传 - result.realPath.compressImage(this, object : OnImageCompressListener { - override fun onSuccess(file: File) { - //上传图片 - uploadFileViewModel.uploadImage(context, file) - } - - override fun onError(e: Throwable) { - e.printStackTrace() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt index 94d87d9..eb25cb8 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt @@ -337,10 +337,6 @@ navigatePageTo() } - binding.uploadMenuItem.setOnClickListener { - navigatePageTo() - } - binding.applyMenuItem.setOnClickListener { navigatePageTo() } diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt index bc8b866..10e9a26 100644 --- a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt @@ -1,6 +1,5 @@ package com.casic.br.operationsite.vm -import androidx.lifecycle.MutableLiveData import com.casic.br.operationsite.extensions.getResponseCode import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.retrofit.RetrofitServiceManager @@ -9,33 +8,28 @@ import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.SaveKeyValues class UserDetailViewModel : BaseViewModel() { private val gson = Gson() - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - fun getUserDetail() = launch({ + loadState.value = LoadState.Loading val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } + val responseCode = response.getResponseCode() + if (responseCode == 200) { + val userDetail = gson.fromJson( + response, object : TypeToken() {}.type + ) + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, userDetail.data.name) + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail } }, { + loadState.value = LoadState.Fail it.printStackTrace() }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt index 1bdbcb4..a7edb5c 100644 --- a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -20,7 +20,7 @@ import com.amap.api.services.geocoder.RegeocodeQuery import com.amap.api.services.geocoder.RegeocodeResult import com.casic.br.operationsite.R -import com.pengxh.kt.lite.extensions.breakLine +import com.pengxh.kt.lite.extensions.wrapLine class CenterMarkerView(private val context: Context, private var aMap: AMap) { private lateinit var centerMarker: Marker @@ -46,7 +46,7 @@ if (code == 1000) { //手动换行 val address = regeocodeResult.regeocodeAddress.formatAddress - locationView.text = address.breakLine(22) + locationView.text = address.wrapLine(22) } } diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index fb34d0e..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt deleted file mode 100644 index 274637f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt +++ /dev/null @@ -1,293 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation -import com.casic.br.operationsite.R -import com.casic.br.operationsite.callback.OnImageCompressListener -import com.casic.br.operationsite.databinding.ActivityUploadActivityBinding -import com.casic.br.operationsite.extensions.combineImagePath -import com.casic.br.operationsite.extensions.compressImage -import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.ImageModel -import com.casic.br.operationsite.model.UserDetailModel -import com.casic.br.operationsite.utils.GlideLoadEngine -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit -import com.casic.br.operationsite.vm.EventViewModel -import com.casic.br.operationsite.vm.UploadFileViewModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.luck.picture.lib.basic.PictureSelector -import com.luck.picture.lib.config.SelectMimeType -import com.luck.picture.lib.entity.LocalMedia -import com.luck.picture.lib.interfaces.OnResultCallbackListener -import com.pengxh.kt.lite.adapter.EditableImageAdapter -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.dp2px -import com.pengxh.kt.lite.extensions.getScreenWidth -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.timestampToCompleteDate -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialog -import com.pengxh.kt.lite.utils.SaveKeyValues -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch -import java.io.File - -class UploadEventActivity : KotlinBaseActivity() { - - private val kTag = "UploadEventActivity" - private lateinit var imageAdapter: EditableImageAdapter - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var eventViewModel: EventViewModel - private val context = this - private val marginOffset by lazy { 2.dp2px(this) } - private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 - private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private var mapLocation: AMapLocation? = null - - override fun initViewBinding(): ActivityUploadActivityBinding { - return ActivityUploadActivityBinding.inflate(layoutInflater) - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - - } - }) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.uploadPersonView.text = userDetail.name - binding.personNumberView.text = userDetail.phone - } - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val url = it.data.toString() - imagePaths.add(url) - recyclerViewImages.add(url.combineImagePath()) - imageAdapter.notifyDataSetChanged() - } - } - - eventViewModel = ViewModelProvider(this)[EventViewModel::class.java] - eventViewModel.resultModel.observe(this) { - if (it.code == 200) { - finish() - } - } - - //左右边距 - val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) - binding.addImageRecyclerView.addItemDecoration( - RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) - ) - binding.addImageRecyclerView.adapter = imageAdapter - } - - override fun onResume() { - super.onResume() - getCurrentLocation() - } - - override fun observeRequestState() { - uploadFileViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "图片上传中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - - eventViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "事件提交中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - } - - override fun initEvent() { - binding.locationImageView.setOnClickListener { getCurrentLocation() } - - imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { - override fun onAddImageClick() { - selectPicture() - } - - override fun onItemClick(position: Int) { - if (recyclerViewImages[position].isEmpty()) { - "图片加载失败,无法查看大图".show(context) - } else { - navigatePageTo(position, recyclerViewImages) - } - } - - override fun onItemLongClick(view: View?, position: Int) { - imagePaths.removeAt(position) - recyclerViewImages.removeAt(position) - imageAdapter.notifyDataSetChanged() - } - }) - - binding.siteEditView.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - - } - - override fun afterTextChanged(s: Editable?) { - val text = s.toString().trim() - binding.inputLengthView.text = String.format("${text.length}/100") - if (text.length > 100) { - binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) - "现场情况字符不能超过100个字符".show(context) - } else { - binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - - binding.uploadEventButton.setOnClickListener { - if (binding.eventNameView.text.isNullOrBlank()) { - "请输入事件名称".show(this) - return@setOnClickListener - } - - if (binding.siteEditView.text.isNullOrBlank()) { - "请输入事件简要描述".show(this) - return@setOnClickListener - } - - val imageModels = ArrayList() - imagePaths.forEach { url -> - imageModels.add(ImageModel("", "", url)) - } - - eventViewModel.addEvent( - this, - binding.eventNameView.text.toString(), - binding.personNumberView.text.toString(), - mapLocation?.longitude.toString(), - System.currentTimeMillis().timestampToCompleteDate(), - binding.siteEditView.text.toString(), - "", - binding.uploadPersonView.text.toString(), - imageModels.toTypedArray(), - mapLocation?.latitude.toString(), - ) - } - } - - private fun selectPicture() { - BottomActionSheet.Builder().setContext(this).setActionItemTitle(listOf("拍照", "相册")) - .setItemTextColor(R.color.mainThemeColor.convertColor(this)) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> { - PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return - } - analyticalSelectResults(result.first()) - } - - override fun onCancel() { - - } - }) - } - - 1 -> { - PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) - .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) - .setImageEngine(GlideLoadEngine.get) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } - } - } - - override fun onCancel() { - - } - }) - } - } - } - }).build().show() - } - - private fun getCurrentLocation() { - binding.eventLocationView.text = "定位中..." - LocationKit.getCurrentLocation(this, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - binding.eventLocationView.text = "定位失败" - binding.eventLocationView.setTextColor(R.color.redTextColor.convertColor(context)) - } else { - mapLocation = aMapLocation - binding.eventLocationView.text = aMapLocation.address - binding.eventLocationView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - } - - private fun analyticalSelectResults(result: LocalMedia) { - //压缩图片后上传 - result.realPath.compressImage(this, object : OnImageCompressListener { - override fun onSuccess(file: File) { - //上传图片 - uploadFileViewModel.uploadImage(context, file) - } - - override fun onError(e: Throwable) { - e.printStackTrace() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt index 94d87d9..eb25cb8 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt @@ -337,10 +337,6 @@ navigatePageTo() } - binding.uploadMenuItem.setOnClickListener { - navigatePageTo() - } - binding.applyMenuItem.setOnClickListener { navigatePageTo() } diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt index bc8b866..10e9a26 100644 --- a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt @@ -1,6 +1,5 @@ package com.casic.br.operationsite.vm -import androidx.lifecycle.MutableLiveData import com.casic.br.operationsite.extensions.getResponseCode import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.retrofit.RetrofitServiceManager @@ -9,33 +8,28 @@ import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.SaveKeyValues class UserDetailViewModel : BaseViewModel() { private val gson = Gson() - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - fun getUserDetail() = launch({ + loadState.value = LoadState.Loading val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } + val responseCode = response.getResponseCode() + if (responseCode == 200) { + val userDetail = gson.fromJson( + response, object : TypeToken() {}.type + ) + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, userDetail.data.name) + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail } }, { + loadState.value = LoadState.Fail it.printStackTrace() }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt index 1bdbcb4..a7edb5c 100644 --- a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -20,7 +20,7 @@ import com.amap.api.services.geocoder.RegeocodeQuery import com.amap.api.services.geocoder.RegeocodeResult import com.casic.br.operationsite.R -import com.pengxh.kt.lite.extensions.breakLine +import com.pengxh.kt.lite.extensions.wrapLine class CenterMarkerView(private val context: Context, private var aMap: AMap) { private lateinit var centerMarker: Marker @@ -46,7 +46,7 @@ if (code == 1000) { //手动换行 val address = regeocodeResult.regeocodeAddress.formatAddress - locationView.text = address.breakLine(22) + locationView.text = address.wrapLine(22) } } diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index fb34d0e..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..13db468 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt deleted file mode 100644 index 274637f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt +++ /dev/null @@ -1,293 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation -import com.casic.br.operationsite.R -import com.casic.br.operationsite.callback.OnImageCompressListener -import com.casic.br.operationsite.databinding.ActivityUploadActivityBinding -import com.casic.br.operationsite.extensions.combineImagePath -import com.casic.br.operationsite.extensions.compressImage -import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.ImageModel -import com.casic.br.operationsite.model.UserDetailModel -import com.casic.br.operationsite.utils.GlideLoadEngine -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit -import com.casic.br.operationsite.vm.EventViewModel -import com.casic.br.operationsite.vm.UploadFileViewModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.luck.picture.lib.basic.PictureSelector -import com.luck.picture.lib.config.SelectMimeType -import com.luck.picture.lib.entity.LocalMedia -import com.luck.picture.lib.interfaces.OnResultCallbackListener -import com.pengxh.kt.lite.adapter.EditableImageAdapter -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.dp2px -import com.pengxh.kt.lite.extensions.getScreenWidth -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.timestampToCompleteDate -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialog -import com.pengxh.kt.lite.utils.SaveKeyValues -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch -import java.io.File - -class UploadEventActivity : KotlinBaseActivity() { - - private val kTag = "UploadEventActivity" - private lateinit var imageAdapter: EditableImageAdapter - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var eventViewModel: EventViewModel - private val context = this - private val marginOffset by lazy { 2.dp2px(this) } - private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 - private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private var mapLocation: AMapLocation? = null - - override fun initViewBinding(): ActivityUploadActivityBinding { - return ActivityUploadActivityBinding.inflate(layoutInflater) - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - - } - }) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.uploadPersonView.text = userDetail.name - binding.personNumberView.text = userDetail.phone - } - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val url = it.data.toString() - imagePaths.add(url) - recyclerViewImages.add(url.combineImagePath()) - imageAdapter.notifyDataSetChanged() - } - } - - eventViewModel = ViewModelProvider(this)[EventViewModel::class.java] - eventViewModel.resultModel.observe(this) { - if (it.code == 200) { - finish() - } - } - - //左右边距 - val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) - binding.addImageRecyclerView.addItemDecoration( - RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) - ) - binding.addImageRecyclerView.adapter = imageAdapter - } - - override fun onResume() { - super.onResume() - getCurrentLocation() - } - - override fun observeRequestState() { - uploadFileViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "图片上传中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - - eventViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "事件提交中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - } - - override fun initEvent() { - binding.locationImageView.setOnClickListener { getCurrentLocation() } - - imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { - override fun onAddImageClick() { - selectPicture() - } - - override fun onItemClick(position: Int) { - if (recyclerViewImages[position].isEmpty()) { - "图片加载失败,无法查看大图".show(context) - } else { - navigatePageTo(position, recyclerViewImages) - } - } - - override fun onItemLongClick(view: View?, position: Int) { - imagePaths.removeAt(position) - recyclerViewImages.removeAt(position) - imageAdapter.notifyDataSetChanged() - } - }) - - binding.siteEditView.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - - } - - override fun afterTextChanged(s: Editable?) { - val text = s.toString().trim() - binding.inputLengthView.text = String.format("${text.length}/100") - if (text.length > 100) { - binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) - "现场情况字符不能超过100个字符".show(context) - } else { - binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - - binding.uploadEventButton.setOnClickListener { - if (binding.eventNameView.text.isNullOrBlank()) { - "请输入事件名称".show(this) - return@setOnClickListener - } - - if (binding.siteEditView.text.isNullOrBlank()) { - "请输入事件简要描述".show(this) - return@setOnClickListener - } - - val imageModels = ArrayList() - imagePaths.forEach { url -> - imageModels.add(ImageModel("", "", url)) - } - - eventViewModel.addEvent( - this, - binding.eventNameView.text.toString(), - binding.personNumberView.text.toString(), - mapLocation?.longitude.toString(), - System.currentTimeMillis().timestampToCompleteDate(), - binding.siteEditView.text.toString(), - "", - binding.uploadPersonView.text.toString(), - imageModels.toTypedArray(), - mapLocation?.latitude.toString(), - ) - } - } - - private fun selectPicture() { - BottomActionSheet.Builder().setContext(this).setActionItemTitle(listOf("拍照", "相册")) - .setItemTextColor(R.color.mainThemeColor.convertColor(this)) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> { - PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return - } - analyticalSelectResults(result.first()) - } - - override fun onCancel() { - - } - }) - } - - 1 -> { - PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) - .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) - .setImageEngine(GlideLoadEngine.get) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } - } - } - - override fun onCancel() { - - } - }) - } - } - } - }).build().show() - } - - private fun getCurrentLocation() { - binding.eventLocationView.text = "定位中..." - LocationKit.getCurrentLocation(this, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - binding.eventLocationView.text = "定位失败" - binding.eventLocationView.setTextColor(R.color.redTextColor.convertColor(context)) - } else { - mapLocation = aMapLocation - binding.eventLocationView.text = aMapLocation.address - binding.eventLocationView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - } - - private fun analyticalSelectResults(result: LocalMedia) { - //压缩图片后上传 - result.realPath.compressImage(this, object : OnImageCompressListener { - override fun onSuccess(file: File) { - //上传图片 - uploadFileViewModel.uploadImage(context, file) - } - - override fun onError(e: Throwable) { - e.printStackTrace() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt index 94d87d9..eb25cb8 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt @@ -337,10 +337,6 @@ navigatePageTo() } - binding.uploadMenuItem.setOnClickListener { - navigatePageTo() - } - binding.applyMenuItem.setOnClickListener { navigatePageTo() } diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt index bc8b866..10e9a26 100644 --- a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt @@ -1,6 +1,5 @@ package com.casic.br.operationsite.vm -import androidx.lifecycle.MutableLiveData import com.casic.br.operationsite.extensions.getResponseCode import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.retrofit.RetrofitServiceManager @@ -9,33 +8,28 @@ import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.SaveKeyValues class UserDetailViewModel : BaseViewModel() { private val gson = Gson() - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - fun getUserDetail() = launch({ + loadState.value = LoadState.Loading val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } + val responseCode = response.getResponseCode() + if (responseCode == 200) { + val userDetail = gson.fromJson( + response, object : TypeToken() {}.type + ) + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, userDetail.data.name) + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail } }, { + loadState.value = LoadState.Fail it.printStackTrace() }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt index 1bdbcb4..a7edb5c 100644 --- a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -20,7 +20,7 @@ import com.amap.api.services.geocoder.RegeocodeQuery import com.amap.api.services.geocoder.RegeocodeResult import com.casic.br.operationsite.R -import com.pengxh.kt.lite.extensions.breakLine +import com.pengxh.kt.lite.extensions.wrapLine class CenterMarkerView(private val context: Context, private var aMap: AMap) { private lateinit var centerMarker: Marker @@ -46,7 +46,7 @@ if (code == 1000) { //手动换行 val address = regeocodeResult.regeocodeAddress.formatAddress - locationView.text = address.breakLine(22) + locationView.text = address.wrapLine(22) } } diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index fb34d0e..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..13db468 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml index 8e06df7..13d10ed 100644 --- a/app/src/main/res/layout/activity_alarm_list.xml +++ b/app/src/main/res/layout/activity_alarm_list.xml @@ -1,7 +1,6 @@ - + app:fabSize="normal" /> \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c9a928a..1130fbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ defaultConfig { applicationId "com.casic.br.operationsite" - minSdkVersion 23 + minSdkVersion 26 targetSdkVersion 33 versionCode 1090 versionName "1.0.9.0" @@ -63,7 +63,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') //基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.1' + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.4' implementation 'androidx.core:core-ktx:1.9.0' def base_version = "1.6.1" implementation "androidx.appcompat:appcompat:${base_version}" @@ -121,6 +121,6 @@ implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' //更多ijk的编码支持 implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' - //悬浮按钮 - implementation 'com.github.clans:fab:1.6.4' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee67360..8f6344c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.OperationSite" android:usesCleartextTraffic="true"> - - + android:theme="@style/Theme.CustomActivityAnimation" /> diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..2144259 --- /dev/null +++ b/app/src/main/ic_launcher-playstore.png Binary files differ diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index 8b23c82..d3c20a7 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -55,7 +55,7 @@ override fun onDestroy() { super.onDestroy() - tcpClient.stop() + tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 4f8635b..e0b3c49 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -58,7 +58,7 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" const val HELMET_VIDEO_APP_KEY = "fe80b2f021644b1b8c77fda743a83670" const val HELMET_VIDEO_SECRET_KEY = "8771ea6e931d4db646a26f67bcb89909" diff --git a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt index 8cd5125..febd34d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/AlarmListActivity.kt @@ -130,7 +130,7 @@ } binding.recyclerView.adapter = alarmAdapter binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) + RecyclerViewItemDivider(0f, 0f, Color.LTGRAY) ) } } diff --git a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt index f8f11d4..f64b4f2 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt @@ -1,22 +1,16 @@ package com.casic.br.operationsite.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.R import com.casic.br.operationsite.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show @@ -29,13 +23,14 @@ class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() binding.leftBackView.setOnClickListener { finish() } } @@ -55,117 +50,85 @@ return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index decb588..0d5bef3 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -15,11 +15,8 @@ import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding import com.casic.br.operationsite.extensions.compressImage import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia @@ -67,13 +64,9 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.operatorView.setText(userDetail.name) + val userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME_KEY, "") as String + if (userName.isNotBlank()) { + binding.operatorView.setText(userName) } //左右边距 diff --git a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt index 5f3585f..d1e830d 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/LoginActivity.kt @@ -89,11 +89,7 @@ loginViewModel.enterResultModel.observe(this) { loginResult -> if (loginResult.code == 200) { AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ userDetailViewModel.getUserDetail() - //验证成功登录 navigatePageTo() finish() } diff --git a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt index bc37415..88ac116 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/PermissionActivity.kt @@ -15,9 +15,8 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() + startLoginActivity() } else { EasyPermissions.requestPermissions( this@PermissionActivity, @@ -28,11 +27,11 @@ } } - private fun startSplashScreenActivity() { + private fun startLoginActivity() { //先把导航隐私政策声明,后面导航会用到 MapsInitializer.updatePrivacyShow(this, true, true) MapsInitializer.updatePrivacyAgree(this, true) - navigatePageTo() + navigatePageTo() finish() } @@ -44,7 +43,7 @@ } override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() + startLoginActivity() } override fun onPermissionsDenied(requestCode: Int, perms: List) { diff --git a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt deleted file mode 100644 index b078b76..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/SplashScreenActivity.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.databinding.ActivitySplashBinding -import com.casic.br.operationsite.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt deleted file mode 100644 index 274637f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt +++ /dev/null @@ -1,293 +0,0 @@ -package com.casic.br.operationsite.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation -import com.casic.br.operationsite.R -import com.casic.br.operationsite.callback.OnImageCompressListener -import com.casic.br.operationsite.databinding.ActivityUploadActivityBinding -import com.casic.br.operationsite.extensions.combineImagePath -import com.casic.br.operationsite.extensions.compressImage -import com.casic.br.operationsite.extensions.initImmersionBar -import com.casic.br.operationsite.model.ImageModel -import com.casic.br.operationsite.model.UserDetailModel -import com.casic.br.operationsite.utils.GlideLoadEngine -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit -import com.casic.br.operationsite.vm.EventViewModel -import com.casic.br.operationsite.vm.UploadFileViewModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.luck.picture.lib.basic.PictureSelector -import com.luck.picture.lib.config.SelectMimeType -import com.luck.picture.lib.entity.LocalMedia -import com.luck.picture.lib.interfaces.OnResultCallbackListener -import com.pengxh.kt.lite.adapter.EditableImageAdapter -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.dp2px -import com.pengxh.kt.lite.extensions.getScreenWidth -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.timestampToCompleteDate -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialog -import com.pengxh.kt.lite.utils.SaveKeyValues -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch -import java.io.File - -class UploadEventActivity : KotlinBaseActivity() { - - private val kTag = "UploadEventActivity" - private lateinit var imageAdapter: EditableImageAdapter - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var eventViewModel: EventViewModel - private val context = this - private val marginOffset by lazy { 2.dp2px(this) } - private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 - private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private var mapLocation: AMapLocation? = null - - override fun initViewBinding(): ActivityUploadActivityBinding { - return ActivityUploadActivityBinding.inflate(layoutInflater) - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - - } - }) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String - if (userDetailJson.isNotBlank()) { - val userDetail = Gson().fromJson( - userDetailJson, object : TypeToken() {}.type - ) - - binding.uploadPersonView.text = userDetail.name - binding.personNumberView.text = userDetail.phone - } - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val url = it.data.toString() - imagePaths.add(url) - recyclerViewImages.add(url.combineImagePath()) - imageAdapter.notifyDataSetChanged() - } - } - - eventViewModel = ViewModelProvider(this)[EventViewModel::class.java] - eventViewModel.resultModel.observe(this) { - if (it.code == 200) { - finish() - } - } - - //左右边距 - val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) - binding.addImageRecyclerView.addItemDecoration( - RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) - ) - binding.addImageRecyclerView.adapter = imageAdapter - } - - override fun onResume() { - super.onResume() - getCurrentLocation() - } - - override fun observeRequestState() { - uploadFileViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "图片上传中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - - eventViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialog.show(this, "事件提交中,请稍后...") - else -> LoadingDialog.dismiss() - } - } - } - - override fun initEvent() { - binding.locationImageView.setOnClickListener { getCurrentLocation() } - - imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { - override fun onAddImageClick() { - selectPicture() - } - - override fun onItemClick(position: Int) { - if (recyclerViewImages[position].isEmpty()) { - "图片加载失败,无法查看大图".show(context) - } else { - navigatePageTo(position, recyclerViewImages) - } - } - - override fun onItemLongClick(view: View?, position: Int) { - imagePaths.removeAt(position) - recyclerViewImages.removeAt(position) - imageAdapter.notifyDataSetChanged() - } - }) - - binding.siteEditView.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - - } - - override fun afterTextChanged(s: Editable?) { - val text = s.toString().trim() - binding.inputLengthView.text = String.format("${text.length}/100") - if (text.length > 100) { - binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) - "现场情况字符不能超过100个字符".show(context) - } else { - binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - - binding.uploadEventButton.setOnClickListener { - if (binding.eventNameView.text.isNullOrBlank()) { - "请输入事件名称".show(this) - return@setOnClickListener - } - - if (binding.siteEditView.text.isNullOrBlank()) { - "请输入事件简要描述".show(this) - return@setOnClickListener - } - - val imageModels = ArrayList() - imagePaths.forEach { url -> - imageModels.add(ImageModel("", "", url)) - } - - eventViewModel.addEvent( - this, - binding.eventNameView.text.toString(), - binding.personNumberView.text.toString(), - mapLocation?.longitude.toString(), - System.currentTimeMillis().timestampToCompleteDate(), - binding.siteEditView.text.toString(), - "", - binding.uploadPersonView.text.toString(), - imageModels.toTypedArray(), - mapLocation?.latitude.toString(), - ) - } - } - - private fun selectPicture() { - BottomActionSheet.Builder().setContext(this).setActionItemTitle(listOf("拍照", "相册")) - .setItemTextColor(R.color.mainThemeColor.convertColor(this)) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> { - PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return - } - analyticalSelectResults(result.first()) - } - - override fun onCancel() { - - } - }) - } - - 1 -> { - PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) - .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) - .setImageEngine(GlideLoadEngine.get) - .forResult(object : OnResultCallbackListener { - override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } - } - } - - override fun onCancel() { - - } - }) - } - } - } - }).build().show() - } - - private fun getCurrentLocation() { - binding.eventLocationView.text = "定位中..." - LocationKit.getCurrentLocation(this, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - binding.eventLocationView.text = "定位失败" - binding.eventLocationView.setTextColor(R.color.redTextColor.convertColor(context)) - } else { - mapLocation = aMapLocation - binding.eventLocationView.text = aMapLocation.address - binding.eventLocationView.setTextColor(R.color.subTextColor.convertColor(context)) - } - } - }) - } - - private fun analyticalSelectResults(result: LocalMedia) { - //压缩图片后上传 - result.realPath.compressImage(this, object : OnImageCompressListener { - override fun onSuccess(file: File) { - //上传图片 - uploadFileViewModel.uploadImage(context, file) - } - - override fun onError(e: Throwable) { - e.printStackTrace() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt index 94d87d9..eb25cb8 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt @@ -337,10 +337,6 @@ navigatePageTo() } - binding.uploadMenuItem.setOnClickListener { - navigatePageTo() - } - binding.applyMenuItem.setOnClickListener { navigatePageTo() } diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt index bc8b866..10e9a26 100644 --- a/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/vm/UserDetailViewModel.kt @@ -1,6 +1,5 @@ package com.casic.br.operationsite.vm -import androidx.lifecycle.MutableLiveData import com.casic.br.operationsite.extensions.getResponseCode import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.retrofit.RetrofitServiceManager @@ -9,33 +8,28 @@ import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.SaveKeyValues class UserDetailViewModel : BaseViewModel() { private val gson = Gson() - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - fun getUserDetail() = launch({ + loadState.value = LoadState.Loading val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } + val responseCode = response.getResponseCode() + if (responseCode == 200) { + val userDetail = gson.fromJson( + response, object : TypeToken() {}.type + ) + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, userDetail.data.name) + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail } }, { + loadState.value = LoadState.Fail it.printStackTrace() }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt index 1bdbcb4..a7edb5c 100644 --- a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -20,7 +20,7 @@ import com.amap.api.services.geocoder.RegeocodeQuery import com.amap.api.services.geocoder.RegeocodeResult import com.casic.br.operationsite.R -import com.pengxh.kt.lite.extensions.breakLine +import com.pengxh.kt.lite.extensions.wrapLine class CenterMarkerView(private val context: Context, private var aMap: AMap) { private lateinit var centerMarker: Marker @@ -46,7 +46,7 @@ if (code == 1000) { //手动换行 val address = regeocodeResult.regeocodeAddress.formatAddress - locationView.text = address.breakLine(22) + locationView.text = address.wrapLine(22) } } diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index fb34d0e..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..13db468 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml index 8e06df7..13d10ed 100644 --- a/app/src/main/res/layout/activity_alarm_list.xml +++ b/app/src/main/res/layout/activity_alarm_list.xml @@ -1,7 +1,6 @@ - + app:fabSize="normal" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_apply_enter.xml b/app/src/main/res/layout/activity_apply_enter.xml index 2ef2323..f380cd0 100644 --- a/app/src/main/res/layout/activity_apply_enter.xml +++ b/app/src/main/res/layout/activity_apply_enter.xml @@ -153,7 +153,8 @@