Kotlin을 사용하여 KnowMyBoard에 Huawei Map Kit 및 Location Kit 통합 3부
소개
이 기사에서는 Huawei ML 키트, 지도 키트 및 위치 키트를 Android 애플리케이션 KnowMyBoard에 통합하는 방법을 알아봅니다. Account Kit는 대규모 사용자 기반의 앱에 원활한 로그인 기능을 제공합니다.
Android용 위치 키트 SDK는 Android 앱용 위치 관련 API를 제공합니다. 이러한 API는 주로 융합 위치, 활동 식별, 지오펜스, 고정밀 위치, 실내 위치 및 지오코딩과 같은 6가지 기능과 관련됩니다. 이 모드는 휴대폰 및 Huawei 태블릿에 적용됩니다. 우리는 사용자의 위치를 얻기 위해 위치 키트를 사용하고 있습니다.
Android용 Huawei Map SDK는 지도를 개발하기 위해 호출할 수 있는 일련의 API입니다. 이 SDK를 사용하여 지도 표시, 지도 상호 작용, 지도 그리기 및 지도 스타일 사용자 지정을 포함하여 지도 관련 기능을 Android 앱에 쉽게 추가할 수 있습니다.
지원되는 국가/지역
Supported Countries/Regions
개발 개요
Android Studio IDE를 설치해야 하며 Android 애플리케이션 개발에 대한 사전 지식이 있다고 가정합니다.
하드웨어 요구 사항
Windows 10을 실행하는 컴퓨터(데스크탑 또는 노트북).
디버깅에 사용되는 Android 휴대폰(USB 케이블 포함).
소프트웨어 요구 사항
자바 JDK 1.8 이상.
Android Studio 소프트웨어 또는 Visual Studio 또는 Code가 설치되었습니다.
HMS 코어(APK) 4.X 이상
통합 단계
1단계. Huawei 개발자 계정 및 Huawei 개발자 웹사이트에서 신원 확인을 완료하려면 Huawei ID 등록을 참조하십시오.
2단계. AppGallery Connect에서 프로젝트 생성
3단계. HMS Core SDK 추가
코딩을 시작하자
MainActivity.kt
package com.huawei.hms.knowmyboard.dtse.activity.view
import androidx.navigation.Navigation.findNavController
import androidx.navigation.ui.NavigationUI.setupWithNavController
import com.huawei.hms.knowmyboard.dtse.activity.viewmodel.LoginViewModel
import android.graphics.Bitmap
import com.huawei.hms.mlsdk.langdetect.local.MLLocalLangDetector
import com.huawei.hms.mlsdk.translate.local.MLLocalTranslator
import android.app.ProgressDialog
import androidx.navigation.NavController
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.huawei.hms.knowmyboard.dtse.activity.app.MyApplication
import android.content.Intent
import com.huawei.hms.support.account.AccountAuthManager
import android.provider.MediaStore
import com.huawei.hmf.tasks.OnSuccessListener
import com.huawei.hms.mlsdk.langdetect.MLLangDetectorFactory
import com.huawei.hms.mlsdk.langdetect.local.MLLocalLangDetectorSetting
import com.huawei.hmf.tasks.OnFailureListener
import android.content.DialogInterface
import android.net.Uri
import android.util.Log
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.huawei.hms.common.ApiException
import com.huawei.hms.knowmyboard.dtse.R
import com.huawei.hms.knowmyboard.dtse.activity.model.UserData
import com.huawei.hms.knowmyboard.dtse.activity.util.Constants
import com.huawei.hms.knowmyboard.dtse.databinding.ActivityMainBinding
import com.huawei.hms.mlsdk.MLAnalyzerFactory
import com.huawei.hms.mlsdk.common.MLApplication
import com.huawei.hms.mlsdk.common.MLFrame
import com.huawei.hms.mlsdk.translate.local.MLLocalTranslateSetting
import com.huawei.hms.mlsdk.translate.MLTranslatorFactory
import com.huawei.hms.mlsdk.model.download.MLModelDownloadStrategy
import com.huawei.hms.mlsdk.model.download.MLModelDownloadListener
import com.huawei.hms.mlsdk.text.MLLocalTextSetting
import com.huawei.hms.mlsdk.text.MLText
import com.huawei.hms.mlsdk.text.MLTextAnalyzer
import java.io.IOException
import java.lang.Exception
import java.util.ArrayList
class MainActivity() : AppCompatActivity() {
var loginViewModel: LoginViewModel? = null
private var mTextAnalyzer: MLTextAnalyzer? = null
var imagePath: Uri? = null
var bitmap: Bitmap? = null
var result = ArrayList<String>()
var myLocalLangDetector: MLLocalLangDetector? = null
var myLocalTranslator: MLLocalTranslator? = null
var textRecognized: String? = null
var progressDialog: ProgressDialog? = null
var navController: NavController? = null
var activityMainBinding: ActivityMainBinding? = null
var bottomNavigationView: BottomNavigationView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding =
DataBindingUtil.setContentView(this@MainActivity, R.layout.activity_main)
loginViewModel = ViewModelProvider(this@MainActivity).get(
LoginViewModel::class.java
)
navController = findNavController(this@MainActivity, R.id.nav_host_fragment)
MyApplication.activity = this
progressDialog = ProgressDialog(this)
progressDialog!!.setCancelable(false)
bottomNavigationView = activityMainBinding!!.bottomNavigation
setupWithNavController(bottomNavigationView!!, navController!!)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
// Process the authorization result to obtain the authorization code from AuthAccount.
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1234) {
Log.e("TAG", " Result can be pulled")
}
if (requestCode == 8888) {
val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data)
if (authAccountTask.isSuccessful) {
// The sign-in is successful, and the user's ID information and authorization code are obtained.
val authAccount = authAccountTask.result
val userData = UserData()
userData.accessToken = authAccount.accessToken
userData.countryCode = authAccount.countryCode
userData.displayName = authAccount.displayName
userData.email = authAccount.email
userData.familyName = authAccount.familyName
userData.givenName = authAccount.givenName
userData.idToken = authAccount.idToken
userData.openId = authAccount.openId
userData.uid = authAccount.uid
userData.photoUriString = authAccount.avatarUri.toString()
userData.unionId = authAccount.unionId
loginViewModel = ViewModelProvider(this@MainActivity).get(
LoginViewModel::class.java
)
loginViewModel!!.sendData(authAccount.displayName)
} else {
// The sign-in failed.
Log.e(
"TAG",
"sign in failed:" + (authAccountTask.exception as ApiException).statusCode
)
}
}
if ((requestCode == 2323) && (resultCode == RESULT_OK) && (data != null)) {
progressDialog!!.setMessage("Initializing text detection..")
progressDialog!!.show()
imagePath = data.data
try {
bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, imagePath)
asyncAnalyzeText(bitmap)
} catch (e: IOException) {
e.printStackTrace()
Log.e("TAG", " BITMAP ERROR")
}
}
if ((requestCode == 2424) && (resultCode == RESULT_OK) && (data != null)) {
progressDialog!!.setMessage("Initializing text detection..")
progressDialog!!.show()
try {
bitmap = data.extras!!["data"] as Bitmap?
asyncAnalyzeText(bitmap)
} catch (e: Exception) {
e.printStackTrace()
Log.e("TAG", " BITMAP ERROR")
}
}
}
private fun asyncAnalyzeText(bitmap: Bitmap?) {
if (mTextAnalyzer == null) {
createMLTextAnalyzer()
}
val frame = MLFrame.fromBitmap(bitmap)
val task = mTextAnalyzer!!.asyncAnalyseFrame(frame)
task.addOnSuccessListener(object : OnSuccessListener<MLText> {
override fun onSuccess(text: MLText) {
progressDialog!!.setMessage("Initializing language detection..")
textRecognized = text.stringValue.trim { it <= ' ' }
if (!textRecognized!!.isEmpty()) {
// Create a local language detector.
val factory = MLLangDetectorFactory.getInstance()
val setting =
MLLocalLangDetectorSetting.Factory() // Set the minimum confidence threshold for language detection.
.setTrustedThreshold(0.01f)
.create()
myLocalLangDetector = factory.getLocalLangDetector(setting)
val firstBestDetectTask = myLocalLangDetector!!.firstBestDetect(textRecognized)
firstBestDetectTask.addOnSuccessListener(OnSuccessListener { languageDetected ->
progressDialog!!.setMessage("Initializing text translation..")
// Processing logic for detection success.
textTranslate(languageDetected, textRecognized!!, bitmap)
}).addOnFailureListener(object : OnFailureListener {
override fun onFailure(e: Exception) {
// Processing logic for detection failure.
Log.e("TAG", "Lang detect error:" + e.message)
}
})
} else {
progressDialog!!.dismiss()
showErrorDialog("Failed to recognize text.")
}
}
}).addOnFailureListener(object : OnFailureListener {
override fun onFailure(e: Exception) {
Log.e("TAG", "#==>" + e.message)
}
})
}
private fun showErrorDialog(msg: String) {
val alertDialog = AlertDialog.Builder(this).create()
alertDialog.setTitle("Error")
alertDialog.setMessage(msg)
alertDialog.setButton(
AlertDialog.BUTTON_POSITIVE,
"OK",
object : DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface, which: Int) {
dialog.dismiss()
}
})
alertDialog.show()
}
private fun textTranslate(languageDetected: String, textRecognized: String, uri: Bitmap?) {
MLApplication.initialize(application)
MLApplication.getInstance().apiKey = Constants.API_KEY
// Create an offline translator.
val setting =
MLLocalTranslateSetting.Factory() // Set the source language code. The ISO 639-1 standard is used. This parameter is mandatory. If this parameter is not set, an error may occur.
.setSourceLangCode(languageDetected) // Set the target language code. The ISO 639-1 standard is used. This parameter is mandatory. If this parameter is not set, an error may occur.
.setTargetLangCode("en")
.create()
myLocalTranslator = MLTranslatorFactory.getInstance().getLocalTranslator(setting)
// Set the model download policy.
val downloadStrategy = MLModelDownloadStrategy.Factory()
.needWifi() // It is recommended that you download the package in a Wi-Fi environment.
.create()
// Create a download progress listener.
val modelDownloadListener: MLModelDownloadListener = object : MLModelDownloadListener {
override fun onProcess(alreadyDownLength: Long, totalLength: Long) {
runOnUiThread(object : Runnable {
override fun run() {
// Display the download progress or perform other operations.
}
})
}
}
myLocalTranslator!!.preparedModel(downloadStrategy, modelDownloadListener)
.addOnSuccessListener(object : OnSuccessListener<Void?> {
override fun onSuccess(aVoid: Void?) {
// Called when the model package is successfully downloaded.
// input is a string of less than 5000 characters.
val task = myLocalTranslator!!.asyncTranslate(textRecognized)
// Before translation, ensure that the models have been successfully downloaded.
task.addOnSuccessListener(object : OnSuccessListener<String> {
override fun onSuccess(translated: String) {
// Processing logic for detection success.
result.clear()
result.add(languageDetected.trim { it <= ' ' })
result.add(textRecognized.trim { it <= ' ' })
result.add(translated.trim { it <= ' ' })
loginViewModel!!.setImage(uri!!)
loginViewModel!!.setTextRecongnized(result)
progressDialog!!.dismiss()
}
}).addOnFailureListener(object : OnFailureListener {
override fun onFailure(e: Exception) {
// Processing logic for detection failure.
progressDialog!!.dismiss()
}
})
}
}).addOnFailureListener(object : OnFailureListener {
override fun onFailure(e: Exception) {
// Called when the model package fails to be downloaded.
progressDialog!!.dismiss()
}
})
}
private fun createMLTextAnalyzer() {
val setting = MLLocalTextSetting.Factory()
.setOCRMode(MLLocalTextSetting.OCR_DETECT_MODE)
.create()
mTextAnalyzer = MLAnalyzerFactory.getInstance().getLocalTextAnalyzer(setting)
}
override fun onStop() {
if (myLocalLangDetector != null) {
myLocalLangDetector!!.stop()
}
if (myLocalTranslator != null) {
myLocalTranslator!!.stop()
}
if (progressDialog != null) {
progressDialog!!.dismiss()
}
super.onStop()
}
companion object {
var TAG = "TAG"
}
}
결과
트릭과 팁
agconnect-services.json 파일이 추가되었는지 확인합니다.
필수 종속 항목이 추가되었는지 확인
AGC에서 서비스가 활성화되어 있는지 확인하십시오.
gradle.build 파일에서 데이터 바인딩 활성화
하단 탐색 ID가 탐색 그래프의 프래그먼트 ID와 동일해야 합니다.
결론
이 기사에서는 Android 애플리케이션 KnowMyBoard에서 Huawei Map 키트, Location 키트를 통합하는 방법을 배웠습니다. 이 샘플과 같이 지도 키트 기능이 도움이 되기를 바라며 요구 사항에 따라 지도 키트를 사용할 수 있습니다.
읽어주셔서 정말 감사합니다. 이 기사가 Android 애플리케이션 KnowMyBoard에서 Huawei 지도 키트와 위치 키트의 통합을 이해하는 데 도움이 되기를 바랍니다.
참조
Map Kit – Training video
Location Kit – Training video
Reference
이 문제에 관하여(Kotlin을 사용하여 KnowMyBoard에 Huawei Map Kit 및 Location Kit 통합 3부), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/hmscommunity/integration-of-huawei-map-kit-and-location-kit-in-knowmyboard-using-kotlin-part-3-362f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)