Commit 6ca214a1 authored by wanglei's avatar wanglei

...商品

parent 6ec4c083
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.ScanQR" android:theme="@style/Theme.ScanQR"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".ui.product.ProductCodeActivity"
android:exported="false" />
<activity <activity
android:name=".ui.website.WebsiteCodeActivity" android:name=".ui.website.WebsiteCodeActivity"
android:exported="false" /> android:exported="false" />
......
...@@ -16,5 +16,6 @@ class FunctionUIBean( ...@@ -16,5 +16,6 @@ class FunctionUIBean(
const val KEY_LOCATION = "key_location" const val KEY_LOCATION = "key_location"
const val KEY_TELEPHONE = "key_telephone" const val KEY_TELEPHONE = "key_telephone"
const val KEY_MESSAGE = "key_message" const val KEY_MESSAGE = "key_message"
const val KEY_PRODUCT = "key_product"
} }
} }
\ No newline at end of file
package com.base.scanqr.bean
import com.base.scanqr.bean.FunctionUIBean.Companion.KEY_PRODUCT
data class ProductUIBean(
var content: String = ""
) : ScanBean(KEY_PRODUCT)
\ No newline at end of file
...@@ -22,7 +22,8 @@ class QRImageAnalyzer() : ImageAnalysis.Analyzer { ...@@ -22,7 +22,8 @@ class QRImageAnalyzer() : ImageAnalysis.Analyzer {
//如需仅检测 Aztec 码和 QR 码 //如需仅检测 Aztec 码和 QR 码
private val options = BarcodeScannerOptions.Builder().setBarcodeFormats( private val options = BarcodeScannerOptions.Builder().setBarcodeFormats(
Barcode.FORMAT_QR_CODE, Barcode.FORMAT_AZTEC, Barcode.TYPE_URL // Barcode.FORMAT_QR_CODE, Barcode.FORMAT_AZTEC, Barcode.TYPE_URL, Barcode.TYPE_PRODUCT,
Barcode.FORMAT_ALL_FORMATS
).build() ).build()
//获取解析器 //获取解析器
......
...@@ -11,11 +11,13 @@ import androidx.camera.core.ImageCapture.FLASH_MODE_ON ...@@ -11,11 +11,13 @@ import androidx.camera.core.ImageCapture.FLASH_MODE_ON
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.base.scanqr.R import com.base.scanqr.R
import com.base.scanqr.base.BaseFragment import com.base.scanqr.base.BaseFragment
import com.base.scanqr.bean.ProductUIBean
import com.base.scanqr.bean.ScanBean.Companion.CREATE_TYPE_SCAN import com.base.scanqr.bean.ScanBean.Companion.CREATE_TYPE_SCAN
import com.base.scanqr.bean.TextUIBean import com.base.scanqr.bean.TextUIBean
import com.base.scanqr.databinding.FragmentScanBinding import com.base.scanqr.databinding.FragmentScanBinding
import com.base.scanqr.qr.QRImageAnalyzer import com.base.scanqr.qr.QRImageAnalyzer
import com.base.scanqr.ui.email.EmailCodeActivity import com.base.scanqr.ui.email.EmailCodeActivity
import com.base.scanqr.ui.product.ProductCodeActivity
import com.base.scanqr.ui.text.TextCodeActivity import com.base.scanqr.ui.text.TextCodeActivity
import com.base.scanqr.ui.website.WebsiteCodeActivity import com.base.scanqr.ui.website.WebsiteCodeActivity
import com.base.scanqr.ui.wifi.WifiCodeActivity import com.base.scanqr.ui.wifi.WifiCodeActivity
...@@ -25,6 +27,7 @@ import com.base.scanqr.utils.LogEx ...@@ -25,6 +27,7 @@ import com.base.scanqr.utils.LogEx
import com.base.scanqr.utils.PermissionUtils.checkCameraPermission import com.base.scanqr.utils.PermissionUtils.checkCameraPermission
import com.base.scanqr.utils.QRCodeUtils import com.base.scanqr.utils.QRCodeUtils
import com.google.gson.Gson import com.google.gson.Gson
import com.google.mlkit.vision.barcode.common.Barcode
import com.gyf.immersionbar.ktx.immersionBar import com.gyf.immersionbar.ktx.immersionBar
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -111,6 +114,20 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl ...@@ -111,6 +114,20 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl
LogEx.logDebug(TAG, "qrCodeValue=$qrCodeValue valueType=$valueType") LogEx.logDebug(TAG, "qrCodeValue=$qrCodeValue valueType=$valueType")
val activity = requireActivity() as MainActivity? val activity = requireActivity() as MainActivity?
activity ?: return activity ?: return
if (valueType == Barcode.TYPE_PRODUCT) {
if (scanJump.get()) return
scanJump.set(true)
activity.startActivity(Intent(activity, ProductCodeActivity::class.java).apply {
val bean = ProductUIBean()
bean.content = qrCodeValue
bean.needCreate = true
bean.createType = CREATE_TYPE_SCAN
putExtra("data", Gson().toJson(bean))
})
return
}
if (QRCodeUtils.isWifiQR(qrCodeValue)) { if (QRCodeUtils.isWifiQR(qrCodeValue)) {
if (scanJump.get()) return if (scanJump.get()) return
scanJump.set(true) scanJump.set(true)
...@@ -146,6 +163,7 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl ...@@ -146,6 +163,7 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl
return return
} }
if (qrCodeValue.isEmpty()) { if (qrCodeValue.isEmpty()) {
if (scanJump.get()) return if (scanJump.get()) return
scanJump.set(true) scanJump.set(true)
......
package com.base.scanqr.ui.product
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Environment
import android.widget.Toast
import androidx.activity.addCallback
import androidx.core.view.updatePadding
import com.base.scanqr.R
import com.base.scanqr.base.BaseActivity
import com.base.scanqr.bean.FunctionUIBean
import com.base.scanqr.bean.ProductUIBean
import com.base.scanqr.databinding.ActivityProductCodeBinding
import com.base.scanqr.ui.widget.InputNameDialog.showInputNameDialog
import com.base.scanqr.utils.BarUtils
import com.base.scanqr.utils.BitmapUtils.saveBitmapToFile
import com.base.scanqr.utils.ClipboardUtils.copyText
import com.base.scanqr.utils.IntentUtils.intentShareImage
import com.base.scanqr.utils.LogEx
import com.base.scanqr.utils.QRCodeUtils.generateEAN13Barcode
import com.base.scanqr.utils.SpJsonUtils
import com.base.scanqr.utils.ToastUtils.toast
import com.google.gson.Gson
import java.io.File
/**
* https://juejin.cn/post/6844904163755687944
* EAN-13 格式
*/
class ProductCodeActivity : BaseActivity<ActivityProductCodeBinding>(ActivityProductCodeBinding::inflate) {
private var productUIBean = ProductUIBean()
private var tempImage: String = ""
override fun initView() {
super.initView()
binding.clTop.updatePadding(top = BarUtils.getStatusBarHeight())
val data = intent.extras?.getString("data")
data?.let {
productUIBean = Gson().fromJson(data, ProductUIBean::class.java)
binding.tvContent.text = productUIBean.content
}
Thread {
val bitmap = generateEAN13Barcode(productUIBean.content, 648, 255)
runOnUiThread {
binding.ivQr.setImageBitmap(bitmap)
val file = File(cacheDir, System.currentTimeMillis().toString() + ".jpg")
bitmap?.let {
val flag = saveBitmapToFile(it, file.absolutePath)
LogEx.logDebug(TAG, "flag=$flag tempImage=${file.absolutePath}")
if (flag) {
tempImage = file.absolutePath
}
}
if (productUIBean.needCreate) {
productUIBean.needCreate = false
SpJsonUtils.addJsonBean<ProductUIBean>(FunctionUIBean.KEY_PRODUCT, productUIBean)
}
}
}.start()
}
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback {
finishToMainTop()
}
binding.flBack.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
binding.llShare.setOnClickListener {
val intent = intentShareImage(this, tempImage)
runCatching {
startActivity(intent)
}
}
binding.llDownload.setOnClickListener {
kotlin.runCatching {
val appFile = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
this.resources.getString(R.string.app_name)
)
if (!appFile.exists()) appFile.mkdirs()
var newName = File(tempImage).name
showInputNameDialog(newName) { name ->
if (name.endsWith(".jpg")) {
name.also { newName = it }
} else {
newName = "$name.jpg"
}
val downFile = File(appFile, newName)
downFile.createNewFile()
File(tempImage).copyTo(downFile, true)
toast("Save to:${appFile.absolutePath}", true)
}
}
}
binding.llCopy.setOnClickListener {
copyText(TAG, productUIBean.content)
toast("Copied to clipboard", true)
}
binding.flSearch.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW)
intent.setData(Uri.parse("https://www.google.com/search?q=${productUIBean.content}"))
try {
startActivity(intent)
} catch (e: ActivityNotFoundException) {
toast("")
Toast.makeText(this, "No application was found to handle the search request", Toast.LENGTH_SHORT).show()
}
}
}
}
\ No newline at end of file
...@@ -14,6 +14,7 @@ import com.base.scanqr.utils.BarUtils ...@@ -14,6 +14,7 @@ import com.base.scanqr.utils.BarUtils
import com.base.scanqr.utils.BitmapUtils.saveBitmapToFile import com.base.scanqr.utils.BitmapUtils.saveBitmapToFile
import com.base.scanqr.utils.ClipboardUtils.copyText import com.base.scanqr.utils.ClipboardUtils.copyText
import com.base.scanqr.utils.IntentUtils.intentShareImage import com.base.scanqr.utils.IntentUtils.intentShareImage
import com.base.scanqr.utils.IntentUtils.intentViewHttp
import com.base.scanqr.utils.LogEx import com.base.scanqr.utils.LogEx
import com.base.scanqr.utils.QRCodeUtils.generateQRCode import com.base.scanqr.utils.QRCodeUtils.generateQRCode
import com.base.scanqr.utils.SpJsonUtils import com.base.scanqr.utils.SpJsonUtils
...@@ -96,7 +97,12 @@ class WebsiteCodeActivity : BaseActivity<ActivityWebsiteCodeBinding>(ActivityWeb ...@@ -96,7 +97,12 @@ class WebsiteCodeActivity : BaseActivity<ActivityWebsiteCodeBinding>(ActivityWeb
toast("Copied to clipboard", true) toast("Copied to clipboard", true)
} }
binding.flSearch.setOnClickListener { binding.flSearch.setOnClickListener {
val intent = intentViewHttp(websiteUIBean.http)
try {
startActivity(intent)
} catch (e: Exception) {
toast("No application was found to handle the http view", true)
}
} }
} }
......
...@@ -77,4 +77,10 @@ object IntentUtils { ...@@ -77,4 +77,10 @@ object IntentUtils {
emailIntent.putExtra(Intent.EXTRA_TEXT, emailUIBean.message) // 替换为邮件内容 emailIntent.putExtra(Intent.EXTRA_TEXT, emailUIBean.message) // 替换为邮件内容
return Intent.createChooser(emailIntent, "Select your mail client") return Intent.createChooser(emailIntent, "Select your mail client")
} }
fun intentViewHttp(url: String): Intent {
val intent = Intent(Intent.ACTION_VIEW)
intent.setData(Uri.parse(url))
return intent
}
} }
\ No newline at end of file
package com.base.scanqr.utils package com.base.scanqr.utils
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.graphics.Paint
import com.base.scanqr.bean.EmailUIBean import com.base.scanqr.bean.EmailUIBean
import com.base.scanqr.bean.ScanBean.Companion.CREATE_TYPE_SCAN import com.base.scanqr.bean.ScanBean.Companion.CREATE_TYPE_SCAN
import com.base.scanqr.bean.WebsiteUIBean import com.base.scanqr.bean.WebsiteUIBean
...@@ -11,6 +13,7 @@ import com.google.zxing.BarcodeFormat ...@@ -11,6 +13,7 @@ import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType import com.google.zxing.EncodeHintType
import com.google.zxing.WriterException import com.google.zxing.WriterException
import com.google.zxing.common.BitMatrix import com.google.zxing.common.BitMatrix
import com.google.zxing.oned.EAN13Writer
import com.google.zxing.qrcode.QRCodeWriter import com.google.zxing.qrcode.QRCodeWriter
object QRCodeUtils { object QRCodeUtils {
...@@ -67,6 +70,34 @@ object QRCodeUtils { ...@@ -67,6 +70,34 @@ object QRCodeUtils {
return null return null
} }
fun generateEAN13Barcode(content: String, width: Int, height: Int): Bitmap? {
val writer = EAN13Writer()
val hints = HashMap<EncodeHintType, Any>()
hints[EncodeHintType.CHARACTER_SET] = "UTF-8"
try {
val bitMatrix: BitMatrix = writer.encode(content, BarcodeFormat.EAN_13, width, height, hints)
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
bitmap.setHasAlpha(true)
val canvas = Canvas(bitmap)
val paint = Paint()
paint.color = Color.BLACK
paint.style = Paint.Style.FILL
for (x in 0 until width) {
for (y in 0 until height) {
if (bitMatrix[x, y]) {
canvas.drawRect(x.toFloat(), y.toFloat(), (x + 1).toFloat(), (y + 1).toFloat(), paint)
}
}
}
return bitmap
} catch (e: WriterException) {
throw RuntimeException(e)
}
}
private fun getPairKeyValue(keyValue: String): Pair<String, String> { private fun getPairKeyValue(keyValue: String): Pair<String, String> {
val split = keyValue.split(":") val split = keyValue.split(":")
var key = "" var key = ""
......
This diff is collapsed.
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
android:textSize="16sp" /> android:textSize="16sp" />
<EditText <EditText
android:text="http://"
android:id="@+id/edit" android:id="@+id/edit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="52dp" android:layout_height="52dp"
......
...@@ -49,4 +49,5 @@ ...@@ -49,4 +49,5 @@
<string name="delete_qrcode">Delete QRCode</string> <string name="delete_qrcode">Delete QRCode</string>
<string name="do_you_want_delete_item">Do you want delete item?</string> <string name="do_you_want_delete_item">Do you want delete item?</string>
<string name="loading">Loading</string> <string name="loading">Loading</string>
<string name="product">Product</string>
</resources> </resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment