作为移动开发码农,扫码功能几乎是绕不开的功能点,之前开发一般使用的是Zxing类库操作,最近发现有华为的扫码SDK可用且效果更好更好用,故记录下用Swift及Kotlin分别实现。
1. 相关资料
- 文档地址—- https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides-V5/service-introduction-0000001050041994-V5
- 代码地址—- https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Examples/android-sample-code-0000001050734383
2. Android实现
- 配置AppGallery Connect,这个直接看官方文档比较简单的,就一些个人信息或公司信息填入申请成为华为开发者
- 集成HMS Core SDK , 同样的看官方文档即可
- 配置混淆脚本, 同上,哈哈,更简单
- 权限配置
<!--相机权限-->
<uses-permission android:name="android.permission.CAMERA" />
<!--读文件权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
代码动态获取权限
import android.Manifest import android.content.Intent import android.content.pm.PackageManager import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Toast import com.huawei.hms.hmsscankit.ScanUtil import com.huawei.hms.ml.scan.HmsScan import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions import com.xlgz520.scantest.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private val rCode = 10000 private val requestCodeScan = 10001 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.scan.setOnClickListener { // 请求权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ this.requestPermissions( arrayOf(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE), rCode ) } } } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { if (grantResults.size < 2 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) return if (requestCode == rCode){ ScanUtil.startScan(this, requestCodeScan, HmsScanAnalyzerOptions.Creator().setHmsScanTypes( HmsScan.ALL_SCAN_TYPE).create()) } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { //当扫码页面结束后,处理扫码结果 super.onActivityResult(requestCode, resultCode, data) if (resultCode != RESULT_OK || data == null) return if (requestCode == requestCodeScan){ val obj: Any? = data.getParcelableExtra(ScanUtil.RESULT) if (obj is HmsScan){ if (obj.getOriginalValue().isNotEmpty()){ // 这里就获取到了扫描结果,本demo只做了最简单的扫码功能,更多使用情况请查看上面的官方文档 Toast.makeText(this, obj.getOriginalValue(), Toast.LENGTH_SHORT).show() } return } } } }
3. iOS实现
集成HMS Core SDK,本文使用的是cocoapods方式安装
pod 'ScanKitFrameWork', '~> 1.0.2.300'
指定权限,打开项目的info.plist文件,增加以下权限
<key>NSCameraUsageDescription</key> <string>请允许APP访问您的相机</string> <key>NSPhotoLibraryUsageDescription</key> <string>请允许APP访问您的相册</string>
代码实现
func initV(){ let btn = UIButton() self.view.addSubview(btn) // 这里使用的snapkit布局 btn.snp.makeConstraints { make in make.center.equalTo(self.view.snp.center) make.width.equalTo(80) make.height.equalTo(35) } btn.backgroundColor = .red btn.setTitleColor(.white, for: .normal) btn.setTitle("点我扫码", for: UIControlState.normal) btn.addTarget(self, action: #selector(scan), for: .touchUpInside) } @objc func scan(){ //"QR_CODE | DATA_MATRIX"表示只扫描QR和DataMatrix的码 let options = HmsScanOptions.init(scanFormatType: UInt32(HMSScanFormatTypeCode.QR_CODE.rawValue | HMSScanFormatTypeCode.DATA_MATRIX.rawValue), photo: false) let scanVc = HmsDefaultScanViewController(defaultScanWithFormatType: options)! scanVc.defaultScanDelegate = self self.view.addSubview(scanVc.view) self.addChildViewController(scanVc) //隐藏导航栏 self.navigationController?.isNavigationBarHidden = false } // 扫描本地图片返回结果 func defaultScanImagePickerDelegate(for image: UIImage!) { DispatchQueue.main.async { //在主线程内处理数据 } } // 扫描结果 func defaultScanDelegate(forDicResult resultDic: [AnyHashable : Any]!) { DispatchQueue.main.async { /** ResultPoint = ( { posX = "323.595001"; posY = "600.075012"; }, { posX = "321.975006"; posY = "316.575012"; }, { posX = "607.905029"; posY = "327.1050011"; }, { posX = "609.525024"; posY = "610.605042"; } ); //曝光值 exposureAdjustmentValue = 0; //码制 formatvalue = "QR_CODE"; //放大倍数 zoomValue = 1.0; //场景类型 sceneType = Text; //码值 text = ssssss */ //在主线程内处理数据 上面注释的就是返回的字典里可取出的各项相关数据 print(resultDic["text"] as! String) } }