diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_aim.xml b/app/src/main/res/drawable/ic_aim.xml new file mode 100644 index 0000000..ad05a1f --- /dev/null +++ b/app/src/main/res/drawable/ic_aim.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_aim.xml b/app/src/main/res/drawable/ic_aim.xml new file mode 100644 index 0000000..ad05a1f --- /dev/null +++ b/app/src/main/res/drawable/ic_aim.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 05f74d6..79d766a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ + + + + + + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_aim.xml b/app/src/main/res/drawable/ic_aim.xml new file mode 100644 index 0000000..ad05a1f --- /dev/null +++ b/app/src/main/res/drawable/ic_aim.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 05f74d6..79d766a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_aim.xml b/app/src/main/res/drawable/ic_aim.xml new file mode 100644 index 0000000..ad05a1f --- /dev/null +++ b/app/src/main/res/drawable/ic_aim.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 05f74d6..79d766a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_label_marker_attribute.xml b/app/src/main/res/layout/include_label_marker_attribute.xml index 813ff0b..de7a99f 100644 --- a/app/src/main/res/layout/include_label_marker_attribute.xml +++ b/app/src/main/res/layout/include_label_marker_attribute.xml @@ -41,7 +41,7 @@ android:id="@+id/markerIdView" style="@style/inputEditTextStyle" android:gravity="center_vertical" - android:textColor="@color/hintColor" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_aim.xml b/app/src/main/res/drawable/ic_aim.xml new file mode 100644 index 0000000..ad05a1f --- /dev/null +++ b/app/src/main/res/drawable/ic_aim.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 05f74d6..79d766a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_label_marker_attribute.xml b/app/src/main/res/layout/include_label_marker_attribute.xml index 813ff0b..de7a99f 100644 --- a/app/src/main/res/layout/include_label_marker_attribute.xml +++ b/app/src/main/res/layout/include_label_marker_attribute.xml @@ -41,7 +41,7 @@ android:id="@+id/markerIdView" style="@style/inputEditTextStyle" android:gravity="center_vertical" - android:textColor="@color/hintColor" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> - + - + - + - + + android:textColor="@color/black" /> + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_aim.xml b/app/src/main/res/drawable/ic_aim.xml new file mode 100644 index 0000000..ad05a1f --- /dev/null +++ b/app/src/main/res/drawable/ic_aim.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 05f74d6..79d766a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_label_marker_attribute.xml b/app/src/main/res/layout/include_label_marker_attribute.xml index 813ff0b..de7a99f 100644 --- a/app/src/main/res/layout/include_label_marker_attribute.xml +++ b/app/src/main/res/layout/include_label_marker_attribute.xml @@ -41,7 +41,7 @@ android:id="@+id/markerIdView" style="@style/inputEditTextStyle" android:gravity="center_vertical" - android:textColor="@color/hintColor" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> - + - + - + - + + android:textColor="@color/black" /> + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_aim.xml b/app/src/main/res/drawable/ic_aim.xml new file mode 100644 index 0000000..ad05a1f --- /dev/null +++ b/app/src/main/res/drawable/ic_aim.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 05f74d6..79d766a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_label_marker_attribute.xml b/app/src/main/res/layout/include_label_marker_attribute.xml index 813ff0b..de7a99f 100644 --- a/app/src/main/res/layout/include_label_marker_attribute.xml +++ b/app/src/main/res/layout/include_label_marker_attribute.xml @@ -41,7 +41,7 @@ android:id="@+id/markerIdView" style="@style/inputEditTextStyle" android:gravity="center_vertical" - android:textColor="@color/hintColor" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> - + - + - + - + + android:textColor="@color/black" /> + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_popup_menu.xml b/app/src/main/res/layout/item_popup_menu.xml new file mode 100644 index 0000000..b4f4ba4 --- /dev/null +++ b/app/src/main/res/layout/item_popup_menu.xml @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d0ac5b..3de7a96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ + () { + + private val layoutInflater by lazy { LayoutInflater.from(context) } + private val screenWidth by lazy { context.getScreenWidth() } + private var images: MutableList = ArrayList() + + fun setupImage(images: MutableList) { + this.images = images + notifyItemRangeChanged(0, images.size) + } + + fun deleteImage(position: Int) { + if (images.isNotEmpty()) { + images.removeAt(position) + /** + * 发生变化的item数目 + * */ + notifyItemRangeRemoved(position, 1) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + layoutInflater.inflate(R.layout.item_editable_rv_g, parent, false) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val imageView = holder.getView(R.id.imageView) + configImageParams(imageView, holder.bindingAdapterPosition) + if (position == itemCount - 1 && images.size < imageCountLimit) { + imageView.setImageResource(R.mipmap.photo6) + imageView.setOnClickListener { //添加图片 + itemClickListener?.onAddImageClick() + } + } else { + Glide.with(context).load(images[position]).into(imageView) + imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener?.onItemClick(holder.bindingAdapterPosition) + } + // 长按监听 + imageView.setOnLongClickListener { v -> //长按删除 + itemClickListener?.onItemLongClick(v, holder.bindingAdapterPosition) + true + } + } + } + + private fun configImageParams(imageView: ImageView, position: Int) { + val temp = spacing.dp2px(context) + val imageSize = (screenWidth - temp * 3) / 3 + + val params = LinearLayout.LayoutParams(imageSize, imageSize) + when (position) { + 0 -> params.setMargins(temp, temp, temp shr 1, temp shr 1) + 1 -> params.setMargins(temp shr 1, temp, temp shr 1, temp shr 1) + 2 -> params.setMargins(temp shr 1, temp, temp, temp shr 1) + 3 -> params.setMargins(temp, temp shr 1, temp shr 1, temp shr 1) + 4 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp shr 1) + 5 -> params.setMargins(temp shr 1, temp shr 1, temp, temp shr 1) + 6 -> params.setMargins(temp, temp shr 1, temp shr 1, temp) + 7 -> params.setMargins(temp shr 1, temp shr 1, temp shr 1, temp) + 8 -> params.setMargins(temp shr 1, temp shr 1, temp, temp) + } + imageView.layoutParams = params + } + + override fun getItemCount(): Int = if (images.size >= imageCountLimit) { + imageCountLimit + } else { + images.size + 1 + } + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(itemClickListener: OnItemClickListener?) { + this.itemClickListener = itemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + + fun onItemClick(position: Int) + + fun onItemLongClick(view: View?, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt new file mode 100644 index 0000000..60abe1e --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ArrayList.kt @@ -0,0 +1,19 @@ +package com.casic.electric.detector.extensions + +/** + * ArrayList扩展方法 + */ + +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(", ") + } + } + return builder.toString() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt new file mode 100644 index 0000000..d48b1ac --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/ByteArray.kt @@ -0,0 +1,15 @@ +package com.casic.electric.detector.extensions + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val v: Int = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt new file mode 100644 index 0000000..f7ed2a2 --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/extensions/Spinner.kt @@ -0,0 +1,10 @@ +package com.casic.electric.detector.extensions + +import android.app.Activity +import android.widget.ArrayAdapter +import android.widget.Spinner + +fun Spinner.show(activity: Activity, items: Array, default: Int) { + this.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, items) + this.setSelection(default) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/extensions/String.kt b/app/src/main/java/com/casic/electric/detector/extensions/String.kt index 197a2a8..d44c315 100644 --- a/app/src/main/java/com/casic/electric/detector/extensions/String.kt +++ b/app/src/main/java/com/casic/electric/detector/extensions/String.kt @@ -55,36 +55,6 @@ return "$httpConfig/ems${this}" } -fun String.toObjectType(): String { - return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { - "1" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { - "2" - } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { - "3" - } else { - "4" - } -} - -fun String.toColor(): String { - return if (this == LocaleConstant.COLOR_ARRAY[0]) { - "0" - } else if (this == LocaleConstant.COLOR_ARRAY[1]) { - "1" - } else if (this == LocaleConstant.COLOR_ARRAY[2]) { - "2" - } else if (this == LocaleConstant.COLOR_ARRAY[3]) { - "3" - } else if (this == LocaleConstant.COLOR_ARRAY[4]) { - "4" - } else if (this == LocaleConstant.COLOR_ARRAY[5]) { - "5" - } else { - "6" - } -} - fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -130,4 +100,34 @@ } } return sb.toString() +} + +fun String.toObjectType(): String { + return if (this == LocaleConstant.POINT_TYPE_ARRAY[0]) { + "1" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[1]) { + "2" + } else if (this == LocaleConstant.POINT_TYPE_ARRAY[2]) { + "3" + } else { + "4" + } +} + +fun String.toColor(): String { + return if (this == LocaleConstant.COLOR_ARRAY[0]) { + "0" + } else if (this == LocaleConstant.COLOR_ARRAY[1]) { + "1" + } else if (this == LocaleConstant.COLOR_ARRAY[2]) { + "2" + } else if (this == LocaleConstant.COLOR_ARRAY[3]) { + "3" + } else if (this == LocaleConstant.COLOR_ARRAY[4]) { + "4" + } else if (this == LocaleConstant.COLOR_ARRAY[5]) { + "5" + } else { + "6" + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt index 4a4e798..5b3b5c1 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/DataBaseManager.kt @@ -74,6 +74,11 @@ ).list() } + fun queryLabelById(markerId: String): List { + return labelBeanDao.queryBuilder() + .where(LabelBeanDao.Properties.MarkerId.eq(markerId)) + .list() + } /******************************* Lable *** End **********************************************/ /******************************* Small Lable *** Start **************************************/ diff --git a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt index d649221..78bde44 100644 --- a/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/electric/detector/utils/LocaleConstant.kt @@ -31,11 +31,19 @@ val POPUP_TITLES = arrayOf("更新数据", "下载工单", "关于软件", "事件上报", "标识器补全") var CONDITION_ARRAY = arrayOf("种类", "编号", "名称", "所属区域", "所属道路", "运检单位", "责任人", "建设时间", "标识器ID") var CONTENT_ARRAY = arrayOf("电缆井", "电缆通道", "配电房", "开关站", "台区", "杆塔") + var OBJECT_MODE_ARRAY = arrayOf("直线井", "转弯井", "丁字井", "十字井", "其他") + var WELL_COVER_MATERIAL_ARRAY = arrayOf("水泥盖板", "双重加重铁盖", "普通复合盖", "轻型连盖", "长方铁盖", "其他") + var CABINET_TYPE_ARRAY = arrayOf("无", "SM6", "SAFE", "RM6", "XGN15", "固体柜") + var PIPE_MATERIAL_ARRAY = arrayOf("无", "PVC管", "波纹管", "镀锌钢管") + var MARKER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") + var VOLTAGE_LEVEL_ARRAY = arrayOf("0.4KV", "10KV", "35KV", "110KV", "220KV") + var VOLTAGE_LEVEL_STATE_ARRAY = booleanArrayOf(false, false, false, false, false) + var CROSS_PIPE_ARRAY = arrayOf("供水", "污水", "燃气", "热力", "石油", "有线电视", "其他") + var CROSS_PIPE_STATE_ARRAY = booleanArrayOf(false, false, false, false, false, false, false) + var POINT_TYPE_ARRAY = arrayOf("管线", "管线附属物", "管线特征管点", "交叉穿越点") var SPINNER_ARRAY = arrayOf("标识器ID", "所属区域", "所属线路", "所属道路", "权属单位", "安装部门", "安装时间", "备注") - var PIPE_MATERIAL_ARRAY = arrayOf("铸铁", "塑料") var DOWN_PIPE_TYPE_ARRAY = arrayOf("热力", "燃气", "供水", "电力", "通信") var BURY_METHOD_ARRAY = arrayOf("直埋", "圆管", "管块", "管沟", "架空") - var IDENTIFIER_TYPE_ARRAY = arrayOf("EM30", "EM50", "EM14") var COLOR_ARRAY = arrayOf("蓝色", "橙色", "红色", "黑色", "紫色", "黄色", "绿色") } \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt index 93f4e16..c850438 100644 --- a/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt +++ b/app/src/main/java/com/casic/electric/detector/view/MainActivity.kt @@ -1,44 +1,38 @@ package com.casic.electric.detector.view import android.app.AlertDialog -import android.app.ProgressDialog import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings -import android.util.Log import android.view.KeyEvent -import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.amap.api.location.AMapLocation import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.MyLocationStyle -import com.casic.electric.detector.BuildConfig import com.casic.electric.detector.R import com.casic.electric.detector.bean.LabelBean import com.casic.electric.detector.bean.SmallLabelBean +import com.casic.electric.detector.bean.TaskBean import com.casic.electric.detector.callback.ILocationListener import com.casic.electric.detector.cluster.ClusterItem import com.casic.electric.detector.cluster.ClusterOverlay import com.casic.electric.detector.cluster.RegionItem -import com.casic.electric.detector.extensions.appendDownloadUrl import com.casic.electric.detector.extensions.appendExcelDownloadUrl import com.casic.electric.detector.extensions.drawCircle import com.casic.electric.detector.extensions.initLayoutImmersionBar import com.casic.electric.detector.utils.* import com.casic.electric.detector.vm.TaskViewModel -import com.casic.electric.detector.vm.VersionViewModel import com.casic.electric.detector.widgets.QueryMarkerDialog import com.casic.electric.detector.widgets.SamplePopupWindow import com.gyf.immersionbar.ImmersionBar @@ -50,6 +44,7 @@ import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -60,12 +55,11 @@ private val kTag = "MainActivity" private val context: Context = this@MainActivity private val samplePopupWindow by lazy { SamplePopupWindow(this) } - private val progressDialog by lazy { ProgressDialog(this) } private var clickTime: Long = 0 private lateinit var wakeLock: PowerManager.WakeLock private lateinit var aMap: AMap - private lateinit var versionViewModel: VersionViewModel private lateinit var taskViewModel: TaskViewModel + private lateinit var taskBean: TaskBean private var latitude: Double = 0.0 private var longitude: Double = 0.0 private var labels = ArrayList() @@ -98,36 +92,6 @@ samplePopupWindow.setPopupMenuItem(LocaleConstant.POPUP_TITLES) samplePopupWindow.setBackgroundDrawable(null) - //初始化下载对话框 - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) - progressDialog.setCanceledOnTouchOutside(false) - progressDialog.setCancelable(false) - - versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] - versionViewModel.versionResult.observe(this) { - if (it.version.toInt() > BuildConfig.VERSION_CODE) { - AlertControlDialog.Builder() - .setContext(this) - .setTitle("提示") - .setMessage("有新版本,是否更新?") - .setNegativeButton("稍后再说") - .setPositiveButton("立即下载") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - downloadApk(it.path) - } - - override fun onCancelClick() { - - } - }).build().show() - } else { - "已是最新版本,无需更新".show(this) - } - } - taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel.markerFileResult.observe(this) { if (it.success == "true") { @@ -215,8 +179,16 @@ override fun initEvent() { rightImageView.setOnClickListener { - val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(this) - samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(this)) + CoroutineScope(Dispatchers.Main).launch { + val labels = withContext(Dispatchers.IO) { + DataBaseManager.get.queryLabelById("0") + } + if (labels.isNotEmpty()) { + samplePopupWindow.setShowPosition(4) + } + val x = rightImageView.width - samplePopupWindow.width - 1f.dp2px(context) + samplePopupWindow.showAsDropDown(rightImageView, x, 1f.dp2px(context)) + } } samplePopupWindow.setOnPopupWindowClickListener(object : @@ -225,7 +197,7 @@ when (position) { 0 -> updateLabels() // 1 -> downloadTask() - 2 -> versionViewModel.getApplicationVersion() + 2 -> navigatePageTo() // 3 -> uploadEvent() // 4 -> uploadLabel() } @@ -257,7 +229,7 @@ //查看 viewButton.setOnClickListener { QueryMarkerDialog.Builder() - .setContext(context) + .setContext(this) .setTitle("查看标识器") .setConditionArray(LocaleConstant.CONDITION_ARRAY) .setNegativeButton("取消") @@ -280,6 +252,30 @@ ) as ArrayList } } + + val latitudeList = ArrayList() + val longitudeList = ArrayList() + + labels.forEach { + val latitude = it.latitude + val longitude = it.longitude + if (latitude.isNotBlank() && longitude.isNotBlank()) { + if (CoordinateConverter.isAMapDataAvailable( + latitude.toDouble(), longitude.toDouble() + ) + ) { + //分别缓存经、纬度 + latitudeList.add(latitude.toDouble()) + longitudeList.add(longitude.toDouble()) + } + } + } + + //移动地图到所有labelBeans的第一个点 + val center = LatLng(latitudeList.first(), longitudeList.first()) + //移动到指定经纬度 + aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 16f)) + showLabelsOnMap() } } @@ -360,7 +356,7 @@ val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true - uiSettings.isMyLocationButtonEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 @@ -382,19 +378,7 @@ } //首次移动到定位点 - LocationHub.getCurrentLocation(this, object : ILocationListener { - override fun onAMapLocationGet(location: AMapLocation?) { - if (location != null) { - aMap.moveCamera( - CameraUpdateFactory.newLatLngZoom( - LatLng(location.latitude, location.longitude), 15f - ) - ) - } else { - "当前位置信号差,无法移动地图到定位点".show(context) - } - } - }) + moveToCurrentLocation() aMap.setOnMapLongClickListener { lifecycleScope.launch { @@ -412,6 +396,25 @@ } } } + + //自定义定位按钮 + aimButton.setOnClickListener { moveToCurrentLocation() } + } + + private fun moveToCurrentLocation() { + LocationHub.getCurrentLocation(this, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { + if (location != null) { + aMap.moveCamera( + CameraUpdateFactory.newLatLngZoom( + LatLng(location.latitude, location.longitude), 16f + ) + ) + } else { + "当前位置信号差,无法移动地图到定位点".show(context) + } + } + }) } //更新数据 @@ -451,58 +454,6 @@ }).build().show() } - private fun downloadApk(url: String?) { - progressDialog.setMessage("下载新版本中...") - progressDialog.show() - if (url.toString().isBlank()) { - "抱歉,版本下载失败".show(this) - return - } - /** - * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk - * */ - val downloadPath = url!!.appendDownloadUrl(FileType.APK) - Log.d(kTag, "downloadApk => $downloadPath") - //开始下载 - downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { - override fun onDownloadStart(totalBytes: Long) { - progressDialog.max = totalBytes.toInt() - } - - override fun onProgressChanged(currentBytes: Long) { - progressDialog.progress = currentBytes.toInt() - } - - override fun onDownloadEnd(file: File?) { - progressDialog.dismiss() - progressDialog.progress = 0 - //安装APK - installApk(file) - } - }) - } - - private fun installApk(apkPackage: File?) { - if (apkPackage == null) { - "安装文件异常,无法安装".show(this) - return - } - val intent = Intent(Intent.ACTION_VIEW) - val data: Uri - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 - data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 - } else { - data = Uri.fromFile(apkPackage) - } - /** - * android 10 - * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk - * */ - intent.setDataAndType(data, "application/vnd.android.package-archive") - startActivity(intent) - } - private fun showLabelsOnMap() { clusterOverlay?.onDestroy() val clusterItems = ArrayList() @@ -568,7 +519,15 @@ builder.include(clusterItem.position) item = clusterItem as RegionItem } - //点击Marker移到Marker视图 + + if (item == null) { + "标识器经纬度异常".show(context) + return@setOnClusterClickListener + } + + val latLng = LatLng(item.position.latitude, item.position.longitude) + + //移动视图 val latLngBounds = builder.build() aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0)) @@ -581,7 +540,7 @@ when (position) { 0 -> { labels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { navigatePageTo(it.toJson()) } } @@ -589,7 +548,7 @@ 1 -> { val electricMarkers = ArrayList() smallLabels.forEach { - if (it.markerId.toString() == item?.tag) { + if (it.markerId.toString() == item.tag) { electricMarkers.add(it.electricMarkerId) } } @@ -603,11 +562,6 @@ showElectricMarkers(electricMarkers) } 2 -> { - if (item == null) { - "标识器经纬度异常".show(context) - return - } - RouteOnMap.startNavigation( context, item.tag, LatLng(item.position.latitude, item.position.longitude) diff --git a/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt new file mode 100644 index 0000000..0b2479d --- /dev/null +++ b/app/src/main/java/com/casic/electric/detector/view/VersionControlActivity.kt @@ -0,0 +1,148 @@ +package com.casic.electric.detector.view + +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.core.content.FileProvider +import androidx.lifecycle.ViewModelProvider +import com.casic.electric.detector.BuildConfig +import com.casic.electric.detector.R +import com.casic.electric.detector.extensions.appendDownloadUrl +import com.casic.electric.detector.extensions.initLayoutImmersionBar +import com.casic.electric.detector.utils.FileType +import com.casic.electric.detector.utils.LoadingDialogHub +import com.casic.electric.detector.utils.LocaleConstant +import com.casic.electric.detector.vm.VersionViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog +import kotlinx.android.synthetic.main.activity_version_control.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class VersionControlActivity : KotlinBaseActivity() { + + private val kTag = "VersionControlActivity" + private val progressDialog by lazy { ProgressDialog(this) } + private lateinit var versionViewModel: VersionViewModel + + override fun initData(savedInstanceState: Bundle?) { + versionView.text = "Version ${BuildConfig.VERSION_NAME}" + + //初始化下载对话框 + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) + + versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] + versionViewModel.versionResult.observe(this) { + if (it.version.toInt() > BuildConfig.VERSION_CODE) { + AlertControlDialog.Builder() + .setContext(this) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.path) + } + + override fun onCancelClick() { + + } + }).build().show() + } else { + "已是最新版本,无需更新".show(this) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + updateLayout.setOnClickListener { + versionViewModel.getApplicationVersion() + } + } + + override fun initLayoutView(): Int = R.layout.activity_version_control + + override fun observeRequestState() { + versionViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "检查版本中,请稍后") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.visibility = View.GONE + } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(this) + return + } + /** + * http://139.198.18.188:8090/ems/apk/EMSCJTX202011052026(V3.14.0).apk + * */ + val downloadPath = url!!.appendDownloadUrl(FileType.APK) + Log.d(kTag, "downloadApk => $downloadPath") + //开始下载 + downloadPath.downloadFile(createDownloadFileDir().toString(), object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "安装文件异常,无法安装".show(this) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile(this, LocaleConstant.APP_AUTHORITY, apkPackage) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + /** + * android 10 + * content://com.casic.app.smartwell.fileprovider/smartWell/Download/1.0.1.apk + * */ + intent.setDataAndType(data, "application/vnd.android.package-archive") + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt index 3d175ab..633e55c 100644 --- a/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt +++ b/app/src/main/java/com/casic/electric/detector/widgets/SamplePopupWindow.kt @@ -10,9 +10,15 @@ import android.widget.TextView import com.casic.electric.detector.R import com.pengxh.kt.lite.extensions.getScreenWidth +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton class SamplePopupWindow constructor(context: Context) : PopupWindow() { private var clickListener: OnPopupWindowClickListener? = null + private var showPosition = -1 + + fun setShowPosition(showPosition: Int) { + this.showPosition = showPosition + } init { width = ((context.getScreenWidth() * 0.35).toInt()) @@ -25,7 +31,7 @@ fun setPopupMenuItem(titleArray: Array) { val popupListView = contentView.findViewById(R.id.popupListView) - popupListView.adapter = object : BaseAdapter() { + val baseAdapter = object : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(contentView.context) override fun getCount(): Int { return titleArray.size @@ -46,15 +52,22 @@ view = inflater.inflate(R.layout.item_popup_menu, null) holder = PopupWindowHolder() holder.titleView = view.findViewById(R.id.titleView) + holder.tagView = view.findViewById(R.id.tagView) view.tag = holder } else { view = convertView holder = view.tag as PopupWindowHolder } holder.titleView.text = titleArray[position] + if (showPosition == position) { + holder.tagView.visibility = View.VISIBLE + } else { + holder.tagView.visibility = View.INVISIBLE + } return view } } + popupListView.adapter = baseAdapter popupListView.setOnItemClickListener { _, _, position, _ -> clickListener?.onPopupItemClicked(position) dismiss() @@ -71,5 +84,6 @@ internal class PopupWindowHolder { lateinit var titleView: TextView + lateinit var tagView: QMUIRoundButton } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_aim.xml b/app/src/main/res/drawable/ic_aim.xml new file mode 100644 index 0000000..ad05a1f --- /dev/null +++ b/app/src/main/res/drawable/ic_aim.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 05f74d6..79d766a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_label_marker_attribute.xml b/app/src/main/res/layout/include_label_marker_attribute.xml index 813ff0b..de7a99f 100644 --- a/app/src/main/res/layout/include_label_marker_attribute.xml +++ b/app/src/main/res/layout/include_label_marker_attribute.xml @@ -41,7 +41,7 @@ android:id="@+id/markerIdView" style="@style/inputEditTextStyle" android:gravity="center_vertical" - android:textColor="@color/hintColor" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> + android:textColor="@color/black" /> - + - + - + - + + android:textColor="@color/black" /> + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_popup_menu.xml b/app/src/main/res/layout/item_popup_menu.xml new file mode 100644 index 0000000..b4f4ba4 --- /dev/null +++ b/app/src/main/res/layout/item_popup_menu.xml @@ -0,0 +1,25 @@ + + + + + + + \ 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 620772b..d593a00 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -24,6 +24,23 @@ @drawable/bg_solid_layout_white_radius_10 + + + + + +