diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml
index e05ab3b..ecbdb78 100644
--- a/app/src/main/res/layout/activity_alarm_list.xml
+++ b/app/src/main/res/layout/activity_alarm_list.xml
@@ -46,7 +46,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml
index e05ab3b..ecbdb78 100644
--- a/app/src/main/res/layout/activity_alarm_list.xml
+++ b/app/src/main/res/layout/activity_alarm_list.xml
@@ -46,7 +46,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml
new file mode 100644
index 0000000..9d060f4
--- /dev/null
+++ b/app/src/main/res/layout/activity_big_image.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml
index e05ab3b..ecbdb78 100644
--- a/app/src/main/res/layout/activity_alarm_list.xml
+++ b/app/src/main/res/layout/activity_alarm_list.xml
@@ -46,7 +46,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml
new file mode 100644
index 0000000..9d060f4
--- /dev/null
+++ b/app/src/main/res/layout/activity_big_image.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upload_activity.xml b/app/src/main/res/layout/activity_upload_activity.xml
new file mode 100644
index 0000000..2d028f0
--- /dev/null
+++ b/app/src/main/res/layout/activity_upload_activity.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml
index e05ab3b..ecbdb78 100644
--- a/app/src/main/res/layout/activity_alarm_list.xml
+++ b/app/src/main/res/layout/activity_alarm_list.xml
@@ -46,7 +46,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml
new file mode 100644
index 0000000..9d060f4
--- /dev/null
+++ b/app/src/main/res/layout/activity_big_image.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upload_activity.xml b/app/src/main/res/layout/activity_upload_activity.xml
new file mode 100644
index 0000000..2d028f0
--- /dev/null
+++ b/app/src/main/res/layout/activity_upload_activity.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml
index e05ab3b..ecbdb78 100644
--- a/app/src/main/res/layout/activity_alarm_list.xml
+++ b/app/src/main/res/layout/activity_alarm_list.xml
@@ -46,7 +46,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml
new file mode 100644
index 0000000..9d060f4
--- /dev/null
+++ b/app/src/main/res/layout/activity_big_image.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upload_activity.xml b/app/src/main/res/layout/activity_upload_activity.xml
new file mode 100644
index 0000000..2d028f0
--- /dev/null
+++ b/app/src/main/res/layout/activity_upload_activity.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 3a2c64f..4ae86a1 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -26,4 +26,7 @@
45dp
+
+
+ 55dp
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml
index e05ab3b..ecbdb78 100644
--- a/app/src/main/res/layout/activity_alarm_list.xml
+++ b/app/src/main/res/layout/activity_alarm_list.xml
@@ -46,7 +46,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml
new file mode 100644
index 0000000..9d060f4
--- /dev/null
+++ b/app/src/main/res/layout/activity_big_image.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upload_activity.xml b/app/src/main/res/layout/activity_upload_activity.xml
new file mode 100644
index 0000000..2d028f0
--- /dev/null
+++ b/app/src/main/res/layout/activity_upload_activity.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 3a2c64f..4ae86a1 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -26,4 +26,7 @@
45dp
+
+
+ 55dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 33c15da..95c23c7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,4 @@
动态感知
+ 未知
\ No newline at end of file
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml
index e05ab3b..ecbdb78 100644
--- a/app/src/main/res/layout/activity_alarm_list.xml
+++ b/app/src/main/res/layout/activity_alarm_list.xml
@@ -46,7 +46,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml
new file mode 100644
index 0000000..9d060f4
--- /dev/null
+++ b/app/src/main/res/layout/activity_big_image.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upload_activity.xml b/app/src/main/res/layout/activity_upload_activity.xml
new file mode 100644
index 0000000..2d028f0
--- /dev/null
+++ b/app/src/main/res/layout/activity_upload_activity.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 3a2c64f..4ae86a1 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -26,4 +26,7 @@
45dp
+
+
+ 55dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 33c15da..95c23c7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,4 @@
动态感知
+ 未知
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 9a3dbf8..a9af1ff 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -33,4 +33,55 @@
- @dimen/sp_16
- @drawable/button_main_selector
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/libs/lite-release.aar b/app/libs/lite-release.aar
index f4b81e1..440b021 100644
--- a/app/libs/lite-release.aar
+++ b/app/libs/lite-release.aar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e84bb78..16d0c19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,10 @@
+
+
+
+
+
+
?
+ ) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .override(maxWidth, maxHeight)
+ .load(url)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Bitmap, @Nullable transition: Transition?
+ ) {
+ call?.onCall(resource)
+ }
+
+ override fun onLoadFailed(@Nullable errorDrawable: Drawable?) {
+ call?.onCall(null)
+ }
+
+ override fun onLoadCleared(@Nullable placeholder: Drawable?) {}
+ })
+ }
+
+ override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {
+ if (!ActivityCompatHelper.assertValidRequest(context)) {
+ return
+ }
+ Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .override(180, 180)
+ .sizeMultiplier(0.5f)
+ .transform(CenterCrop(), RoundedCorners(8))
+ .placeholder(R.drawable.ps_image_placeholder)
+ .into(imageView)
+ }
+
+ override fun pauseRequests(context: Context?) {
+ context?.let { Glide.with(it).pauseRequests() }
+ }
+
+ override fun resumeRequests(context: Context?) {
+ context?.let { Glide.with(it).resumeRequests() }
+ }
+
+ override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
+ Glide.with(context)
+ .load(url)
+ .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder))
+ .into(imageView)
+ }
+}
\ No newline at end of file
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 05eee10..ce0a6a2 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
@@ -1,9 +1,17 @@
package com.casic.br.operationsite.utils
+import android.Manifest
+
object LocaleConstant {
+ val USER_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA
+ )
+
const val SERVER_BASE_URL = "http://192.168.43.66:12209"
const val DEFAULT_SERVER_CONFIG = "defaultServerConfig"
+ const val PERMISSIONS_CODE = 999
const val PAGE_LIMIT = 20
}
\ No newline at end of file
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
new file mode 100644
index 0000000..fa4401d
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/BigImageActivity.kt
@@ -0,0 +1,84 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+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 com.casic.br.operationsite.R
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import kotlinx.android.synthetic.main.activity_big_image.*
+import java.util.*
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initLayoutView(): Int = R.layout.activity_big_image
+
+ override fun setupTopBarLayout() {
+ ImmerseStatusBarUtil.setColor(this, Color.BLACK)
+ leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun initEvent() {
+ val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ imagePagerView.adapter = BigImageAdapter(this, urls)
+ imagePagerView.currentItem = index
+ imagePagerView.offscreenPageLimit = imageSize
+ imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ pageNumberView.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: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ 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
new file mode 100644
index 0000000..27d881b
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/UploadEventActivity.kt
@@ -0,0 +1,249 @@
+package com.casic.br.operationsite.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.os.Handler
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.GridLayoutManager
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.callback.OnImageCompressListener
+import com.casic.br.operationsite.extensions.combineImagePath
+import com.casic.br.operationsite.extensions.compressImage
+import com.casic.br.operationsite.utils.DialogHelper
+import com.casic.br.operationsite.utils.GlideLoadEngine
+import com.casic.br.operationsite.vm.UploadFileViewModel
+import com.gyf.immersionbar.ImmersionBar
+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.extensions.convertColor
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
+import kotlinx.android.synthetic.main.activity_upload_activity.*
+import kotlinx.android.synthetic.main.include_base_title.*
+import java.io.File
+
+class UploadEventActivity : KotlinBaseActivity() {
+
+ private val kTag = "UploadEventActivity"
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var uploadFileViewModel: UploadFileViewModel
+ private val context: Context = this@UploadEventActivity
+ private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集
+ private val realPaths: ArrayList = ArrayList() //真实图片路径
+
+ override fun initLayoutView(): Int = R.layout.activity_upload_activity
+
+ override fun setupTopBarLayout() {
+ ImmersionBar.with(this).statusBarDarkFont(false).init()
+ ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this))
+
+ leftBackView.setOnClickListener { finish() }
+ titleView.text = "燃气作业现场动态感知"
+ }
+
+ override fun initData() {
+ weakReferenceHandler = WeakReferenceHandler(callback)
+
+ uploadFileViewModel = ViewModelProvider(this).get(UploadFileViewModel::class.java)
+
+ imageAdapter = EditableImageAdapter(this, 3)
+ addImageRecyclerView.layoutManager = GridLayoutManager(this, 3)
+ addImageRecyclerView.adapter = imageAdapter
+ }
+
+ override fun initEvent() {
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ selectPicture()
+ }
+
+ override fun onItemClick(position: Int) {
+ if (realPaths[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, realPaths)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ imagePaths.removeAt(position)
+ imageAdapter.deleteImage(position)
+ }
+ })
+
+ uploadFileViewModel.resultModel.observe(this, {
+ if (it.code == 200) {
+ val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1
+ if (sumItemCount <= 4) {
+ val url = it.data.toString()
+ if (url.isNotBlank()) {
+ imagePaths.add(url)
+ realPaths.add(url.combineImagePath())
+ }
+ imageAdapter.setupImage(realPaths)
+ } else {
+ "最多只能上传3张图片".show(this)
+ }
+ }
+ })
+ uploadFileViewModel.loadState.observe(this, {
+ DialogHelper.dismissLoadingDialog()
+ })
+
+ 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()
+ inputLengthView.text = String.format("${text.length}/100")
+ if (text.length > 100) {
+ inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
+ "现场情况字符不能超过100个字符".show(context)
+ } else {
+ inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
+ }
+ }
+ })
+
+ uploadEventButton.setOnClickListener {
+
+ }
+ }
+
+ private fun selectPicture() {
+ BottomActionSheet.Builder()
+ .setContext(this)
+ .setItemTextColor(Color.BLUE)
+ .setActionItemTitle(listOf("拍照", "相册"))
+ .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[0])
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ 1 -> {
+ PictureSelector.create(context)
+ .openGallery(SelectMimeType.ofImage())
+ .isGif(false)
+ .isMaxSelectEnabledMask(true)
+ .setFilterMinFileSize(100)
+ .setMaxSelectNum(3)
+ .isDisplayCamera(false)
+ .setImageEngine(GlideLoadEngine.instance)
+ .forResult(object : OnResultCallbackListener {
+ override fun onResult(result: ArrayList?) {
+ DialogHelper.showLoadingDialog(
+ this@UploadEventActivity,
+ "图片上传中,请稍后..."
+ )
+ if (result == null) {
+ "选择照片失败,请重试".show(context)
+ return
+ }
+ // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
+ val sum = (result.size * 500).toLong()
+ object : CountDownTimer(sum, 500) {
+ override fun onTick(millisUntilFinished: Long) {
+ val i = millisUntilFinished / 500
+ val message = weakReferenceHandler.obtainMessage()
+ message.obj = result[i.toInt()]
+ message.what = 2022071301
+ weakReferenceHandler.handleMessage(message)
+ }
+
+ override fun onFinish() {
+
+ }
+ }.start()
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+ }
+ }
+ }).build().show()
+ }
+
+ private val callback = Handler.Callback {
+ if (it.what == 2022071301) {
+ analyticalSelectResults(it.obj as LocalMedia)
+ }
+ true
+ }
+
+ private fun analyticalSelectResults(result: LocalMedia) {
+ //压缩图片
+// val realPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+// result.realPath
+// } else {
+// result.sandboxPath
+// }
+// Log.d(kTag, "初始路径:" + result.path)
+// Log.d(kTag, "绝对路径:" + result.realPath)
+// Log.d(kTag, "原图路径:" + result.originalPath)
+// Log.d(kTag, "沙盒路径:" + result.sandboxPath)
+ result.realPath.compressImage(this, object : OnImageCompressListener {
+ override fun onSuccess(file: File) {
+ Log.d(kTag, "onSuccess: " + file.absolutePath)
+ //上传图片
+ uploadFileViewModel.uploadImage(file)
+ }
+
+ override fun onError(e: Throwable) {
+ e.printStackTrace()
+ }
+ })
+ }
+
+// private lateinit var loadingDialog: QMUITipDialog
+//
+// private fun showLoadingDialog(context: Context?, message: String?) {
+// loadingDialog = QMUITipDialog.Builder(context)
+// .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
+// .setTipWord(message)
+// .create()
+// loadingDialog.show()
+// }
+//
+// private fun dismissLoadingDialog() {
+// if (loadingDialog.isShowing) {
+// loadingDialog.dismiss()
+// }
+// }
+}
\ 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 8d3b0d7..9f200b7 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
@@ -89,7 +89,7 @@
}
uploadTextView.setOnClickListener {
-
+ navigatePageTo()
}
applyTextView.setOnClickListener {
diff --git a/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
new file mode 100644
index 0000000..6ef047c
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/vm/UploadFileViewModel.kt
@@ -0,0 +1,38 @@
+package com.casic.br.operationsite.vm
+
+import androidx.lifecycle.MutableLiveData
+import com.casic.br.operationsite.base.BaseApplication
+import com.casic.br.operationsite.extensions.separateResponseCode
+import com.casic.br.operationsite.extensions.toErrorMessage
+import com.casic.br.operationsite.model.CommonResultModel
+import com.casic.br.operationsite.retrofit.RetrofitServiceManager
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pengxh.kt.lite.extensions.launch
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.vm.BaseViewModel
+import com.pengxh.kt.lite.vm.LoadState
+import java.io.File
+
+class UploadFileViewModel : BaseViewModel() {
+
+ private val gson = Gson()
+ val resultModel = MutableLiveData()
+
+ fun uploadImage(image: File) = launch({
+ val response = RetrofitServiceManager.uploadImage(image)
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ loadState.value = LoadState.Success
+ resultModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ loadState.value = LoadState.Fail
+ response.toErrorMessage().show(BaseApplication.obtainInstance())
+ }
+ }, {
+ loadState.value = LoadState.Fail
+ it.printStackTrace()
+ })
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
new file mode 100644
index 0000000..f00d59c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_white_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
new file mode 100644
index 0000000..5c85867
--- /dev/null
+++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_detail.xml b/app/src/main/res/layout/activity_alarm_detail.xml
index 44144d7..9b7c5eb 100644
--- a/app/src/main/res/layout/activity_alarm_detail.xml
+++ b/app/src/main/res/layout/activity_alarm_detail.xml
@@ -81,7 +81,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alarm_list.xml b/app/src/main/res/layout/activity_alarm_list.xml
index e05ab3b..ecbdb78 100644
--- a/app/src/main/res/layout/activity_alarm_list.xml
+++ b/app/src/main/res/layout/activity_alarm_list.xml
@@ -46,7 +46,6 @@
+ android:text="取消" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml
new file mode 100644
index 0000000..9d060f4
--- /dev/null
+++ b/app/src/main/res/layout/activity_big_image.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upload_activity.xml b/app/src/main/res/layout/activity_upload_activity.xml
new file mode 100644
index 0000000..2d028f0
--- /dev/null
+++ b/app/src/main/res/layout/activity_upload_activity.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 3a2c64f..4ae86a1 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -26,4 +26,7 @@
45dp
+
+
+ 55dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 33c15da..95c23c7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,4 @@
动态感知
+ 未知
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 9a3dbf8..a9af1ff 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -33,4 +33,55 @@
- @dimen/sp_16
- @drawable/button_main_selector
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..064f301
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file