Commit edafd42c authored by wanglei's avatar wanglei

...

parent fe2a3a48
......@@ -22,6 +22,7 @@ class FunctionUIBean(
const val KEY_TELEPHONE = "key_telephone"
const val KEY_MESSAGE = "key_message"
const val KEY_PRODUCT = "key_product"
const val KEY_FOOD = "key_food"
const val KEY_WHATSAPP = "key_whatsapp"
const val KEY_FACEBOOK = "key_facebook"
......
package com.base.scanqrclear.bean
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_FOOD
data class OpenFoodBean(
val image_front_url: String,
val product_name: String,
val ingredients_text: String,//成分
val product_quantity: Int,//500
val product_quantity_unit: String,//ml
val nutriscore_grade: String,// a 等级
val nova_groups: String? = null,
val nova_groups_tags: Array<String>,
) : ScanBean(KEY_FOOD) {
var qrString: String = ""
val dataSource: String = ""
}
\ No newline at end of file
......@@ -5,6 +5,8 @@ import android.graphics.Color
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.view.View
import androidx.activity.addCallback
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import com.base.scanqrclear.R
......@@ -13,6 +15,7 @@ import com.base.scanqrclear.base.BaseActivity
import com.base.scanqrclear.bean.FacebookUIBean
import com.base.scanqrclear.bean.FacebookUIBean.Companion.createFacebookQrString
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_FACEBOOK
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_FOOD
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_INSTAGRAM
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_PAYPAL
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_SPOTIFY
......@@ -20,6 +23,7 @@ import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_WHATSAPP
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_X
import com.base.scanqrclear.bean.InstagramUIBean
import com.base.scanqrclear.bean.InstagramUIBean.Companion.createInstagramQrString
import com.base.scanqrclear.bean.OpenFoodBean
import com.base.scanqrclear.bean.PaypalUIBean
import com.base.scanqrclear.bean.PaypalUIBean.Companion.createPaypalQrString
import com.base.scanqrclear.bean.ScanBean
......@@ -34,7 +38,9 @@ import com.base.scanqrclear.utils.BarUtils
import com.base.scanqrclear.utils.BitmapUtils.saveBitmapToFile
import com.base.scanqrclear.utils.KotlinExt.toFormatTime6
import com.base.scanqrclear.utils.LogEx
import com.base.scanqrclear.utils.QRCodeUtils.generateEAN13Barcode
import com.base.scanqrclear.utils.QRCodeUtils.generateQRCode
import com.bumptech.glide.Glide
import com.google.gson.Gson
import com.gyf.immersionbar.ktx.immersionBar
import java.io.File
......@@ -58,13 +64,28 @@ class QrResultsActivity : BaseActivity<ActivityQrResultsBinding>(ActivityQrResul
val data = intent.extras?.getString("data") ?: ""
when (scanType) {
KEY_FOOD -> {
bean = Gson().fromJson(data, OpenFoodBean::class.java)
qrString = (bean as OpenFoodBean).qrString
binding.cardFood.visibility = View.VISIBLE
binding.llOperation2.visibility = View.GONE
binding.flAd.visibility = View.VISIBLE
binding.flAd2.visibility = View.INVISIBLE
Glide.with(this).load((bean as OpenFoodBean).image_front_url).into(binding.ivFood)
binding.tvIngredients.text = (bean as OpenFoodBean).ingredients_text
qrTitle = "Barcode:"
createNormalContent()
generateEAN()
}
KEY_WHATSAPP -> {
bean = Gson().fromJson(data, WhatsappUIBean::class.java)
qrString = (bean as WhatsappUIBean).createWhatsappQrString()
binding.ivQrIcon.setImageResource(R.mipmap.h_whatsapp)
binding.tvQrTypeTitle.text = "Whatsapp"
title = "Phone number:"
qrTitle = "Phone number:"
createNormalContent()
generateQR()
}
KEY_FACEBOOK -> {
......@@ -72,8 +93,9 @@ class QrResultsActivity : BaseActivity<ActivityQrResultsBinding>(ActivityQrResul
qrString = (bean as FacebookUIBean).createFacebookQrString()
binding.ivQrIcon.setImageResource(R.mipmap.h_facebook)
binding.tvQrTypeTitle.text = "Facebook"
title = "Content:"
qrTitle = "Content:"
createNormalContent()
generateQR()
}
KEY_INSTAGRAM -> {
......@@ -81,8 +103,9 @@ class QrResultsActivity : BaseActivity<ActivityQrResultsBinding>(ActivityQrResul
qrString = (bean as InstagramUIBean).createInstagramQrString()
binding.ivQrIcon.setImageResource(R.mipmap.h_instagram)
binding.tvQrTypeTitle.text = "Instagram"
title = "Content:"
qrTitle = "Content:"
createNormalContent()
generateQR()
}
KEY_X -> {
......@@ -92,6 +115,7 @@ class QrResultsActivity : BaseActivity<ActivityQrResultsBinding>(ActivityQrResul
binding.tvQrTypeTitle.text = "X"
qrTitle = "Content:"
createNormalContent()
generateQR()
}
KEY_PAYPAL -> {
......@@ -101,6 +125,7 @@ class QrResultsActivity : BaseActivity<ActivityQrResultsBinding>(ActivityQrResul
binding.tvQrTypeTitle.text = "Paypal"
qrTitle = "Content:"
createNormalContent()
generateQR()
}
KEY_SPOTIFY -> {
......@@ -146,12 +171,40 @@ class QrResultsActivity : BaseActivity<ActivityQrResultsBinding>(ActivityQrResul
)
binding.tvQrContent.append(ss2)
generateQR()
}
}
binding.tvTime.text = System.currentTimeMillis().toFormatTime6()
if (binding.flAd.isVisible) {
AdsMgr.showNative(binding.flAd, R.layout.layout_admob_item)
}
if (binding.flAd2.isVisible) {
AdsMgr.showNative(binding.flAd2, R.layout.layout_admob_item)
}
}
private fun generateEAN() {
Thread {
val bitmap = generateEAN13Barcode(qrString, 555, 555)
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) {
tempImagePath = file.absolutePath
}
}
}
}.start()
}
private fun generateQR() {
Thread {
LogEx.logDebug(TAG, "messageQrString=$qrString")
val bitmap = generateQRCode(qrString, 735, 735, 2)
......@@ -167,13 +220,6 @@ class QrResultsActivity : BaseActivity<ActivityQrResultsBinding>(ActivityQrResul
}
}
}.start()
if (binding.flAd.isVisible) {
AdsMgr.showNative(binding.flAd, R.layout.layout_admob_item)
}
if (binding.flAd2.isVisible) {
AdsMgr.showNative(binding.flAd2, R.layout.layout_admob_item)
}
}
private fun createNormalContent() {
......@@ -199,6 +245,13 @@ class QrResultsActivity : BaseActivity<ActivityQrResultsBinding>(ActivityQrResul
@SuppressLint("SetTextI18n")
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback {
finishToMainTop()
}
binding.flBack.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
}
override fun configSystemBar() {
......
......@@ -3,7 +3,6 @@ package com.base.scanqrclear.qr
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Point
import androidx.annotation.ColorInt
......@@ -77,7 +76,7 @@ object QrStyleUtils {
// 1. 计算二维码的宽度和高度
val size = calculateQRSize(points)
// 2. 生成二维码
val qrCodeBitmap = createQRCodeBitmap(content, size.first, size.second, qrColor,qrBgColor)
val qrCodeBitmap = createQRCodeBitmap(content, size.first, size.second, qrColor, qrBgColor)
qrCodeBitmap?.let {
// 3. 计算旋转角度
......
......@@ -30,6 +30,7 @@ import com.base.scanqrclear.ui.widget.AppExitDialog.showAppExitDialog
import com.base.scanqrclear.ui.widget.NotificationDialog.showNotificationTurnOn
import com.base.scanqrclear.utils.AppPreferences
import com.base.scanqrclear.utils.LogEx
import com.base.scanqrclear.utils.OpenFoodFactsUtils
import com.base.scanqrclear.utils.PermissionUtils.areNotificationsEnabled
import com.base.scanqrclear.utils.PermissionUtils.checkCameraPermission
import com.google.android.material.tabs.TabLayout
......
......@@ -23,6 +23,7 @@ import com.base.scanqrclear.bean.EventUIBean.Companion.isEventQR
import com.base.scanqrclear.bean.FacebookUIBean.Companion.createFaceBookUIBean
import com.base.scanqrclear.bean.FacebookUIBean.Companion.isFacebookQR
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_FACEBOOK
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_FOOD
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_INSTAGRAM
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_PAYPAL
import com.base.scanqrclear.bean.FunctionUIBean.Companion.KEY_SPOTIFY
......@@ -32,6 +33,7 @@ import com.base.scanqrclear.bean.InstagramUIBean.Companion.createInstagramUIBean
import com.base.scanqrclear.bean.InstagramUIBean.Companion.isInstagramQR
import com.base.scanqrclear.bean.MessageUIBean.Companion.createMessageBean
import com.base.scanqrclear.bean.MessageUIBean.Companion.isMessageQR
import com.base.scanqrclear.bean.OpenFoodBean
import com.base.scanqrclear.bean.PaypalUIBean.Companion.createPaypalUIBean
import com.base.scanqrclear.bean.PaypalUIBean.Companion.isPaypalQR
import com.base.scanqrclear.bean.ProductUIBean
......@@ -64,7 +66,9 @@ import com.base.scanqrclear.ui.website.WebsiteCodeActivity
import com.base.scanqrclear.ui.wifi.WifiCodeActivity
import com.base.scanqrclear.utils.BitmapUtils.uriToBitmap
import com.base.scanqrclear.utils.IntentUtils.intentSafPickImage
import com.base.scanqrclear.utils.KotlinExt.isNumeric
import com.base.scanqrclear.utils.LogEx
import com.base.scanqrclear.utils.OpenFoodFactsUtils.getOpenFood
import com.base.scanqrclear.utils.PermissionUtils.checkCameraPermission
import com.google.gson.Gson
import com.google.mlkit.vision.barcode.common.Barcode
......@@ -160,17 +164,31 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl
if (valueType == Barcode.TYPE_PRODUCT) {
if (scanJump.get()) return
scanJump.set(true)
var bean: OpenFoodBean? = null
if (isNumeric(qrCodeValue)) {
activity.lifecycleScope.launch(Dispatchers.IO) {
bean = getOpenFood(qrCodeValue)
bean?.qrString = qrCodeValue
}
}
val jump = {
if (bean?.qrString?.isNotEmpty() == true) {
jumpQrResultsActivity(activity, qrCodeValue, KEY_FOOD, bean)
} else {
jumpProductCodeActivity(activity, qrCodeValue)
}
}
AdsMgr.showInsert(activity, true, object : AdsShowCallBack() {
override fun close(where: Int) {
jumpProductCodeActivity(activity, qrCodeValue)
jump()
}
override fun failed(where: Int) {
jumpProductCodeActivity(activity, qrCodeValue)
jump()
}
override fun googleFailed(where: Int) {
jumpProductCodeActivity(activity, qrCodeValue)
jump()
}
})
return
......@@ -424,18 +442,35 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl
if (valueType == Barcode.TYPE_TEXT) {
if (scanJump.get()) return
scanJump.set(true)
var bean: OpenFoodBean? = null
if (isNumeric(qrCodeValue)) {
activity.lifecycleScope.launch(Dispatchers.IO) {
LogEx.logDebug(TAG, "$bean")
bean = getOpenFood(qrCodeValue)
bean?.qrString = qrCodeValue
}
}
val jump = {
if (bean?.qrString?.isNotEmpty() == true) {
jumpQrResultsActivity(activity, qrCodeValue, KEY_FOOD, bean)
} else {
jumpTextCodeActivity(activity, qrCodeValue)
}
}
AdsMgr.showInsert(activity, true, object : AdsShowCallBack() {
override fun close(where: Int) {
jumpTextCodeActivity(activity, qrCodeValue)
jump()
}
override fun failed(where: Int) {
jumpTextCodeActivity(activity, qrCodeValue)
jump()
}
override fun googleFailed(where: Int) {
jumpTextCodeActivity(activity, qrCodeValue)
jump()
}
})
return
......@@ -443,20 +478,25 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl
}
private fun jumpQrResultsActivity(activity: ScanAc, qrCodeValue: String, scanType: String) {
private fun jumpQrResultsActivity(
activity: ScanAc,
qrCodeValue: String,
scanType: String,
otherScanBean: ScanBean? = null
) {
activity.startActivity(Intent(activity, QrResultsActivity::class.java).apply {
val bean: ScanBean =
when (scanType) {
KEY_WHATSAPP -> createWhatsappUIBean(qrCodeValue)
KEY_FACEBOOK -> createFaceBookUIBean(qrCodeValue)
KEY_INSTAGRAM -> createInstagramUIBean(qrCodeValue)
KEY_X -> createXUIBean(qrCodeValue)
KEY_SPOTIFY -> createSpotifyUIBean(qrCodeValue)
KEY_PAYPAL -> createPaypalUIBean(qrCodeValue)
else -> ScanBean()
}
bean.needCreate = true
bean.createType = CREATE_TYPE_SCAN
val bean: ScanBean? = when (scanType) {
KEY_WHATSAPP -> createWhatsappUIBean(qrCodeValue)
KEY_FACEBOOK -> createFaceBookUIBean(qrCodeValue)
KEY_INSTAGRAM -> createInstagramUIBean(qrCodeValue)
KEY_X -> createXUIBean(qrCodeValue)
KEY_SPOTIFY -> createSpotifyUIBean(qrCodeValue)
KEY_PAYPAL -> createPaypalUIBean(qrCodeValue)
KEY_FOOD -> otherScanBean
else -> ScanBean()
}
bean?.needCreate = true
bean?.createType = CREATE_TYPE_SCAN
putExtra("data", Gson().toJson(bean))
putExtra("scanType", scanType)
})
......
......@@ -7,6 +7,10 @@ import java.util.Locale
object KotlinExt {
fun isNumeric(str: String): Boolean {
return str.matches("\\d+".toRegex())
}
fun Number.toFormatSize(count: Int = 1): String {
var suffix = "B"
var fSize = this.toDouble()
......
package com.base.scanqrclear.utils
import com.base.scanqrclear.bean.OpenFoodBean
import com.google.gson.Gson
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject
object OpenFoodFactsUtils {
private val TAG = "OpenFoodFactsUtils"
//https://world.openfoodfacts.org/api/v3/product/4890008100309.json
fun getOpenFood(qrCode: String): OpenFoodBean? {
try {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://world.openfoodfacts.org/api/v3/product/$qrCode.json")
.get()
.addHeader("User-Agent", "okhttp/4.10.0")
.addHeader("Accept-Encoding", "gzip")
.addHeader(
"base",
"{\"device_id\":\"8e0ca12e-1022-4d88-8b97-dd6aa3e5d4bd\",\"platform\":\"1\",\"device_model\":\"Xiaomi MI 9\",\"app_lang\":\"zh_CN\",\"sys_lang\":\"zh_CN\",\"client_version\":\"1.25.0\",\"inner_version\":10012500,\"sys_version\":\"11\",\"channel\":\"\",\"country\":\"CN\",\"time_zone\":\"GMT-6\",\"package_name\":\"com.healthapplines.scanner.ai\",\"guid\":\"8e0ca12e-1022-4d88-8b97-dd6aa3e5d4bd\",\"network_type\":\"NETWORK_WIFI\"}"
)
.addHeader("version", "10001")
.addHeader("nonce", "ckCkrQ5flf")
.addHeader("timestamp", "${System.currentTimeMillis()}")
.addHeader(
"token",
"eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhMWVjZmM1OS02Y2JkLTQwNmEtYjM4Zi01NzU2Y2ExNTY3OGQiLCJpYXQiOjE3MzcwODMzNzksInN1YiI6IjEyNzcwMDkifQ.yTdcAZ5DYC9smu6YhTkL7T2kW0CwGiP1XfX3RJUHmJM"
)
.addHeader("sign", "4B8F5E4DB16324FB6CC4A3BA2AD83E15")
.build()
val response = client.newCall(request).execute()
val body = response.body?.string() ?: ""
LogEx.logDebug(TAG, "body=$body")
val jsonObject = JSONObject(body)
val productJson = jsonObject.getJSONObject("product").toString()
val bean = Gson().fromJson(productJson, OpenFoodBean::class.java)
return bean
} catch (e: Exception) {
}
return null
}
}
\ No newline at end of file
......@@ -85,14 +85,14 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="10dp"
android:visibility="visible"
app:cardCornerRadius="5dp"
app:cardElevation="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:visibility="gone">
android:background="@color/white">
<androidx.cardview.widget.CardView
android:id="@+id/cardImage"
......@@ -105,18 +105,28 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="125dp"
android:maxHeight="166dp"
android:minWidth="100dp"
android:minHeight="120dp"
tools:ignore="ContentDescription" />
app:cardCornerRadius="10dp"
app:cardElevation="0dp"
tools:ignore="ContentDescription">
<ImageView
android:id="@+id/ivFood"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="125dp"
android:maxHeight="166dp"
android:minWidth="100dp"
android:minHeight="120dp" />
</androidx.cardview.widget.CardView>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/tvIngredients"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
......@@ -289,16 +299,26 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="13dp"
android:layout_marginTop="10dp"
android:background="@drawable/bg_f0f1f7_5"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/ivQr"
android:layout_width="95dp"
android:layout_height="95dp"
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginVertical="10dp"
tools:ignore="ContentDescription" />
android:background="@color/white"
android:padding="2dp">
<ImageView
android:id="@+id/ivQr"
android:layout_width="95dp"
android:layout_height="95dp"
android:layout_gravity="center"
tools:ignore="ContentDescription" />
</FrameLayout>
</FrameLayout>
......@@ -339,6 +359,8 @@
tools:text="2025.02.18 17:30" />
<TextView
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="@id/llOperation2"
android:id="@+id/tvQrContent"
android:layout_width="0dp"
android:layout_height="wrap_content"
......@@ -356,7 +378,6 @@
android:id="@+id/llOperation2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
......
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