<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: HMS Community</title>
    <description>The latest articles on DEV Community by HMS Community (@hmscommunity).</description>
    <link>https://dev.to/hmscommunity</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F827307%2F9bd3f633-4ee5-4e97-a76c-d1d0e6ec9434.jpg</url>
      <title>DEV Community: HMS Community</title>
      <link>https://dev.to/hmscommunity</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hmscommunity"/>
    <language>en</language>
    <item>
      <title>Find hand points using Hand Gesture Recognition feature by Huawei ML Kit in Android (Kotlin)</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Tue, 13 Sep 2022 10:15:42 +0000</pubDate>
      <link>https://dev.to/hmscommunity/find-hand-points-using-hand-gesture-recognition-feature-by-huawei-ml-kit-in-android-kotlin-2kcp</link>
      <guid>https://dev.to/hmscommunity/find-hand-points-using-hand-gesture-recognition-feature-by-huawei-ml-kit-in-android-kotlin-2kcp</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dzbqPqPM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0iotn20awodnvba5umlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dzbqPqPM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0iotn20awodnvba5umlf.png" alt="Image description" width="880" height="639"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we can learn how to find the hand key points using &lt;strong&gt;Huawei ML Kit&lt;/strong&gt; of &lt;strong&gt;Hand Gesture Recognition&lt;/strong&gt; feature. This service provides two capabilities: &lt;strong&gt;hand keypoint detection&lt;/strong&gt; and hand gesture recognition. The hand keypoint detection capability can detect &lt;strong&gt;21&lt;/strong&gt; hand keypoints (including fingertips, knuckles, and wrists) and return the positions of the key points. The hand gesture recognition capability can &lt;strong&gt;detect&lt;/strong&gt; and &lt;strong&gt;return&lt;/strong&gt; the positions of all rectangle areas of the hand from images and videos, and the type and confidence of a gesture. This capability can recognize &lt;strong&gt;14&lt;/strong&gt; gestures, including the thumbs-up/down, OK sign, fist, finger heart, and number gestures from &lt;strong&gt;1&lt;/strong&gt; to &lt;strong&gt;9&lt;/strong&gt;. Both capabilities support detection from static images and real-time camera streams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hand keypoint detection is widely used in daily life. For example, after integrating this capability, users can convert the detected hand keypoints into a &lt;strong&gt;2D&lt;/strong&gt; model, and synchronize the model to the character model, to produce a vivid 2D animation. In addition, when shooting a short video, special effects can be generated based on dynamic hand trajectories. This allows users to play finger games, thereby making the video shooting process more creative and interactive. Hand gesture recognition enables your app to call various commands by recognizing users' gestures. Users can control their smart home appliances without touching them. In this way, this capability makes the human-machine interaction more efficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Any operating system (MacOS, Linux and Windows).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a Huawei phone with HMS 4.0.0.300 or later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimum API Level 21 is required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required EMUI 9.0.0 and later version devices.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to integrate HMS Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a &lt;a href="https://developer.huawei.com/consumer/en/doc/start/registration-and-verification-0000001053628148"&gt;Huawei ID&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a project in android studio, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#1"&gt;Creating an Android Studio Project&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To generate &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;. On right-upper corner of android project click &lt;strong&gt;Gradle&lt;/strong&gt;, choose &lt;strong&gt;Project Name &amp;gt; Tasks &amp;gt; android&lt;/strong&gt;, and then click &lt;strong&gt;signingReport&lt;/strong&gt;, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gz-PoET2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9e3fueyuvdr9y753k1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gz-PoET2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9e3fueyuvdr9y753k1b.png" alt="Image description" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Project Name depends on the user created name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#0"&gt;Create an App in AppGallery Connect&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;strong&gt;agconnect-services.json&lt;/strong&gt; file from &lt;strong&gt;App information&lt;/strong&gt;, &lt;strong&gt;copy&lt;/strong&gt; and &lt;strong&gt;paste&lt;/strong&gt; in android Project under app directory, as follows.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ZgEGSLT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ad59nniswh2kzuboh041.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ZgEGSLT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ad59nniswh2kzuboh041.png" alt="Image description" width="464" height="616"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt; and click &lt;strong&gt;Save&lt;/strong&gt; button, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k3uE3emd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/otre7g2axuq08zknuiyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k3uE3emd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/otre7g2axuq08zknuiyz.png" alt="Image description" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Manage APIs&lt;/strong&gt; tab and enable &lt;strong&gt;ML Kit&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FLISCXLf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k9srtrutbnqn7h9chcec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FLISCXLf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k9srtrutbnqn7h9chcec.png" alt="Image description" width="880" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the below maven URL in &lt;strong&gt;build.gradle(Project)&lt;/strong&gt; file under the repositories of buildscript, dependencies and allprojects, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#6"&gt;Add Configuration&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.4.1.300'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add the below plugin and dependencies in &lt;strong&gt;build.gradle(Module)&lt;/strong&gt; file.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apply plugin: 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.5.300'
/ ML Kit Hand Gesture
// Import the base SDK
implementation 'com.huawei.hms:ml-computer-vision-handkeypoint:2.1.0.300'
// Import the hand keypoint detection model package.
implementation 'com.huawei.hms:ml-computer-vision-handkeypoint-model:2.1.0.300'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now Sync the gradle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the required permission to the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.CAMERA" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.INTERNET" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Let us move to development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have created a project on Android studio with empty activity let us start coding.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;MainActivity.kt&lt;/strong&gt; we can find the business logic for buttons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MainActivity : AppCompatActivity() {

    private var staticButton: Button? = null
    private var liveButton: Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        staticButton = findViewById(R.id.btn_static)
        liveButton = findViewById(R.id.btn_live)

        staticButton!!.setOnClickListener {
            val intent = Intent(this@MainActivity, StaticHandKeyPointAnalyse::class.java)
            startActivity(intent)
        }
        liveButton!!.setOnClickListener {
            val intent = Intent(this@MainActivity, LiveHandKeyPointAnalyse::class.java)
            startActivity(intent)
        }

    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;LiveHandKeyPointAnalyse.kt&lt;/strong&gt; we can find the business logic for live analysis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LiveHandKeyPointAnalyse : AppCompatActivity(), View.OnClickListener {

    private val TAG: String = LiveHandKeyPointAnalyse::class.java.getSimpleName()
    private var mPreview: LensEnginePreview? = null
    private var mOverlay: GraphicOverlay? = null
    private var mFacingSwitch: Button? = null
    private var mAnalyzer: MLHandKeypointAnalyzer? = null
    private var mLensEngine: LensEngine? = null
    private val lensType = LensEngine.BACK_LENS
    private var mLensType = 0
    private var isFront = false
    private var isPermissionRequested = false
    private val CAMERA_PERMISSION_CODE = 0
    private val ALL_PERMISSION = arrayOf(Manifest.permission.CAMERA)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_live_hand_key_point_analyse)

        if (savedInstanceState != null) {
            mLensType = savedInstanceState.getInt("lensType")
        }
        initView()
        createHandAnalyzer()
        if (Camera.getNumberOfCameras() == 1) {
            mFacingSwitch!!.visibility = View.GONE
        }
        // Checking Camera Permissions
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            createLensEngine()
        } else {
            checkPermission()
        }


    }


    private fun initView() {
        mPreview = findViewById(R.id.hand_preview)
        mOverlay = findViewById(R.id.hand_overlay)
        mFacingSwitch = findViewById(R.id.handswitch)
        mFacingSwitch!!.setOnClickListener(this)
    }

    private fun createHandAnalyzer() {
        // Create a  analyzer. You can create an analyzer using the provided customized face detection parameter: MLHandKeypointAnalyzerSetting
        val setting = MLHandKeypointAnalyzerSetting.Factory()
            .setMaxHandResults(2)
            .setSceneType(MLHandKeypointAnalyzerSetting.TYPE_ALL)
            .create()
        mAnalyzer = MLHandKeypointAnalyzerFactory.getInstance().getHandKeypointAnalyzer(setting)
        mAnalyzer!!.setTransactor(HandAnalyzerTransactor(this, mOverlay!!) )
    }

    // Check the permissions required by the SDK.
    private fun checkPermission() {
        if (Build.VERSION.SDK_INT &amp;gt;= 23 &amp;amp;&amp;amp; !isPermissionRequested) {
            isPermissionRequested = true
            val permissionsList = ArrayList&amp;lt;String&amp;gt;()
            for (perm in getAllPermission()!!) {
                if (PackageManager.PERMISSION_GRANTED != checkSelfPermission(perm.toString())) {
                    permissionsList.add(perm.toString())
                }
            }
            if (!permissionsList.isEmpty()) {
                requestPermissions(permissionsList.toTypedArray(), 0)
            }
        }
    }

    private fun getAllPermission(): MutableList&amp;lt;Array&amp;lt;String&amp;gt;&amp;gt; {
        return Collections.unmodifiableList(listOf(ALL_PERMISSION))
    }

    private fun createLensEngine() {
        val context = this.applicationContext
        // Create LensEngine.
        mLensEngine = LensEngine.Creator(context, mAnalyzer)
            .setLensType(mLensType)
            .applyDisplayDimension(640, 480)
            .applyFps(25.0f)
            .enableAutomaticFocus(true)
            .create()
    }

    private fun startLensEngine() {
        if (mLensEngine != null) {
            try {
                mPreview!!.start(mLensEngine, mOverlay)
            } catch (e: IOException) {
                Log.e(TAG, "Failed to start lens engine.", e)
                mLensEngine!!.release()
                mLensEngine = null
            }
        }
    }

    // Permission application callback.
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array&amp;lt;String?&amp;gt;, grantResults: IntArray) {
        var hasAllGranted = true
        if (requestCode == CAMERA_PERMISSION_CODE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                createLensEngine()
            } else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                hasAllGranted = false
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[0]!!)) {
                    showWaringDialog()
                } else {
                    Toast.makeText(this, R.string.toast, Toast.LENGTH_SHORT).show()
                    finish()
                }
            }
            return
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    override fun onSaveInstanceState(outState: Bundle) {
        outState.putInt("lensType", lensType)
        super.onSaveInstanceState(outState)
    }

    private class HandAnalyzerTransactor internal constructor(mainActivity: LiveHandKeyPointAnalyse?,
        private val mGraphicOverlay: GraphicOverlay) : MLTransactor&amp;lt;MLHandKeypoints?&amp;gt; {
        // Process the results returned by the analyzer.
        override fun transactResult(result: MLAnalyzer.Result&amp;lt;MLHandKeypoints?&amp;gt;) {
            mGraphicOverlay.clear()
            val handKeypointsSparseArray = result.analyseList
            val list: MutableList&amp;lt;MLHandKeypoints?&amp;gt; = ArrayList()
            for (i in 0 until handKeypointsSparseArray.size()) {
                list.add(handKeypointsSparseArray.valueAt(i))
            }
            val graphic = HandKeypointGraphic(mGraphicOverlay, list)
            mGraphicOverlay.add(graphic)
        }
        override fun destroy() {
            mGraphicOverlay.clear()
        }
    }

    override fun onClick(v: View?) {
        when (v!!.id) {
            R.id.handswitch -&amp;gt; switchCamera()
            else -&amp;gt; {}
        }
    }

    private fun switchCamera() {
        isFront = !isFront
        mLensType = if (isFront) {
            LensEngine.FRONT_LENS
        } else {
            LensEngine.BACK_LENS
        }
        if (mLensEngine != null) {
            mLensEngine!!.close()
        }
        createLensEngine()
        startLensEngine()
    }

    private fun showWaringDialog() {
        val dialog = AlertDialog.Builder(this)
        dialog.setMessage(R.string.Information_permission)
            .setPositiveButton(R.string.go_authorization,
                DialogInterface.OnClickListener { dialog, which -&amp;gt;
                    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                    val uri = Uri.fromParts("package", applicationContext.packageName, null)
                    intent.data = uri
                    startActivity(intent)
                })
            .setNegativeButton("Cancel", DialogInterface.OnClickListener { dialog, which -&amp;gt; finish() })
            .setOnCancelListener(dialogInterface)
        dialog.setCancelable(false)
        dialog.show()
    }

    var dialogInterface = DialogInterface.OnCancelListener { }

    override fun onResume() {
        super.onResume()
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            createLensEngine()
            startLensEngine()
        } else {
            checkPermission()
        }
    }

    override fun onPause() {
        super.onPause()
        mPreview!!.stop()
    }

    override fun onDestroy() {
        super.onDestroy()
        if (mLensEngine != null) {
            mLensEngine!!.release()
        }
        if (mAnalyzer != null) {
            mAnalyzer!!.stop()
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;strong&gt;LensEnginePreview.kt&lt;/strong&gt; class to find the business logic for lens engine view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LensEnginePreview(private val mContext: Context, attrs: AttributeSet?) : ViewGroup(mContext, attrs) {

    private val mSurfaceView: SurfaceView
    private var mStartRequested = false
    private var mSurfaceAvailable = false
    private var mLensEngine: LensEngine? = null
    private var mOverlay: GraphicOverlay? = null

    @Throws(IOException::class)
    fun start(lensEngine: LensEngine?) {
        if (lensEngine == null) {
            stop()
        }
        mLensEngine = lensEngine
        if (mLensEngine != null) {
            mStartRequested = true
            startIfReady()
        }
    }

    @Throws(IOException::class)
    fun start(lensEngine: LensEngine?, overlay: GraphicOverlay?) {
        mOverlay = overlay
        this.start(lensEngine)
    }

    fun stop() {
        if (mLensEngine != null) {
            mLensEngine!!.close()
        }
    }

    @Throws(IOException::class)
    private fun startIfReady() {
        if (mStartRequested &amp;amp;&amp;amp; mSurfaceAvailable) {
            mLensEngine!!.run(mSurfaceView.holder)
            if (mOverlay != null) {
                val size = mLensEngine!!.displayDimension
                val min = Math.min(size.width, size.height)
                val max = Math.max(size.width, size.height)
                if (isPortraitMode) {
                    // Swap width and height sizes when in portrait, since it will be rotated by 90 degrees.
                    mOverlay!!.setCameraInfo(min, max, mLensEngine!!.lensType)
                } else {
                    mOverlay!!.setCameraInfo(max, min, mLensEngine!!.lensType)
                }
                mOverlay!!.clear()
            }
            mStartRequested = false
        }
    }

    private inner class SurfaceCallback : SurfaceHolder.Callback {
        override fun surfaceCreated(surface: SurfaceHolder) {
            mSurfaceAvailable = true
            try {
                startIfReady()
            } catch (e: IOException) {
                Log.e(TAG, "Could not start camera source.", e)
            }
        }
        override fun surfaceDestroyed(surface: SurfaceHolder) {
            mSurfaceAvailable = false
        }
        override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        var previewWidth = 480
        var previewHeight = 360
        if (mLensEngine != null) {
            val size = mLensEngine!!.displayDimension
            if (size != null) {
                previewWidth = size.width
                previewHeight = size.height
            }
        }
        // Swap width and height sizes when in portrait, since it will be rotated 90 degrees
        if (isPortraitMode) {
            val tmp = previewWidth
            previewWidth = previewHeight
            previewHeight = tmp
        }
        val viewWidth = right - left
        val viewHeight = bottom - top
        val childWidth: Int
        val childHeight: Int
        var childXOffset = 0
        var childYOffset = 0
        val widthRatio = viewWidth.toFloat() / previewWidth.toFloat()
        val heightRatio = viewHeight.toFloat() / previewHeight.toFloat()
        // To fill the view with the camera preview, while also preserving the correct aspect ratio,
        // it is usually necessary to slightly oversize the child and to crop off portions along one
        // of the dimensions. We scale up based on the dimension requiring the most correction, and
        // compute a crop offset for the other dimension.
        if (widthRatio &amp;gt; heightRatio) {
            childWidth = viewWidth
            childHeight = (previewHeight.toFloat() * widthRatio).toInt()
            childYOffset = (childHeight - viewHeight) / 2
        } else {
            childWidth = (previewWidth.toFloat() * heightRatio).toInt()
            childHeight = viewHeight
            childXOffset = (childWidth - viewWidth) / 2
        }
        for (i in 0 until this.childCount) {
            // One dimension will be cropped. We shift child over or up by this offset and adjust
            // the size to maintain the proper aspect ratio.
            getChildAt(i).layout(-1 * childXOffset, -1 * childYOffset,
                childWidth - childXOffset,childHeight - childYOffset )
        }
        try {
            startIfReady()
        } catch (e: IOException) {
            Log.e(TAG, "Could not start camera source.", e)
        }
    }

    private val isPortraitMode: Boolean
        get() {
            val orientation = mContext.resources.configuration.orientation
            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                return false
            }
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                return true
            }
            Log.d(TAG, "isPortraitMode returning false by default")
            return false
        }

    companion object {
        private val TAG = LensEnginePreview::class.java.simpleName
    }

    init {
        mSurfaceView = SurfaceView(mContext)
        mSurfaceView.holder.addCallback(SurfaceCallback())
        this.addView(mSurfaceView)
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;strong&gt;HandKeypointGraphic.kt&lt;/strong&gt; class to find the business logic for hand key point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class HandKeypointGraphic(overlay: GraphicOverlay?, private val handKeypoints: MutableList&amp;lt;MLHandKeypoints?&amp;gt;) : GraphicOverlay.Graphic(overlay!!) {

    private val rectPaint: Paint
    private val idPaintnew: Paint
    companion object {
        private const val BOX_STROKE_WIDTH = 5.0f
    }

    private fun translateRect(rect: Rect): Rect {
        var left: Float = translateX(rect.left)
        var right: Float = translateX(rect.right)
        var bottom: Float = translateY(rect.bottom)
        var top: Float = translateY(rect.top)
        if (left &amp;gt; right) {
            val size = left
            left = right
            right = size
        }
        if (bottom &amp;lt; top) {
            val size = bottom
            bottom = top
            top = size
        }
        return Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
    }

    init {
        val selectedColor = Color.WHITE
        idPaintnew = Paint()
        idPaintnew.color = Color.GREEN
        idPaintnew.textSize = 32f
        rectPaint = Paint()
        rectPaint.color = selectedColor
        rectPaint.style = Paint.Style.STROKE
        rectPaint.strokeWidth = BOX_STROKE_WIDTH
    }

    override fun draw(canvas: Canvas?) {
        for (i in handKeypoints.indices) {
            val mHandKeypoints = handKeypoints[i]
            if (mHandKeypoints!!.getHandKeypoints() == null) {
                continue
            }
            val rect = translateRect(handKeypoints[i]!!.getRect())
            canvas!!.drawRect(rect, rectPaint)
            for (handKeypoint in mHandKeypoints.getHandKeypoints()) {
                if (!(Math.abs(handKeypoint.getPointX() - 0f) == 0f &amp;amp;&amp;amp; Math.abs(handKeypoint.getPointY() - 0f) == 0f)) {
                    canvas!!.drawCircle(translateX(handKeypoint.getPointX().toInt()),
                        translateY(handKeypoint.getPointY().toInt()), 24f, idPaintnew)
                }
            }
        }
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;strong&gt;GraphicOverlay.kt&lt;/strong&gt; class to find the business logic for graphic overlay.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class GraphicOverlay(context: Context?, attrs: AttributeSet?) : View(context, attrs) {

    private val mLock = Any()
    private var mPreviewWidth = 0
    private var mWidthScaleFactor = 1.0f
    private var mPreviewHeight = 0
    private var mHeightScaleFactor = 1.0f
    private var mFacing = LensEngine.BACK_LENS
    private val mGraphics: MutableSet&amp;lt;Graphic&amp;gt; = HashSet()

    // Base class for a custom graphics object to be rendered within the graphic overlay. Subclass
    // this and implement the [Graphic.draw] method to define the graphics element. Add instances to the overlay using [GraphicOverlay.add].
    abstract class Graphic(private val mOverlay: GraphicOverlay) {
         // Draw the graphic on the supplied canvas. Drawing should use the following methods to
         // convert to view coordinates for the graphics that are drawn:
         // 1. [Graphic.scaleX] and [Graphic.scaleY] adjust the size of the supplied value from the preview scale to the view scale.
         // 2. [Graphic.translateX] and [Graphic.translateY] adjust the coordinate from the preview's coordinate system to the view coordinate system.
         // @param canvas drawing canvas
        abstract fun draw(canvas: Canvas?)

        // Adjusts a horizontal value of the supplied value from the preview scale to the view scale.
        fun scaleX(horizontal: Float): Float {
            return horizontal * mOverlay.mWidthScaleFactor
        }


        // Adjusts a vertical value of the supplied value from the preview scale to the view scale.
        fun scaleY(vertical: Float): Float {
            return vertical * mOverlay.mHeightScaleFactor
        }

        // Adjusts the x coordinate from the preview's coordinate system to the view coordinate system.
        fun translateX(x: Int): Float {
            return if (mOverlay.mFacing == LensEngine.FRONT_LENS) {
                mOverlay.width - scaleX(x.toFloat())
            } else {
                scaleX(x.toFloat())
            }
        }
        // Adjusts the y coordinate from the preview's coordinate system to the view coordinate system.
        fun translateY(y: Int): Float {
            return scaleY(y.toFloat())
        }

    }

    // Removes all graphics from the overlay.
    fun clear() {
        synchronized(mLock) { mGraphics.clear() }
        postInvalidate()
    }

    // Adds a graphic to the overlay.
    fun add(graphic: Graphic) {
        synchronized(mLock) { mGraphics.add(graphic) }
        postInvalidate()
    }

    // Sets the camera attributes for size and facing direction, which informs how to transform image coordinates later.
    fun setCameraInfo(previewWidth: Int, previewHeight: Int, facing: Int) {
        synchronized(mLock) {
            mPreviewWidth = previewWidth
            mPreviewHeight = previewHeight
            mFacing = facing
        }
        postInvalidate()
    }

    // Draws the overlay with its associated graphic objects.
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        synchronized(mLock) {
            if (mPreviewWidth != 0 &amp;amp;&amp;amp; mPreviewHeight != 0) {
                mWidthScaleFactor = canvas.width.toFloat() / mPreviewWidth.toFloat()
                mHeightScaleFactor = canvas.height.toFloat() / mPreviewHeight.toFloat()
            }
            for (graphic in mGraphics) {
                graphic.draw(canvas)
            }
        }
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;StaticHandKeyPointAnalyse.kt&lt;/strong&gt; we can find the business logic static hand key point analyses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class StaticHandKeyPointAnalyse : AppCompatActivity() {

    var analyzer: MLHandKeypointAnalyzer? = null
    var bitmap: Bitmap? = null
    var mutableBitmap: Bitmap? = null
    var mlFrame: MLFrame? = null
    var imageSelected: ImageView? = null
    var picUri: Uri? = null
    var pickButton: Button? = null
    var analyzeButton:Button? = null
    var permissions = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.CAMERA)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_static_hand_key_point_analyse)

        pickButton = findViewById(R.id.pick_img)
        analyzeButton = findViewById(R.id.analyse_img)
        imageSelected = findViewById(R.id.selected_img)
        initialiseSettings()
        pickButton!!.setOnClickListener(View.OnClickListener {
            pickRequiredImage()
        })
        analyzeButton!!.setOnClickListener(View.OnClickListener {
            asynchronouslyStaticHandkey()
        })
        checkRequiredPermission()

    }

    private fun checkRequiredPermission() {
        if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            || PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            || PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)) {
            ActivityCompat.requestPermissions(this, permissions, 111)
        }
    }

    private fun initialiseSettings() {
        val setting = MLHandKeypointAnalyzerSetting.Factory() // MLHandKeypointAnalyzerSetting.TYPE_ALL indicates that all results are returned.
                // MLHandKeypointAnalyzerSetting.TYPE_KEYPOINT_ONLY indicates that only hand keypoint information is returned.
                // MLHandKeypointAnalyzerSetting.TYPE_RECT_ONLY indicates that only palm information is returned.
                .setSceneType(MLHandKeypointAnalyzerSetting.TYPE_ALL) // Set the maximum number of hand regions that can be detected in an image. By default, a maximum of 10 hand regions can be detected.
                .setMaxHandResults(1)
                .create()
        analyzer = MLHandKeypointAnalyzerFactory.getInstance().getHandKeypointAnalyzer(setting)
    }

    private fun asynchronouslyStaticHandkey() {
        val task = analyzer!!.asyncAnalyseFrame(mlFrame)
        task.addOnSuccessListener { results -&amp;gt;
            val canvas = Canvas(mutableBitmap!!)
            val paint = Paint()
            paint.color = Color.GREEN
            paint.style = Paint.Style.FILL
            val mlHandKeypoints = results[0]
            for (mlHandKeypoint in mlHandKeypoints.getHandKeypoints()) {
                canvas.drawCircle(mlHandKeypoint.pointX, mlHandKeypoint.pointY, 48f, paint)
            }
            imageSelected!!.setImageBitmap(mutableBitmap)
            checkAnalyserForStop()
        }.addOnFailureListener { // Detection failure.
            checkAnalyserForStop()
        }
    }

    private fun checkAnalyserForStop() {
        if (analyzer != null) {
            analyzer!!.stop()
        }
    }

    private fun pickRequiredImage() {
        val intent = Intent()
        intent.type = "image/*"
        intent.action = Intent.ACTION_PICK
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), 20)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 20 &amp;amp;&amp;amp; resultCode == RESULT_OK &amp;amp;&amp;amp; null != data) {
            picUri = data.data
            val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
            val cursor = contentResolver.query( picUri!!, filePathColumn, null, null, null)
            cursor!!.moveToFirst()
            cursor.close()
            imageSelected!!.setImageURI(picUri)
            imageSelected!!.invalidate()
            val drawable = imageSelected!!.drawable as BitmapDrawable
            bitmap = drawable.bitmap
            mutableBitmap = bitmap!!.copy(Bitmap.Config.ARGB_8888, true)
            mlFrame = null
            mlFrame = MLFrame.fromBitmap(bitmap)
        }
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_main.xml&lt;/strong&gt; we can create the UI screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"&amp;gt;

    &amp;lt;Button
        android:id="@+id/btn_static"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Static Detection"
        android:textAllCaps="false"
        android:textSize="18sp"
        app:layout_constraintBottom_toTopOf="@+id/btn_live"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textColor="@color/black"
        style="@style/Widget.MaterialComponents.Button.MyTextButton"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;

    &amp;lt;Button
        android:id="@+id/btn_live"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Live Detection"
        android:textAllCaps="false"
        android:textSize="18sp"
        android:layout_marginBottom="150dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:textColor="@color/black"
        style="@style/Widget.MaterialComponents.Button.MyTextButton"
        app:layout_constraintRight_toRightOf="parent" /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_live_hand_key_point_analyse.xml&lt;/strong&gt; we can create the UI screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".LiveHandKeyPointAnalyse"&amp;gt;

    &amp;lt;com.example.mlhandgesturesample.LensEnginePreview
        android:id="@+id/hand_preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="MissingClass"&amp;gt;
        &amp;lt;com.example.mlhandgesturesample.GraphicOverlay
            android:id="@+id/hand_overlay"
            android:layout_width="match_parent"
            android:layout_height="match_parent" /&amp;gt;
    &amp;lt;/com.example.mlhandgesturesample.LensEnginePreview&amp;gt;

    &amp;lt;Button
        android:id="@+id/handswitch"
        android:layout_width="35dp"
        android:layout_height="35dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="35dp"
        android:background="@drawable/front_back_switch"
        android:textOff=""
        android:textOn=""
        tools:ignore="MissingConstraints" /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_static_hand_key_point_analyse.xml&lt;/strong&gt; we can create the UI screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".StaticHandKeyPointAnalyse"&amp;gt;

    &amp;lt;com.google.android.material.button.MaterialButton
        android:id="@+id/pick_img"
        android:text="Pick Image"
        android:textSize="18sp"
        android:textColor="@android:color/black"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/selected_img"
        app:layout_constraintLeft_toLeftOf="@id/selected_img"
        app:layout_constraintRight_toRightOf="@id/selected_img"
        style="@style/Widget.MaterialComponents.Button.MyTextButton"/&amp;gt;

    &amp;lt;ImageView
        android:visibility="visible"
        android:id="@+id/selected_img"
        android:layout_width="350dp"
        android:layout_height="350dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;

    &amp;lt;com.google.android.material.button.MaterialButton
        android:id="@+id/analyse_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black"
        android:text="Analyse"
        android:textSize="18sp"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/selected_img"
        app:layout_constraintLeft_toLeftOf="@id/selected_img"
        app:layout_constraintRight_toRightOf="@id/selected_img"
        style="@style/Widget.MaterialComponents.Button.MyTextButton"/&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pZgSPEpz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhurkyysmc0erq3af850.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pZgSPEpz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhurkyysmc0erq3af850.gif" alt="Image description" width="216" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips and Tricks&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make sure you are already registered as Huawei developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set minSDK version to 21 or later, otherwise you will get AndriodManifest merge issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added the agconnect-services.json file to app folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added SHA-256 fingerprint without fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure all the dependencies are added properly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we have learned how to find the hand key points using Huawei ML Kit of Hand Gesture Recognition feature. This service provides two capabilities: hand keypoint detection and hand gesture recognition. The hand keypoint detection capability can detect 21 hand keypoints (including fingertips, knuckles, and wrists) and return the positions of the key points. The hand gesture recognition capability can detect and return the positions of all rectangle areas of the hand from images and videos, and the type and confidence of a gesture. This capability can recognize 14 gestures, including the thumbs-up/down, OK sign, fist, finger heart, and number gestures from 1 to 9. Both capabilities support detection from static images and real-time camera streams.&lt;/p&gt;

&lt;p&gt;I hope you have read this article. If you found it is helpful, please provide likes and comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ML Kit – &lt;a href="https://developer.huawei.com/consumer/en/doc/development/hiai-Guides/handgesturerecognition-0000001051615541"&gt;Hand Gesture Recognition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ML Kit – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101630382080217904"&gt;Training Video&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mlkit</category>
      <category>android</category>
      <category>xml</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Integration of the Roll Ads feature of Huawei Ads Kit in Android app (Kotlin)</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Mon, 05 Sep 2022 02:58:38 +0000</pubDate>
      <link>https://dev.to/hmscommunity/integration-of-the-roll-ads-feature-of-huawei-ads-kit-in-android-app-kotlin-j2b</link>
      <guid>https://dev.to/hmscommunity/integration-of-the-roll-ads-feature-of-huawei-ads-kit-in-android-app-kotlin-j2b</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HmhgJEU8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1hjl8dz8sn2bky00uxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HmhgJEU8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1hjl8dz8sn2bky00uxg.png" alt="Image description" width="880" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we can learn how to integrate &lt;strong&gt;Roll Ads feature of Huawei Ads Kit&lt;/strong&gt; into the android app. So, Roll ads are displayed as short &lt;strong&gt;videos&lt;/strong&gt; or &lt;strong&gt;images&lt;/strong&gt;, &lt;strong&gt;before&lt;/strong&gt;, &lt;strong&gt;during&lt;/strong&gt;, or &lt;strong&gt;after&lt;/strong&gt; the video content is played.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ads Kit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Huawei Ads provides to developers a wide-ranging capabilities to deliver good quality ads content to users. This is the best way to reach the target audience easily and can measure user productivity. It is very useful when we publish a free app and want to earn some money from it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HMS Ads Kit&lt;/strong&gt; has &lt;strong&gt;7&lt;/strong&gt; types of Ads kits. Now we can implement &lt;strong&gt;Roll Ads&lt;/strong&gt; in this application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Any operating system (MacOS, Linux and Windows).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a Huawei phone with HMS 4.0.0.300 or later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimum API Level 24 is required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required EMUI 9.0.0 and later version devices.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to integrate HMS Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a &lt;a href="https://developer.huawei.com/consumer/en/doc/start/registration-and-verification-0000001053628148"&gt;Huawei ID&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a project in android studio, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#1"&gt;Creating an Android Studio Project&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To generate &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;. On right-upper corner of android project click &lt;strong&gt;Gradle&lt;/strong&gt;, choose &lt;strong&gt;Project Name &amp;gt; Tasks &amp;gt; android&lt;/strong&gt;, and then click &lt;strong&gt;signingReport&lt;/strong&gt;, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Qz0syvqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xhtvy6fld8ptst17bsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qz0syvqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xhtvy6fld8ptst17bsi.png" alt="Image description" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Project Name depends on the user created name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#0"&gt;Create an App in AppGallery Connect&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;strong&gt;agconnect-services.json&lt;/strong&gt; file from &lt;strong&gt;App information&lt;/strong&gt;, copy and paste in android &lt;strong&gt;Project&lt;/strong&gt; under &lt;strong&gt;app&lt;/strong&gt; directory, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--52NsNq42--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/utwah6p924pc0qbpmzel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--52NsNq42--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/utwah6p924pc0qbpmzel.png" alt="Image description" width="464" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enter &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt; and click &lt;strong&gt;Save&lt;/strong&gt; button, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the below maven URL in &lt;strong&gt;build.gradle(Project)&lt;/strong&gt; file under the repositories of &lt;strong&gt;buildscript&lt;/strong&gt;, &lt;strong&gt;dependencies&lt;/strong&gt; and &lt;strong&gt;allprojects&lt;/strong&gt;, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#6"&gt;Add Configuration&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add the below plugin and dependencies in &lt;strong&gt;build.gradle(Module)&lt;/strong&gt; file.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apply plugin: id 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Huawei Ads Kit
implementation 'com.huawei.hms:ads-lite:13.4.51.300'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now Sync the gradle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the required permission to the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Ads Kit
&amp;lt;uses-permission android:name="android.permission.INTERNET" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Let us move to development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have created a project on Android studio with empty activity let us start coding.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;MainActivity.kt&lt;/strong&gt; we can find the business logic for Ads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MainActivity : AppCompatActivity() {

    private var videoContent: TextView? = null
    private var skipAd: TextView? = null
    private var countDown: TextView? = null
    private var callToAction: TextView? = null
    private var loadButton: Button? = null
    private var registerButton: Button? = null
    private var muteButton: Button? = null
    private var pauseButton: Button? = null
    private var instreamContainer: RelativeLayout? = null
    private var instreamView: InstreamView? = null
    private var whyThisAd: ImageView? = null
    private var context: Context? = null
    private var maxAdDuration = 0
    private var whyThisAdUrl: String? = null
    private var isMuted = false
    private var adLoader: InstreamAdLoader? = null
    private var instreamAds: List&amp;lt;InstreamAd&amp;gt;? = ArrayList()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        context = applicationContext
        setTitle(R.string.instream_ad)
        initInstreamAdView()
        initButtons()
        configAdLoader()

    }

    private val mediaChangeListener = InstreamMediaChangeListener { instreamAd -&amp;gt;
        whyThisAdUrl = null
        whyThisAdUrl = instreamAd.whyThisAd
        Log.i(TAG, "onSegmentMediaChange, whyThisAd: $whyThisAdUrl")
        if (!TextUtils.isEmpty(whyThisAdUrl)) {
            whyThisAd!!.visibility = View.VISIBLE
            whyThisAd!!.setOnClickListener { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(whyThisAdUrl))) }
        } else {
            whyThisAd!!.visibility = View.GONE
        }
        val cta = instreamAd.callToAction
        if (!TextUtils.isEmpty(cta)) {
            callToAction!!.visibility = View.VISIBLE
            callToAction!!.text = cta
            instreamView!!.callToActionView = callToAction
        }
    }

    private val mediaStateListener: InstreamMediaStateListener = object : InstreamMediaStateListener {
        override fun onMediaProgress(per: Int, playTime: Int) {
            updateCountDown(playTime.toLong())
        }
        override fun onMediaStart(playTime: Int) {
            updateCountDown(playTime.toLong())
        }
        override fun onMediaPause(playTime: Int) {
            updateCountDown(playTime.toLong())
        }
        override fun onMediaStop(playTime: Int) {
            updateCountDown(playTime.toLong())
        }
        override fun onMediaCompletion(playTime: Int) {
            updateCountDown(playTime.toLong())
            playVideo()
        }
        override fun onMediaError(playTime: Int, errorCode: Int, extra: Int) {
            updateCountDown(playTime.toLong())
        }
    }

    private val mediaMuteListener: MediaMuteListener = object : MediaMuteListener {
        override fun onMute() {
            isMuted = true
            Toast.makeText(context, "Ad muted", Toast.LENGTH_SHORT).show()
        }
        override fun onUnmute() {
            isMuted = false
            Toast.makeText(context, "Ad unmuted", Toast.LENGTH_SHORT).show()
        }
    }

    private fun initInstreamAdView() {
        instreamContainer = findViewById(R.id.instream_ad_container)
        videoContent = findViewById(R.id.instream_video_content)
        skipAd = findViewById(R.id.instream_skip)
        skipAd!!.setOnClickListener(View.OnClickListener {
            if (null != instreamView) {
                instreamView!!.onClose()
                instreamView!!.destroy()
                instreamContainer!!.visibility = View.GONE
            }
        })
        countDown = findViewById(R.id.instream_count_down)
        callToAction = findViewById(R.id.instream_call_to_action)
        whyThisAd = findViewById(R.id.instream_why_this_ad)
        instreamView = findViewById(R.id.instream_view)
        instreamView!!.setInstreamMediaChangeListener(mediaChangeListener)
        instreamView!!.setInstreamMediaStateListener(mediaStateListener)
        instreamView!!.setMediaMuteListener(mediaMuteListener)
        instreamView!!.setOnInstreamAdClickListener(InstreamView.OnInstreamAdClickListener {
            Toast.makeText(context,"instream clicked.", Toast.LENGTH_SHORT).show()
        })
    }

    private val clickListener = View.OnClickListener { view -&amp;gt;
        when (view.id) {
            R.id.instream_load -&amp;gt; if (null != adLoader) {
                loadButton!!.text = getString(R.string.instream_loading)
                adLoader!!.loadAd(AdParam.Builder().build())
            }
            R.id.instream_register -&amp;gt; if (null == instreamAds || instreamAds!!.isEmpty()) {
                playVideo()
            } else {
                playInstreamAds(instreamAds!!)
            }
            R.id.instream_mute -&amp;gt; if (isMuted) {
                instreamView!!.unmute()
                muteButton!!.text = getString(R.string.instream_mute)
            } else {
                instreamView!!.mute()
                muteButton!!.text = getString(R.string.instream_unmute)
            }
            R.id.instream_pause_play -&amp;gt; if (instreamView!!.isPlaying) {
                instreamView!!.pause()
                pauseButton!!.text = getString(R.string.instream_play)
            } else {
                instreamView!!.play()
                pauseButton!!.text = getString(R.string.instream_pause)
            }
            else -&amp;gt; {
            }
        }
    }

    private fun initButtons() {
        loadButton = findViewById(R.id.instream_load)
        registerButton = findViewById(R.id.instream_register)
        muteButton = findViewById(R.id.instream_mute)
        pauseButton = findViewById(R.id.instream_pause_play)
        loadButton!!.setOnClickListener(clickListener)
        registerButton!!.setOnClickListener(clickListener)
        muteButton!!.setOnClickListener(clickListener)
        pauseButton!!.setOnClickListener(clickListener)
    }

    private val instreamAdLoadListener: InstreamAdLoadListener = object : InstreamAdLoadListener {
        override fun onAdLoaded(ads: MutableList&amp;lt;InstreamAd&amp;gt;) {
            if (null == ads || ads.size == 0) {
                playVideo()
                return
            }
            val it = ads.iterator()
            while (it.hasNext()) {
                val ad = it.next()
                if (ad.isExpired) {
                    it.remove()
                }
            }
            if (ads.size == 0) {
                playVideo()
                return
            }
            loadButton!!.text = getString(R.string.instream_loaded)
            instreamAds = ads
            Toast.makeText(context, "onAdLoaded, ad size: " + ads.size + ", click REGISTER to play.", Toast.LENGTH_SHORT).show()
        }
        override fun onAdFailed(errorCode: Int) {
            Log.w(TAG, "onAdFailed: $errorCode")
            loadButton!!.text = getString(R.string.instream_load)
            Toast.makeText(context, "onAdFailed: $errorCode", Toast.LENGTH_SHORT).show()
            playVideo()
        }
    }

    private fun configAdLoader() {
        // if the maximum total duration is 60 seconds and the maximum number of roll ads is eight,
        // at most four 15-second roll ads or two 30-second roll ads will be returned.
        // If the maximum total duration is 120 seconds and the maximum number of roll ads is four,
        // no more roll ads will be returned after whichever is reached.
        val totalDuration = 60
        val maxCount = 4
        val builder = InstreamAdLoader.Builder(context, getString(R.string.instream_ad_id))
        adLoader = builder.setTotalDuration(totalDuration)
            .setMaxCount(maxCount)
            .setInstreamAdLoadListener(instreamAdLoadListener)
            .build()
    }

    // play your normal video content.
    private fun playVideo() {
        hideAdViews()
        videoContent!!.setText(R.string.instream_normal_video_playing)
    }

    private fun hideAdViews() {
        instreamContainer!!.visibility = View.GONE
    }

    private fun playInstreamAds(ads: List&amp;lt;InstreamAd&amp;gt;) {
        maxAdDuration = getMaxInstreamDuration(ads)
        instreamContainer!!.visibility = View.VISIBLE
        loadButton!!.text = getString(R.string.instream_load)
        instreamView!!.setInstreamAds(ads)
    }

    private fun updateCountDown(playTime: Long) {
        val time = Math.round((maxAdDuration - playTime) / 1000.toFloat()).toString()
        runOnUiThread { countDown!!.text = time + "s" }
    }

    private fun getMaxInstreamDuration(ads: List&amp;lt;InstreamAd&amp;gt;): Int {
        var duration = 0
        for (ad in ads) {
            duration += ad.duration.toInt()
        }
        return duration
    }

    override fun onPause() {
        super.onPause()
        if (null != instreamView &amp;amp;&amp;amp; instreamView!!.isPlaying) {
            instreamView!!.pause()
            pauseButton!!.text = getText(R.string.instream_play)
        }
    }

    override fun onResume() {
        super.onResume()
        if (null != instreamView &amp;amp;&amp;amp; !instreamView!!.isPlaying) {
            instreamView!!.play()
            pauseButton!!.text = getText(R.string.instream_pause)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (null != instreamView) {
            instreamView!!.removeInstreamMediaStateListener()
            instreamView!!.removeInstreamMediaChangeListener()
            instreamView!!.removeMediaMuteListener()
            instreamView!!.destroy()
        }
    }

    companion object {
        private val TAG = MainActivity::class.java.simpleName
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_main.xml&lt;/strong&gt; we can create the UI screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"&amp;gt;

    &amp;lt;RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"&amp;gt;

        &amp;lt;RelativeLayout
            android:id="@+id/your_video_content"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="@android:color/black"&amp;gt;
            &amp;lt;TextView
                android:id="@+id/instream_video_content"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAlignment="center"
                android:layout_centerInParent="true"
                android:text="Your video content"
                android:textColor="@android:color/white"/&amp;gt;
        &amp;lt;/RelativeLayout&amp;gt;

        &amp;lt;RelativeLayout
            android:id="@+id/instream_ad_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"&amp;gt;

            &amp;lt;com.huawei.hms.ads.instreamad.InstreamView
                android:id="@+id/instream_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent" /&amp;gt;

            &amp;lt;TextView
                android:id="@+id/instream_skip"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingVertical="3dp"
                android:paddingHorizontal="5dp"
                android:layout_alignStart="@id/instream_view"
                android:layout_alignLeft="@id/instream_view"
                android:layout_alignTop="@id/instream_view"
                android:layout_marginStart="16dp"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="8dp"
                android:text="Skip"
                android:textColor="@android:color/white"
                android:textSize="16sp"
                android:background="@drawable/emui_button_select"/&amp;gt;

            &amp;lt;TextView
                android:id="@+id/instream_count_down"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingVertical="3dp"
                android:paddingHorizontal="5dp"
                android:layout_alignEnd="@id/instream_view"
                android:layout_alignRight="@id/instream_view"
                android:layout_alignTop="@id/instream_view"
                android:layout_marginEnd="16dp"
                android:layout_marginRight="16dp"
                android:layout_marginTop="8dp"
                android:textColor="@android:color/white"
                android:textSize="16sp"
                android:background="@drawable/emui_button_select"/&amp;gt;

            &amp;lt;TextView
                android:id="@+id/instream_ad_flag"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignStart="@id/instream_view"
                android:layout_alignLeft="@id/instream_view"
                android:layout_alignBottom="@id/instream_view"
                android:layout_marginStart="16dp"
                android:layout_marginLeft="16dp"
                android:layout_marginBottom="8dp"
                android:background="@drawable/emui_button_select"
                android:gravity="center"
                android:text="Ad"
                android:textColor="@android:color/white"
                android:textSize="8sp"
                android:textStyle="bold" /&amp;gt;

            &amp;lt;ImageView
                android:id="@+id/instream_why_this_ad"
                android:layout_width="14dp"
                android:layout_height="14dp"
                android:layout_toEndOf="@id/instream_ad_flag"
                android:layout_toRightOf="@id/instream_ad_flag"
                android:layout_alignBottom="@id/instream_view"
                android:layout_marginLeft="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginBottom="8dp"
                android:src="@drawable/app_whythisad_info"/&amp;gt;

            &amp;lt;TextView
                android:id="@+id/instream_call_to_action"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingVertical="3dp"
                android:paddingHorizontal="5dp"
                android:layout_alignEnd="@id/instream_view"
                android:layout_alignRight="@id/instream_view"
                android:layout_alignBottom="@id/instream_view"
                android:layout_marginEnd="16dp"
                android:layout_marginRight="16dp"
                android:layout_marginBottom="8dp"
                android:text="Learn more"
                android:textColor="@android:color/white"
                android:textSize="16sp"
                android:background="@drawable/emui_button_select"/&amp;gt;
        &amp;lt;/RelativeLayout&amp;gt;

        &amp;lt;RelativeLayout
            android:id="@+id/instream_ctrl_panel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingHorizontal="16dp"
            android:paddingVertical="16dp"
            android:layout_below="@id/your_video_content"&amp;gt;
            &amp;lt;LinearLayout
                android:id="@+id/load_and_register"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_centerHorizontal="true"&amp;gt;
                &amp;lt;Button
                    android:id="@+id/instream_load"
                    android:layout_width="120dp"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:text="Load Ad"/&amp;gt;
                &amp;lt;Button
                    android:id="@+id/instream_register"
                    android:layout_width="120dp"
                    android:layout_height="wrap_content"
                    android:text="Register"/&amp;gt;
            &amp;lt;/LinearLayout&amp;gt;
            &amp;lt;LinearLayout
                android:id="@+id/play_ctrl"
                android:layout_below="@id/load_and_register"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_centerHorizontal="true"&amp;gt;
                &amp;lt;Button
                    android:id="@+id/instream_mute"
                    android:layout_width="100dp"
                    android:layout_marginRight="10dp"
                    android:layout_height="wrap_content"
                    android:text="Mute"/&amp;gt;
                &amp;lt;Button
                    android:id="@+id/instream_pause_play"
                    android:layout_width="100dp"
                    android:layout_height="wrap_content"
                    android:text="Pause"/&amp;gt;
            &amp;lt;/LinearLayout&amp;gt;
        &amp;lt;/RelativeLayout&amp;gt;
    &amp;lt;/RelativeLayout&amp;gt;


&amp;lt;/ScrollView&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FVCB6sfR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5p17pebbe77wuw2ekzcp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FVCB6sfR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5p17pebbe77wuw2ekzcp.gif" alt="Image description" width="216" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips and Tricks&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make sure you are already registered as Huawei developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added the agconnect-services.json file to app folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added SHA-256 fingerprint without fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure all the dependencies are added properly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we have learned how to integrate &lt;strong&gt;Roll Ads feature of Huawei Ads Kit&lt;/strong&gt; into the android app. So, Roll ads are displayed as &lt;strong&gt;short videos&lt;/strong&gt; or &lt;strong&gt;images&lt;/strong&gt;, &lt;strong&gt;before&lt;/strong&gt;, &lt;strong&gt;during&lt;/strong&gt;, or &lt;strong&gt;after the video&lt;/strong&gt; content is played.&lt;/p&gt;

&lt;p&gt;I hope you have read this article. If you found it is helpful, please provide likes and comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ads Kit - &lt;a href="https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/publisher-service-instream-0000001058253743"&gt;Roll Ads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ads Kit – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101614748910616026"&gt;Training Video&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ads</category>
      <category>kotlin</category>
      <category>android</category>
      <category>xml</category>
    </item>
    <item>
      <title>Check the similar words using Text Embedding feature by Huawei ML Kit in Android (Kotlin)</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Mon, 29 Aug 2022 09:33:54 +0000</pubDate>
      <link>https://dev.to/hmscommunity/check-the-similar-words-using-text-embedding-feature-by-huawei-ml-kit-in-android-kotlin-3gb7</link>
      <guid>https://dev.to/hmscommunity/check-the-similar-words-using-text-embedding-feature-by-huawei-ml-kit-in-android-kotlin-3gb7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0vWa3qWj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yh7gd59chg0hja46aak.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0vWa3qWj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yh7gd59chg0hja46aak.PNG" alt="Image description" width="707" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we can learn how to check similar words and sentences using &lt;strong&gt;Text Embedding&lt;/strong&gt; feature of &lt;strong&gt;Huawei ML Kit&lt;/strong&gt;. This Huawei ML Kit provides &lt;strong&gt;Text Embedding&lt;/strong&gt; feature which helps to get matching vector value of &lt;strong&gt;words&lt;/strong&gt; or &lt;strong&gt;sentences&lt;/strong&gt;. Using this feature, we can improve our research based on the result. It provides similarity between two words or sentences and similar words of a particular word searched. We can also improve searching and browsing efficiency using after getting results related to search text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service can be used in &lt;strong&gt;text&lt;/strong&gt; search scenarios. A user can enter a &lt;strong&gt;keyword&lt;/strong&gt; in your news app to return hot news related to the word, improving the search and browsing efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Precautions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Text embedding depends on the on-cloud API for recognition. During commissioning and usage, ensure that the device can access the Internet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Any operating system (MacOS, Linux and Windows).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a Huawei phone with HMS 4.0.0.300 or later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimum API Level 21 is required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required EMUI 9.0.0 and later version devices.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to integrate HMS Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a &lt;a href="https://developer.huawei.com/consumer/en/doc/start/registration-and-verification-0000001053628148"&gt;Huawei ID&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a project in android studio, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#1"&gt;Creating an Android Studio Project&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To generate &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;. On right-upper corner of android project click &lt;strong&gt;Gradle&lt;/strong&gt;, choose &lt;strong&gt;Project Name &amp;gt; Tasks &amp;gt; android&lt;/strong&gt;, and then click &lt;strong&gt;signingReport&lt;/strong&gt;, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F-Mi4QWJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/blpdd9snesra2dn7t2vp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F-Mi4QWJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/blpdd9snesra2dn7t2vp.png" alt="Image description" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Project Name depends on the user created name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#0"&gt;Create an App in AppGallery Connect&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;strong&gt;agconnect-services.json&lt;/strong&gt; file from &lt;strong&gt;App information&lt;/strong&gt;, copy and paste in android &lt;strong&gt;Project&lt;/strong&gt; under &lt;strong&gt;app&lt;/strong&gt; directory, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hulsJnD1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v4oxnl2pfptb5lue7voy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hulsJnD1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v4oxnl2pfptb5lue7voy.png" alt="Image description" width="464" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt; and click &lt;strong&gt;Save&lt;/strong&gt; button, as follows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--muhEip2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cl13hquw815ku2lyo2xg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--muhEip2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cl13hquw815ku2lyo2xg.png" alt="Image description" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Manage APIs&lt;/strong&gt; tab and enable &lt;strong&gt;ML Kit&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fYhueYQu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kkolmsb9n2k16oigvydi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fYhueYQu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kkolmsb9n2k16oigvydi.png" alt="Image description" width="880" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the below maven URL in &lt;strong&gt;build.gradle(Project)&lt;/strong&gt; file under the repositories of &lt;strong&gt;buildscript&lt;/strong&gt;, &lt;strong&gt;dependencies&lt;/strong&gt; and &lt;strong&gt;allprojects&lt;/strong&gt;, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#6"&gt;Add Configuration&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.4.1.300'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add the below plugin and dependencies in &lt;strong&gt;build.gradle(Module)&lt;/strong&gt; file.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apply plugin: 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.5.0.300'
// ML Kit Text Embedding
implementation 'com.huawei.hms:ml-nlp-textembedding:2.0.4.300'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now Sync the gradle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the required permission to the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name="android.permission.INTERNET" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Let us move to development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have created a project on Android studio with empty activity let us start coding.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;MainActivity.kt&lt;/strong&gt; we can find the business logic for buttons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MainActivity : AppCompatActivity() {

    var wordSimilar: Button? = null
    var sentenceSimilar:Button? = null
    var similarWords:Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        MLApplication.getInstance().apiKey = getString(R.string.api_key)
        wordSimilar = findViewById(R.id.word_similar)
        sentenceSimilar = findViewById(R.id.sentence_similar)
        similarWords = findViewById(R.id.similar_words)

        wordSimilar!!.setOnClickListener(View.OnClickListener {
            startActivity(Intent(this@MainActivity, WordSimilarActivity::class.java)) })

        sentenceSimilar!!.setOnClickListener(View.OnClickListener {
            startActivity(Intent(this@MainActivity, SentenceSimilarActivity::class.java)) })

        similarWords!!.setOnClickListener(View.OnClickListener {
            startActivity(Intent(this@MainActivity, SimilarWordsActivity::class.java)) })

    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;WordSimilarActivity.kt&lt;/strong&gt; we can find the business logic for similar words.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class WordSimilarActivity : AppCompatActivity() {

    private var analyzer: MLTextEmbeddingAnalyzer? = null
    private var checkWordSimilarity: Button? = null
    var resultTextView: TextView? = null
    var similarWord1: EditText? = null
    var similarWord2:EditText? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_word_similar)

        resultTextView = findViewById(R.id.similar_word_value)
        checkWordSimilarity = findViewById(R.id.check_word_similarity)
        similarWord1 = findViewById(R.id.similar_word1)
        similarWord2 = findViewById(R.id.similar_word2)
        checkWordSimilarity!!.setOnClickListener(View.OnClickListener { getWordSimillarityApi() })
        analyzer = UtilForAnalyzer.getAnalyzer()

    }

    private fun getWordSimillarityApi() {
        val wordsSimilarityTask = analyzer!!.analyseWordsSimilarity(
            similarWord1!!.text.toString(), similarWord2!!.text.toString() )
        wordsSimilarityTask.addOnSuccessListener { wordsSimilarity -&amp;gt;
            resultTextView!!.text = "The similarity value is $wordsSimilarity"
        }.addOnFailureListener { e -&amp;gt; onFailure(e) }
    }

    private fun onFailure(e: Exception?) {
        if (e is MLTextEmbeddingException) {
            val embeddingException = e
            embeddingException.errCode
            embeddingException.message
        } else {
        }
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a class for analyzer &lt;strong&gt;UtilForAnalyzer.kt&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UtilForAnalyzer {

    companion object{
        private var analyzer: MLTextEmbeddingAnalyzer? = null
        var setting: MLTextEmbeddingSetting? = null

        fun getAnalyzer(): MLTextEmbeddingAnalyzer? {
            if (analyzer == null) {
                setting = MLTextEmbeddingSetting.Factory()
                    .setLanguage(MLTextEmbeddingSetting.LANGUAGE_EN)
                    .create()
                analyzer = MLTextEmbeddingAnalyzerFactory.getInstance().getMLTextEmbeddingAnalyzer(setting)
            }
            return analyzer
        }

    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;SentenceSimilarActivity.kt&lt;/strong&gt; we can find the business logic for similar sentence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SentenceSimilarActivity : AppCompatActivity() {

    private var analyzer: MLTextEmbeddingAnalyzer? = null
    private var checkSentenceSimilarity: Button? = null
    private var sentence_1: EditText? = null
    private var sentence_2: EditText? = null
    var resultTextView: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sentence_similar)

        sentence_1 = findViewById(R.id.sentence1)
        sentence_2 = findViewById(R.id.sentence2)
        resultTextView = findViewById(R.id.similar_word_value)
        checkSentenceSimilarity = findViewById(R.id.check_sentence_similarity)
        checkSentenceSimilarity!!.setOnClickListener(View.OnClickListener { getSentenceSimilarityApi() })
        analyzer = UtilForAnalyzer.getAnalyzer()

    }

    private fun getSentenceSimilarityApi() {
        val sentencesSimilarityTask = analyzer!!.analyseSentencesSimilarity(
            sentence_1!!.text.toString(), sentence_2!!.text.toString()
        )
        sentencesSimilarityTask.addOnSuccessListener { sentencesSimilarity -&amp;gt;
            resultTextView!!.text = "The similarity value is $sentencesSimilarity"
        }.addOnFailureListener { e -&amp;gt; onFailure(e) }
    }

    private fun onFailure(e: Exception?) {
        if (e is MLTextEmbeddingException) {
            val embeddingException = e
            embeddingException.errCode
            embeddingException.message
        } else {
        }
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;SimilarWordsActivity.kt&lt;/strong&gt; we can find the business logic for similar words count.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SimilarWordsActivity : AppCompatActivity() {

    private var findSimilarWords: Button? = null
    private var word_1: EditText? = null
    private var word_2:EditText? = null
    private var analyzer: MLTextEmbeddingAnalyzer? = null
    var resultTextView: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_similar_words)

        word_1 = findViewById(R.id.word1)
        word_2 = findViewById(R.id.word2)
        resultTextView = findViewById(R.id.similar_word_value)
        findSimilarWords = findViewById(R.id.check_word_similarity)
        findSimilarWords!!.setOnClickListener(View.OnClickListener { noOfSimilarWords() })
        analyzer = UtilForAnalyzer.getAnalyzer()

    }

    private fun noOfSimilarWords() {
        val multipleSimilarityWordsTask = analyzer!!.analyseSimilarWords(
            word_1!!.text.toString(), word_2!!.text.toString().toInt() )
        multipleSimilarityWordsTask.addOnSuccessListener { words -&amp;gt;
            val stringBuilder = StringBuilder()
            for (word in words) {
                stringBuilder.append(word)
                stringBuilder.append("\t")
            }
            resultTextView!!.text = stringBuilder.toString()
        }.addOnFailureListener { e -&amp;gt; onFailure(e) }
    }

    private fun onFailure(e: Exception?) {
        if (e is MLTextEmbeddingException) {
            val embeddingException = e
            embeddingException.errCode
            embeddingException.message
        } else {
        }
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_main.xml&lt;/strong&gt; we can create the UI screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"&amp;gt;

    &amp;lt;Button
        android:id="@+id/word_similar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Check Word Similarity"
        android:textAllCaps="false"
        android:textSize="17sp"
        app:layout_constraintBottom_toTopOf="@+id/sentence_similar"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;
    &amp;lt;Button
        android:id="@+id/sentence_similar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Check Sentence Similarity"
        android:textAllCaps="false"
        android:textSize="17sp"
        app:layout_constraintBottom_toTopOf="@+id/similar_words"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/word_similar" /&amp;gt;
    &amp;lt;Button
        android:id="@+id/similar_words"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Get Similar Words"
        android:textAllCaps="false"
        android:textSize="17sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/word_similar" /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_word_similar.xml&lt;/strong&gt; we can create the UI screen for sentences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".WordSimilarActivity"&amp;gt;

    &amp;lt;EditText
        android:id="@+id/similar_word1"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="17sp"
        app:layout_constraintBottom_toTopOf="@+id/similar_word2"
        android:background="@drawable/edittext_bg"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;
    &amp;lt;EditText
        android:id="@+id/similar_word2"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="17sp"
        android:background="@drawable/edittext_bg"
        app:layout_constraintBottom_toTopOf="@+id/similar_word_value"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/similar_word1" /&amp;gt;
    &amp;lt;TextView
        android:id="@+id/similar_word_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/check_word_similarity"
        android:textColor="@color/black"
        android:textSize="20dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/similar_word2" /&amp;gt;
    &amp;lt;Button
        android:id="@+id/check_word_similarity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Check word Similarity"
        android:textAllCaps="false"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/similar_word_value" /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_sentence_similar.xml&lt;/strong&gt; we can create the UI screen for sentences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SentenceSimilarActivity"&amp;gt;

    &amp;lt;EditText
        android:id="@+id/sentence1"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="@drawable/edittext_bg"
        app:layout_constraintBottom_toTopOf="@+id/sentence2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;
    &amp;lt;EditText
        android:id="@+id/sentence2"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="@drawable/edittext_bg"
        app:layout_constraintBottom_toTopOf="@+id/similar_word_value"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/sentence1" /&amp;gt;
    &amp;lt;TextView
        android:id="@+id/similar_word_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/check_sentence_similarity"
        android:textColor="@color/purple_500"
        android:textSize="20dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/sentence2" /&amp;gt;
    &amp;lt;Button
        android:id="@+id/check_sentence_similarity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Check Sentence Similarity"
        android:textSize="17sp"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/similar_word_value" /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_similar_words.xm&lt;/strong&gt;l we can create the UI screen for words count.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SimilarWordsActivity"&amp;gt;

    &amp;lt;EditText
        android:id="@+id/word1"
        android:gravity="center"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:textSize="17sp"
        app:layout_constraintBottom_toTopOf="@+id/word2"
        android:background="@drawable/edittext_bg"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;
    &amp;lt;EditText
        android:id="@+id/word2"
        android:gravity="center"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:hint="enter number"
        android:textSize="17sp"
        android:inputType="number"
        android:background="@drawable/edittext_bg"
        app:layout_constraintBottom_toTopOf="@+id/similar_word_value"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/word1" /&amp;gt;
    &amp;lt;TextView
        android:id="@+id/similar_word_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        app:layout_constraintBottom_toTopOf="@+id/check_word_similarity"
        android:textColor="@color/black"
        android:textSize="15dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/word2" /&amp;gt;
    &amp;lt;Button
        android:id="@+id/check_word_similarity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Check Similar Words"
        android:textSize="17sp"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/similar_word_value" /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nnbo_GXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/17oms8r6yj1qmx31tmlq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nnbo_GXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/17oms8r6yj1qmx31tmlq.gif" alt="Image description" width="320" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips and Tricks&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make sure you are already registered as Huawei developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set minSDK version to 21 or later, otherwise you will get AndriodManifest merge issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added the agconnect-services.json file to app folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added SHA-256 fingerprint without fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure all the dependencies are added properly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we can learn how to check similar words and sentences using &lt;strong&gt;Text Embedding&lt;/strong&gt; feature of &lt;strong&gt;Huawei ML Kit&lt;/strong&gt;. This Huawei ML Kit provides &lt;strong&gt;Text Embedding&lt;/strong&gt; feature which helps to get matching vector value of &lt;strong&gt;words&lt;/strong&gt; or &lt;strong&gt;sentences&lt;/strong&gt;. Using this feature, we can improve our research based on the result. It provides similarity between two words or sentences and similar words of a particular word searched. We can also improve searching and browsing efficiency using after getting results related to search text.&lt;/p&gt;

&lt;p&gt;I hope you have read this article. If you found it is helpful, please provide likes and comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ML Kit&lt;/strong&gt; – &lt;a href="https://developer.huawei.com/consumer/en/doc/development/hiai-Guides/text-embedding-0000001055002819"&gt;Text Embedding&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ML Kit&lt;/strong&gt; – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101626700826278339"&gt;Training Video&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ads</category>
      <category>kotlin</category>
      <category>android</category>
      <category>xm</category>
    </item>
    <item>
      <title>Capture the bank cards using Bank Card Recognition feature by Huawei ML Kit in Android (Kotlin)</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Mon, 22 Aug 2022 06:36:00 +0000</pubDate>
      <link>https://dev.to/hmscommunity/capture-the-bank-cards-using-bank-card-recognition-feature-by-huawei-ml-kit-in-android-kotlin-544k</link>
      <guid>https://dev.to/hmscommunity/capture-the-bank-cards-using-bank-card-recognition-feature-by-huawei-ml-kit-in-android-kotlin-544k</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0rS_m0Um--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zilehpp4dt0baecwlxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0rS_m0Um--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zilehpp4dt0baecwlxq.png" alt="Image description" width="880" height="606"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we can learn how to recognize bank cards using &lt;strong&gt;Huawei ML Kit&lt;/strong&gt; of &lt;strong&gt;Bank Card Recognition&lt;/strong&gt; feature. The bank card recognition service recognizes bank cards in camera streams within an angle offset of &lt;strong&gt;15&lt;/strong&gt; degrees and extracts key information such as &lt;strong&gt;card number&lt;/strong&gt; and &lt;strong&gt;expiration date&lt;/strong&gt;. This service works with the &lt;strong&gt;ID card&lt;/strong&gt; recognition service to offer a host of popular functions such as identity verification and bank &lt;strong&gt;card number input&lt;/strong&gt;, making user operations easier than ever.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The bank card recognition service can extract bank card information in its original structure, which is useful for identity verification in financial services and bank card binding for payment in e-commerce apps. For example, in the past, when binding a bank card for online payment, users have to manually input their card numbers. It is easy to make mistakes. At present, with the bank card recognition service, inputting bank card numbers is automatic, thereby quick and accurate, greatly improving user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Precautions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the current version, only camera stream-based bank card recognition is supported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Any operating system (MacOS, Linux and Windows).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a Huawei phone with HMS 4.0.0.300 or later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimum API Level 21 is required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required EMUI 9.0.0 and later version devices.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to integrate HMS Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a &lt;a href="https://developer.huawei.com/consumer/en/doc/start/registration-and-verification-0000001053628148"&gt;Huawei ID&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a project in android studio, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#1"&gt;Creating an Android Studio Project&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To generate &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;. On right-upper corner of android project click &lt;strong&gt;Gradle&lt;/strong&gt;, choose &lt;strong&gt;Project Name &amp;gt; Tasks &amp;gt; android&lt;/strong&gt;, and then click &lt;strong&gt;signingReport&lt;/strong&gt;, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bzDyh8es--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aflkigomqgjdn7n8z3bb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bzDyh8es--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aflkigomqgjdn7n8z3bb.png" alt="Image description" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Project Name depends on the user created name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#0"&gt;Create an App in AppGallery Connect&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;strong&gt;agconnect-services.json&lt;/strong&gt; file from &lt;strong&gt;App information&lt;/strong&gt;, copy and paste in android &lt;strong&gt;Project&lt;/strong&gt; under &lt;strong&gt;app&lt;/strong&gt; directory, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u3NPEWIX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrk7ec8m5l2z96as99ur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u3NPEWIX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrk7ec8m5l2z96as99ur.png" alt="Image description" width="464" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt; and click &lt;strong&gt;Save&lt;/strong&gt; button, as follows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qBh1TQRw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hmzpl4uw1hfh8k15hhos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qBh1TQRw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hmzpl4uw1hfh8k15hhos.png" alt="Image description" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Manage APIs&lt;/strong&gt; tab and enable &lt;strong&gt;ML Kit&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rw_wx_Fc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i2896zmqv28akmezkikh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rw_wx_Fc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i2896zmqv28akmezkikh.png" alt="Image description" width="880" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the below maven URL in &lt;strong&gt;build.gradle(Project&lt;/strong&gt;) file under the repositories of &lt;strong&gt;buildscript&lt;/strong&gt;, &lt;strong&gt;dependencies&lt;/strong&gt; and &lt;strong&gt;allprojects&lt;/strong&gt;, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#6"&gt;Add Configuration&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add the below plugin and dependencies in &lt;strong&gt;build.gradle(Module)&lt;/strong&gt; file.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apply plugin: 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.5.0.300'
// ML Kit Bank Card Recognition
implementation 'com.huawei.hms:ml-computer-card-bcr:3.5.0.300'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now Sync the gradle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the required permission to the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name="android.permission.CAMERA" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Let us move to development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have created a project on Android studio with empty activity let us start coding.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;MainActivity.kt&lt;/strong&gt; we can find the business logic for buttons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MainActivity : AppCompatActivity() {

    var startCapture: Button? = null
    var permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)

    private val callback: MLBcrCapture.Callback = object : MLBcrCapture.Callback {
        override fun onSuccess(bankCardResult: MLBcrCaptureResult) {
            // Processing for successful recognition.
            val stringBuffer = StringBuffer()
            stringBuffer.append("Issuer Name :" + bankCardResult.issuer)
            stringBuffer.append("\n")
            stringBuffer.append("Organization Name :" + bankCardResult.organization)
            stringBuffer.append("\n")
            stringBuffer.append("Card Number :" + bankCardResult.number)
            stringBuffer.append("\n")
            stringBuffer.append("Expiery Date :" + bankCardResult.expire)
            stringBuffer.append("\n")
            stringBuffer.append("Card Type :" + bankCardResult.type)
            stringBuffer.append("\n")
            createDialog(stringBuffer.toString())
        }
        override fun onCanceled() {
            // Processing for recognition request cancellation.
            Toast.makeText(this@MainActivity, "Cancelled", Toast.LENGTH_SHORT).show()
        }
        // Callback method used when no text is recognized or a system exception occurs during recognition.
        // retCode: result code.
        // bitmap: bank card image that fails to be recognized.
        override fun onFailure(retCode: Int, bitmap: Bitmap) {
            // Processing logic for recognition failure.
            Toast.makeText(this@MainActivity, retCode.toString(), Toast.LENGTH_SHORT).show()
        }
        override fun onDenied() {
            // Processing for recognition request deny scenarios, for example, the camera is unavailable.
            Toast.makeText(this@MainActivity, "Denied", Toast.LENGTH_SHORT).show()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        requestPermission()
        startCapture = findViewById(R.id.start_capture)
        startCapture!!.setOnClickListener(View.OnClickListener { startCaptureActivity(callback) })

    }

    private fun startCaptureActivity(callback: MLBcrCapture.Callback) {
        val config = MLBcrCaptureConfig.Factory() // Set the expected result type of bank card recognition.
                // MLBcrCaptureConfig.RESULT_NUM_ONLY: Recognize only the bank card number.
                // MLBcrCaptureConfig.RESULT_SIMPLE: Recognize only the bank card number and validity period.
                // MLBcrCaptureConfig.ALL_RESULT: Recognize information such as the bank card number, validity period, issuing bank, card organization, and card type.
                .setResultType(MLBcrCaptureConfig.RESULT_ALL) // Set the recognition screen display orientation.
                // MLBcrCaptureConfig.ORIENTATION_AUTO: adaptive mode. The display orientation is determined by the physical sensor.
                // MLBcrCaptureConfig.ORIENTATION_LANDSCAPE: landscape mode.
                // MLBcrCaptureConfig.ORIENTATION_PORTRAIT: portrait mode.
                .setOrientation(MLBcrCaptureConfig.ORIENTATION_AUTO)
                .create()
        val bankCapture = MLBcrCaptureFactory.getInstance().getBcrCapture(config)
        bankCapture.captureFrame(this, callback)
    }

    private fun requestPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
            ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, permissions, 111)
        }
    }

    @SuppressLint("InflateParams")
    private fun createDialog(retrievedText: String) {
        val wm = this@MainActivity.getSystemService(WINDOW_SERVICE) as WindowManager
        val width = wm.defaultDisplay.width
        val height = wm.defaultDisplay.height
        val dialog = Dialog(this@MainActivity, R.style.MyDialog)
        val view: View = LayoutInflater.from(this@MainActivity).inflate(R.layout.layout_for_dialog, null)
        (view.findViewById&amp;lt;View&amp;gt;(R.id.retrieved_information) as TextView).text = retrievedText
        val params = dialog.window!!.attributes
        params.width = WindowManager.LayoutParams.MATCH_PARENT
        params.height = WindowManager.LayoutParams.WRAP_CONTENT
        dialog.setContentView(view)
        dialog.window!!.setGravity(Gravity.CENTER)
        dialog.window!!.setWindowAnimations(R.style.MyDialog)
        dialog.show()
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_main.xml&lt;/strong&gt; we can create the UI screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"&amp;gt;

    &amp;lt;Button
        android:id="@+id/start_capture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Capture"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The layout for the dialog is &lt;strong&gt;layout_for_dialog.xml&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"&amp;gt;

    &amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"&amp;gt;
        &amp;lt;TextView
            android:id="@+id/retrieved_information"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:scrollbars="vertical"
            android:textColor="@color/black" /&amp;gt;
    &amp;lt;/LinearLayout&amp;gt;

&amp;lt;/ScrollView&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f4Beqtmf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qd9ozsg8uobpfwt13biy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f4Beqtmf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qd9ozsg8uobpfwt13biy.gif" alt="Image description" width="216" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips and Tricks&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make sure you are already registered as Huawei developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set minSDK version to 21 or later, otherwise you will get AndriodManifest merge issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added the agconnect-services.json file to app folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added SHA-256 fingerprint without fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure all the dependencies are added properly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we have learned how to recognize bank cards using &lt;strong&gt;Huawei ML Kit&lt;/strong&gt; of &lt;strong&gt;Bank Card Recognition&lt;/strong&gt; feature. The bank card recognition service recognizes bank cards in camera streams within an angle offset of &lt;strong&gt;15 degrees&lt;/strong&gt; and extracts key information such as &lt;strong&gt;card number&lt;/strong&gt; and &lt;strong&gt;expiration&lt;/strong&gt; &lt;strong&gt;date&lt;/strong&gt;. This service works with the &lt;strong&gt;ID card&lt;/strong&gt; recognition service to offer a host of popular functions such as identity verification and bank &lt;strong&gt;card number input&lt;/strong&gt;, making user operations easier than ever.&lt;/p&gt;

&lt;p&gt;I hope you have read this article. If you found it is helpful, please provide likes and comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ML Kit&lt;/strong&gt; – &lt;a href="https://developer.huawei.com/consumer/en/doc/development/hiai-Guides/bank-card-recognition-0000001050038118"&gt;Bank Card Recognition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ML Kit&lt;/strong&gt; – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101628260104789916"&gt;Training Video&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>mlkit</category>
      <category>android</category>
      <category>xml</category>
    </item>
    <item>
      <title>Integration of the Rewarded Ads feature of Huawei Ads Kit in Android</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Mon, 22 Aug 2022 06:18:08 +0000</pubDate>
      <link>https://dev.to/hmscommunity/integration-of-the-rewarded-ads-feature-of-huawei-ads-kit-in-android-k1f</link>
      <guid>https://dev.to/hmscommunity/integration-of-the-rewarded-ads-feature-of-huawei-ads-kit-in-android-k1f</guid>
      <description>&lt;p&gt;In this article, we can learn how to integrate Rewarded Ads feature of Huawei Ads Kit into the android app. So, Rewarded ads are full-screen video ads that allow users to view in exchange for in-app rewards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ads Kit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Huawei Ads provides to developers a wide-ranging capabilities to deliver good quality ads content to users. This is the best way to reach the target audience easily and can measure user productivity. It is very useful when we publish a free app and want to earn some money from it.&lt;/p&gt;

&lt;p&gt;HMS Ads Kit has 7 types of Ads kits. Now we can implement Rewarded Ads in this application.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Integration of the Rewarded Ads feature of Huawei Ads Kit in Android app (Kotlin)</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Tue, 16 Aug 2022 07:12:00 +0000</pubDate>
      <link>https://dev.to/hmscommunity/search-the-hospitals-using-huawei-map-kit-site-kit-and-location-kit-in-patient-tracking-android-app-kotlin-part-5-5cio</link>
      <guid>https://dev.to/hmscommunity/search-the-hospitals-using-huawei-map-kit-site-kit-and-location-kit-in-patient-tracking-android-app-kotlin-part-5-5cio</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uCcjV8o4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8bga80kejzsjdx66xf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uCcjV8o4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8bga80kejzsjdx66xf9.png" alt="Image description" width="880" height="264"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we can learn how to integrate &lt;strong&gt;Rewarded Ads feature of Huawei Ads Kit&lt;/strong&gt; into the android app. So, Rewarded ads are full-screen video ads that allow users to view in exchange for in-app rewards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ads Kit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Huawei Ads provides to developers a wide-ranging capabilities to deliver good quality ads content to users. This is the best way to reach the target audience easily and can measure user productivity. It is very useful when we publish a free app and want to earn some money from it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HMS Ads Kit&lt;/strong&gt; has &lt;strong&gt;7&lt;/strong&gt; types of Ads kits. Now we can implement Rewarded Ads in this application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Any operating system (MacOS, Linux and Windows).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a Huawei phone with HMS 4.0.0.300 or later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimum API Level 24 is required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required EMUI 9.0.0 and later version devices.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to integrate HMS Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a &lt;a href="https://developer.huawei.com/consumer/en/doc/start/registration-and-verification-0000001053628148"&gt;Huawei ID&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a project in android studio, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#1"&gt;Creating an Android Studio Project&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To generate &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;. On right-upper corner of android project click &lt;strong&gt;Gradle&lt;/strong&gt;, choose &lt;strong&gt;Project Name &amp;gt; Tasks &amp;gt; android&lt;/strong&gt;, and then click &lt;strong&gt;signingReport&lt;/strong&gt;, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HbxJYxCt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5t7d9z6527buuxpkobvb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HbxJYxCt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5t7d9z6527buuxpkobvb.png" alt="Image description" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Project Name depends on the user created name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#0"&gt;Create an App in AppGallery Connect&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;strong&gt;agconnect-services.json&lt;/strong&gt; file from &lt;strong&gt;App information&lt;/strong&gt;, &lt;strong&gt;copy&lt;/strong&gt; and &lt;strong&gt;paste&lt;/strong&gt; in android &lt;strong&gt;Project&lt;/strong&gt; under &lt;strong&gt;app&lt;/strong&gt; directory, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ao3h_oj5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w4vu1ookyvvpyhv6exdd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ao3h_oj5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w4vu1ookyvvpyhv6exdd.png" alt="Image description" width="464" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt; and click &lt;strong&gt;Save&lt;/strong&gt; button, as follows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gTpH7Cmz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lrlwi70gp9ks9t291t87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gTpH7Cmz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lrlwi70gp9ks9t291t87.png" alt="Image description" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the below maven URL in &lt;strong&gt;build.gradle(Project)&lt;/strong&gt; file under the repositories of &lt;strong&gt;buildscript&lt;/strong&gt;, &lt;strong&gt;dependencies&lt;/strong&gt; and &lt;strong&gt;allprojects&lt;/strong&gt;, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#6"&gt;Add Configuration&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add the below plugin and dependencies in &lt;strong&gt;build.gradle(Module)&lt;/strong&gt; file.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apply plugin: id 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Huawei Ads Kit
implementation 'com.huawei.hms:ads-lite:13.4.51.300'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now Sync the gradle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the required permission to the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Ads Kit
&amp;lt;uses-permission android:name="android.permission.INTERNET" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Let us move to development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have created a project on Android studio with empty activity let us start coding.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;MainActivity.kt&lt;/strong&gt; we can find the business logic for Ads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MainActivity : AppCompatActivity() {

    companion object {
        private const val PLUS_SCORE = 1
        private const val MINUS_SCORE = 5
        private const val RANGE = 2
    }
    private var rewardedTitle: TextView? = null
    private var scoreView: TextView? = null
    private var reStartButton: Button? = null
    private var watchAdButton: Button? = null
    private var rewardedAd: RewardAd? = null
    private var score = 1
    private val defaultScore = 10

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        title = getString(R.string.reward_ad)
        rewardedTitle = findViewById(R.id.text_reward)
        rewardedTitle!!.setText(R.string.reward_ad_title)

        // Load a rewarded ad.
        loadRewardAd()

        // Load a score view.
        loadScoreView()

        // Load the button for watching a rewarded ad.
        loadWatchButton()

        // Load the button for starting a game.
        loadPlayButton()

    }

    // Load a rewarded ad.
    private fun loadRewardAd() {
        if (rewardedAd == null) {
            rewardedAd = RewardAd(this@MainActivity, getString(R.string.ad_id_reward))
        }
        val rewardAdLoadListener: RewardAdLoadListener = object : RewardAdLoadListener() {
            override fun onRewardAdFailedToLoad(errorCode: Int) {
                showToast("onRewardAdFailedToLoad errorCode is :$errorCode");
            }
            override fun onRewardedLoaded() {
                showToast("onRewardedLoaded")
            }
        }
        rewardedAd!!.loadAd(AdParam.Builder().build(), rewardAdLoadListener)
    }

   // Display a rewarded ad.
    private fun rewardAdShow() {
        if (rewardedAd!!.isLoaded) {
            rewardedAd!!.show(this@MainActivity, object : RewardAdStatusListener() {
                override fun onRewardAdClosed() {
                    showToast("onRewardAdClosed")
                    loadRewardAd()
                }
                override fun onRewardAdFailedToShow(errorCode: Int) {
                    showToast("onRewardAdFailedToShow errorCode is :$errorCode")
                }
                override fun onRewardAdOpened() {
                    showToast("onRewardAdOpened")
                }
                override fun onRewarded(reward: Reward) {
                    // You are advised to grant a reward immediately and at the same time, check whether the reward
                    // takes effect on the server. If no reward information is configured, grant a reward based on the
                    // actual scenario.
                    val addScore = if (reward.amount == 0) defaultScore else reward.amount
                    showToast("Watch video show finished , add $addScore scores")
                    score += addScore
                    setScore(score)
                    loadRewardAd()
                }
            })
        }
    }

    // Set a Score
    private fun setScore(score: Int) {
        scoreView!!.text = "Score:$score"
    }

    // Load the button for watching a rewarded ad
    private fun loadWatchButton() {
        watchAdButton = findViewById(R.id.show_video_button)
        watchAdButton!!.setOnClickListener(View.OnClickListener { rewardAdShow() })
    }

    // Load the button for starting a game
    private fun loadPlayButton() {
        reStartButton = findViewById(R.id.play_button)
        reStartButton!!.setOnClickListener(View.OnClickListener { play() })
    }

    private fun loadScoreView() {
        scoreView = findViewById(R.id.score_count_text)
        scoreView!!.text = "Score:$score"
    }

    // Used to play a game
    private fun play() {
        // If the score is 0, a message is displayed, asking users to watch the ad in exchange for scores.
        if (score == 0) {
            Toast.makeText(this@MainActivity, "Watch video ad to add score", Toast.LENGTH_SHORT).show()
            return
        }
        // The value 0 or 1 is returned randomly. If the value is 1, the score increases by 1. If the value is 0, the
        // score decreases by 5. If the score is a negative number, the score is set to 0.
        val random = Random().nextInt(RANGE)
        if (random == 1) {
            score += PLUS_SCORE
            Toast.makeText(this@MainActivity, "You win！", Toast.LENGTH_SHORT).show()
        } else {
            score -= MINUS_SCORE
            score = if (score &amp;lt; 0) 0 else score
            Toast.makeText(this@MainActivity, "You lose！", Toast.LENGTH_SHORT).show()
        }
        setScore(score)
    }

    private fun showToast(text: String) {
        runOnUiThread {
            Toast.makeText(this@MainActivity, text, Toast.LENGTH_SHORT).show()
        }
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_main.xml&lt;/strong&gt; we can create the UI screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"&amp;gt;

    &amp;lt;TextView
        android:id="@+id/text_reward"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:textAlignment="center"
        android:textSize="20sp"
        android:text="This is rewarded ads sample"/&amp;gt;

    &amp;lt;Button
        android:id="@+id/play_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text_reward"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:text="Play" /&amp;gt;

    &amp;lt;Button
        android:id="@+id/show_video_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/play_button"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:text="Watch Video" /&amp;gt;

    &amp;lt;TextView
        android:id="@+id/score_count_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/show_video_button"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:textAppearance="?android:attr/textAppearanceLarge" /&amp;gt;

&amp;lt;/RelativeLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kYCd5fXw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sk16xll9umhtv3i8vups.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kYCd5fXw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sk16xll9umhtv3i8vups.gif" alt="Image description" width="320" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips and Tricks&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make sure you are already registered as Huawei developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added the agconnect-services.json file to app folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have added SHA-256 fingerprint without fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure all the dependencies are added properly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we have learned how to integrate the &lt;strong&gt;Huawei Analytics Kit&lt;/strong&gt; and &lt;strong&gt;Ads Kit&lt;/strong&gt; in Book Reading app. So, I will provide the series of articles on this Book Reading App, in upcoming articles will integrate other Huawei Kits.&lt;/p&gt;

&lt;p&gt;I hope you have read this article. If you found it is helpful, please provide likes and comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ads Kit - &lt;a href="https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/publisher-service-reward-0000001050066917"&gt;Rewarded Ads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ads Kit – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101614748910616026"&gt;Training Video&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ads</category>
      <category>kotlin</category>
      <category>android</category>
      <category>hmscore</category>
    </item>
    <item>
      <title>Huawei Cloud DB — How to perform CRUD operation</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Fri, 12 Aug 2022 07:26:45 +0000</pubDate>
      <link>https://dev.to/hmscommunity/huawei-cloud-db-how-to-perform-crud-operation-bj0</link>
      <guid>https://dev.to/hmscommunity/huawei-cloud-db-how-to-perform-crud-operation-bj0</guid>
      <description>&lt;p&gt;For our scenario, we will have two tables named BookmarkStatus and LikeStatus. BookmarkStatus and LikeStatus tables holds a record for each user’s bookmark/like for the specified object and deletes the record when user remove his/her like or bookmark.&lt;/p&gt;

&lt;p&gt;Let’s start with initializing our cloud db object. I will initialize cloud db object once when application started (in SplashScreen) and use it through the application.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;companion object {        &lt;br&gt;
fun initDb() {            AGConnectCloudDB.initialize(ContextProvider.getApplicationContext())        }    &lt;br&gt;
}     &lt;br&gt;
fun dbGetInstance(){  &lt;br&gt;
      mCloudDb = AGConnectCloudDB.getInstance()  &lt;br&gt;
  }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, create a base viewModel to call certain functions of cloud db instead of calling them in every viewModel.&lt;br&gt;
&lt;code&gt;open class BaseViewModel : ViewModel() {&lt;br&gt;
    var mCloudDbZoneWrapper: CloudDbRepository =&lt;br&gt;
        CloudDbRepository()&lt;br&gt;
    init {&lt;br&gt;
        mCloudDbZoneWrapper.createObjectType()&lt;br&gt;
        mCloudDbZoneWrapper.openCloudDbZone()&lt;br&gt;
    }&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
Here is what createObjectType() and openCloudDbZone() functions do.&lt;br&gt;
`/*&lt;br&gt;
    Create object type&lt;br&gt;
    */&lt;br&gt;
    fun createObjectType() {&lt;br&gt;
        dbGetInstance()&lt;br&gt;
        try {&lt;br&gt;
            mCloudDb!!.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo())&lt;br&gt;
        } catch (exception: AGConnectCloudDBException) {&lt;br&gt;
            Log.w("CloudDbRepository", exception.errMsg)&lt;br&gt;
        }&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
Following method opens cloud db zone with given configs.
*/
fun openCloudDbZone() {
    val mConfig: CloudDBZoneConfig = CloudDBZoneConfig(
        "YOUR_CLOUD_DB_NAME", CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE,
        CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC
    )
    mConfig.persistenceEnabled = true

    try {
        mCloudDbZone = mCloudDb!!.openCloudDBZone(mConfig, true)
    } catch (exception: AGConnectCloudDBException) {
        Log.w("CloudDbRepository", exception.errMsg)
    }
}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have all settings done. All we need to do is calling executeUpsert() and executeDelete() functions properly in related repositories.&lt;br&gt;
`private fun bookmarkResult(&lt;br&gt;
        snapshot: CloudDBZoneSnapshot,&lt;br&gt;
        bookmark: BookmarkStatus,&lt;br&gt;
        triggered: Boolean&lt;br&gt;
    ) {&lt;br&gt;
        val bookmarkStatsCursor: CloudDBZoneObjectList = snapshot.snapshotObjects&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    try {
        if (bookmarkStatsCursor.hasNext()) {
            val bookmarkStats = bookmarkStatsCursor.next()
            if (bookmarkStats != null &amp;amp;&amp;amp; bookmarkStats.object != null) {
                if (triggered) {
                    //deleteBookmark
                    val deleteTask = mCloudDBZone.executeDelete(bookmarkStats)
                    deleteTask.addOnSuccessListener {
                        Log.w(TAG, "BookmarkDelete success")
                        bookmarkStatus.postValue(false)
                    }.addOnFailureListener {
                        Log.w(TAG, "BookmarkDelete fail" + it.message)
                    }
                } else {
                    bookmarkStatus.postValue(true)
                }
            }
        } else {
            if (triggered) {
                //add bookmark
                val upsertTask = mCloudDBZone.executeUpsert(bookmark)
                upsertTask.addOnSuccessListener {
                    Log.w(TAG, "BookmarkAdd success")
                    bookmarkStatus.postValue(true)
                }.addOnFailureListener {
                    Log.w(TAG, "BookmarkDelete fail" + it.message)
                }
            } else {
                bookmarkStatus.postValue(false)
            }
        }

    } catch (exception: Exception) {
    }
    snapshot.release()
}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this function, triggered parameter is for if user clicked bookmark button or not if clicked then value is true.&lt;/p&gt;

&lt;p&gt;Here is the logic;&lt;/p&gt;

&lt;p&gt;If user bookmarked the given object (which is queried in another method and passed as a parameter to this method as snapshot) then bookmarkStatsCursor.hasNext() returns true and if not triggered , this means user bookmarked the object and is trying to display bookmark status and all we need to do is using postValue() of the observable property bookmarkStatus and pass the value as true. Let’s say user has a record on BookmarkStatus table and triggered is true then we can say user is trying to remove bookmark of the object. So we need to use executeDelete(bookmark) to delete bookmark from table. With the help of addOnSuccessListener we will post value as false which means user does not have a bookmark on the given object anymore.&lt;/p&gt;

&lt;p&gt;If user does not have a bookmark in given object and triggered is false, this means user did not bookmark object and trying to display bookmark status. We will post value as false. If triggered is true then, user is trying to add bookmark to that object. In this situation, we will add a record to the bookmark table using executeUpsert(bookmark) method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8W4as9Iw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/39bjduoooorax9zbk970.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8W4as9Iw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/39bjduoooorax9zbk970.gif" alt="Image description" width="200" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that you can use addOnFailureListener to catch errors occurred during adding or deleting functions.&lt;/p&gt;

&lt;p&gt;To add or delete records to/from LikeStatus table, you can use same logic with BookmarkStatus table given above.&lt;/p&gt;

&lt;p&gt;So, as you can see, it is very simple to implement cloud db in your project and you can apply all CRUD functions simply as demonstrated above :)&lt;/p&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-clouddb-introduction-0000001054212760"&gt;https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-clouddb-introduction-0000001054212760&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Integrating Huawei ML Kit(Text Translation) in Client Server Messaging App Using Socket in Android</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Fri, 05 Aug 2022 11:52:00 +0000</pubDate>
      <link>https://dev.to/hmscommunity/integrating-huawei-ml-kittext-translation-in-client-server-messaging-app-using-socket-in-android-1a7b</link>
      <guid>https://dev.to/hmscommunity/integrating-huawei-ml-kittext-translation-in-client-server-messaging-app-using-socket-in-android-1a7b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we will learn how to integrate Huawei ML kit in Android application. ML Kit provides many text service, you can check these services in the link provided in the reference section , in this sample we will be integrating one of its text service I.e. On-device translation, it translates text from the source language into the target language with the support of an on-device model, even when no Internet service is available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supported Devices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d032DRnO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ltfq9us4rz2qn9wlgrv.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d032DRnO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ltfq9us4rz2qn9wlgrv.PNG" alt="Image description" width="880" height="309"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Development Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need to install Android Studio IDE and I assume that you have prior knowledge of Android application development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardware Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A computer (desktop or laptop) running Windows 10.&lt;br&gt;
Android phone (with the USB cable), which is used for debugging.&lt;br&gt;
&lt;strong&gt;Software Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Java JDK 1.8 or later.&lt;br&gt;
Android Studio software installed.&lt;br&gt;
HMS Core (APK) 4.X or later&lt;br&gt;
&lt;strong&gt;Integration steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Huawei developer account and complete identity verification in Huawei developer website, refer to register &lt;a href="https://developer.huawei.com/consumer/en/doc/start/registration-and-verification-0000001053628148"&gt;Huawei ID&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#0"&gt;Create project in AppGallery Connect&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3.&lt;/strong&gt; &lt;a href="https://developer.huawei.com/consumer/en/doc/development/hiai-Guides/add-appgallery-0000001050038080"&gt;Adding HMS Core SDK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's start coding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I call sign in method?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void signInWithHuaweiID() {

AccountAuthParams authParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setAuthorizationCode().createParams();

service = AccountAuthManager.getService(ClientActivity.this, authParams);

startActivityForResult(service.getSignInIntent(), 1212);

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I get sign in result?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

// Process the authorization result to obtain the authorization code from AuthAccount.

super.onActivityResult(requestCode, resultCode, data);

if (requestCode == 1212) {

Task&amp;lt;AuthAccount&amp;gt; authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);

if (authAccountTask.isSuccessful()) {

// The sign-in is successful, and the user's ID information and authorization code are obtained.

AuthAccount authAccount = authAccountTask.getResult();

Log.i("TAG", "serverAuthCode:" + authAccount.getAuthorizationCode());

userName = authAccount.getDisplayName();

makeConnect();

} else {

// The sign-in failed.

Log.e("TAG", "sign in failed:" + ((ApiException) authAccountTask.getException()).getStatusCode());

}

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I start server?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wManager = (WifiManager) getSystemService(WIFI_SERVICE);

serverIP = Formatter.formatIpAddress(wManager.getConnectionInfo().getIpAddress());

ip_txt.setText(serverIP);

class ServerThread implements Runnable {

@Override

public void run() {

try {

while (true) {

serverSocket = new ServerSocket(POST_NUMBER);

socket = serverSocket.accept();

output = new PrintWriter(socket.getOutputStream());

input = new BufferedReader(new InputStreamReader(socket.getInputStream()));

Log.d("TAG", " here ");

runOnUiThread(new Runnable() {

@Override

public void run() {

tv_status.setText("Waiting for conn at " + POST_NUMBER);

}

});

handler.post(new Runnable() {

@Override

public void run() {

tv_status.setText("Connected");

}

});

}

} catch (Exception e) {

e.printStackTrace();

}

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I send message using socket?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SendMessage implements Runnable {

private String message;

SendMessage(String message) {

this.message = message;

}

@Override

public void run() {

output.write(message+"\r");

output.flush();

runOnUiThread(new Runnable() {

@Override

public void run() {

tv_chat.append("\n New Message: " + message);

ed_message.setText("");

}

});

Thread.interrupted();

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I receive message using socket?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private class ReadMessage implements Runnable {

@Override

public void run() {

while (true) {

try {

// Log.d("TAG","Server: Listening for message");

if(input!=null){

final String message = input.readLine();

if (message != null) {

handler.post(new Runnable() {

@Override

public void run() {

tv_chat.append("\n" + message );

}

});

}

}

} catch (IOException e) {

// Log.e("TAG","Error while receiving message");

e.printStackTrace();

}

}

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Close the Socket and other connections&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override

protected void onPause() {

super.onPause();

if (socket != null) {

try {

output.close();

input.close();

socket.close();



} catch (IOException e) {

e.printStackTrace();

}

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I revoke auth permission?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(service!=null){

// service indicates the AccountAuthService instance generated using the getService method during the sign-in authorization.

service.cancelAuthorization().addOnCompleteListener(new OnCompleteListener&amp;lt;Void&amp;gt;() {

@Override

public void onComplete(Task&amp;lt;Void&amp;gt; task) {

if (task.isSuccessful()) {

// Processing after a successful authorization cancellation.

Log.i("TAG", "onSuccess: ");

} else {

// Handle the exception.

Exception exception = task.getException();

if (exception instanceof ApiException){

int statusCode = ((ApiException) exception).getStatusCode();

Log.i("TAG", "onFailure: " + statusCode);

}

}

}

});

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I translate message using ML Text Service?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void translateMessage(String text) {

MLApplication.getInstance().setApiKey(API_KEY);

// create an offline translator.

MLLocalTranslateSetting setting = new 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("en")

// 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("hi")

.create();

myLocalTranslator = MLTranslatorFactory.getInstance().getLocalTranslator(setting);

// Set the model download policy.

MLModelDownloadStrategy downloadStrategy = new MLModelDownloadStrategy.Factory()

.needWifi()// It is recommended that you download the package in a Wi-Fi environment.

.create();

// Create a download progress listener.

MLModelDownloadListener modelDownloadListener = new MLModelDownloadListener() {

@Override

public void onProcess(long alreadyDownLength, long totalLength) {

runOnUiThread(new Runnable() {

@Override

public void run() {

// Display the download progress or perform other operations.

}

});

}

};

myLocalTranslator.preparedModel(downloadStrategy, modelDownloadListener).

addOnSuccessListener(new OnSuccessListener&amp;lt;Void&amp;gt;() {

@Override

public void onSuccess(Void aVoid) {

// Called when the model package is successfully downloaded.

// input is a string of less than 5000 characters.

final Task&amp;lt;String&amp;gt; task = myLocalTranslator.asyncTranslate(text);

// Before translation, ensure that the models have been successfully downloaded.

task.addOnSuccessListener(new OnSuccessListener&amp;lt;String&amp;gt;() {

@Override

public void onSuccess(String translated) {

// Processing logic for detection success.

Log.d("TAG", "Text : " + translated);

}

}).addOnFailureListener(new OnFailureListener() {

@Override

public void onFailure(Exception e) {

e.printStackTrace();

}

});

}

}).addOnFailureListener(new OnFailureListener() {

@Override

public void onFailure(Exception e) {

e.printStackTrace();

}

});

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tricks and Tips&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Makes sure that agconnect-services.json file added.&lt;br&gt;
Make sure required dependencies are added&lt;br&gt;
Make sure that service is enabled in AGC&lt;br&gt;
Make sure that languages are supported&lt;br&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we have learnt how to integrate Huawei ML kit service i.e. text translation(message) in Client Server messaging using Socket in Android application. You can check the desired result in the result section. Hoping Huawei ML kit capabilities are helpful to you as well, like this sample, you can make use of ML services as per your requirement.&lt;/p&gt;

&lt;p&gt;Thank you so much for reading. I hope this article helps you to understand the integration of Huawei ML kit in Android application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/introduction-0000001050048870"&gt;Huawei ML Kit&lt;/a&gt; – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101590717026948018"&gt;Training video&lt;/a&gt;&lt;br&gt;
&lt;a href="https://forums.developer.huawei.com/forumPortal/en/topic/0202950768632370171"&gt;Checkout in forum&lt;/a&gt;&lt;/p&gt;

</description>
      <category>huaweimlkit</category>
      <category>hmscore</category>
      <category>accountkit</category>
      <category>java</category>
    </item>
    <item>
      <title>Integration of Huawei Site Kit in KnowMyBoard using kotlin Part 4</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Mon, 01 Aug 2022 03:52:20 +0000</pubDate>
      <link>https://dev.to/hmscommunity/integration-of-huawei-site-kit-in-knowmyboard-using-kotlin-part-4-4b6c</link>
      <guid>https://dev.to/hmscommunity/integration-of-huawei-site-kit-in-knowmyboard-using-kotlin-part-4-4b6c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Site Kit is basically used for apps to provide the place related services. This kit provide to search the places with keyword, Find nearby place, place suggestion for user input, Get place details using the unique id.&lt;/p&gt;

&lt;p&gt;Features of Huawei Site Kit&lt;/p&gt;

&lt;p&gt;Keyword search: Returns a place list based on keywords entered by the user.&lt;br&gt;&lt;br&gt;
Nearby place search: Searches for nearby places based on the current location of the user's device.&lt;br&gt;
Place details: Searches for details about a place. &lt;br&gt;
Search suggestion: Returns a list of place suggestions.&lt;br&gt;
Site Search: Returns a site object.&lt;br&gt;
Development Overview&lt;/p&gt;

&lt;p&gt;You need to install Android Studio IDE and I assume that you have prior knowledge of Android application development.&lt;/p&gt;

&lt;p&gt;Hardware Requirements&lt;/p&gt;

&lt;p&gt;A computer (desktop or laptop) running Windows 10.&lt;br&gt;
Android phone (with the USB cable), which is used for debugging.&lt;br&gt;
Software Requirements&lt;/p&gt;

&lt;p&gt;Java JDK 1.8 or later.&lt;br&gt;
Android Studio software or Visual Studio or Code installed.&lt;br&gt;
HMS Core (APK) 4.X or later&lt;br&gt;
Integration steps&lt;/p&gt;

&lt;p&gt;Step 1. Huawei developer account and complete identity verification in Huawei developer website, refer to register Huawei ID.&lt;/p&gt;

&lt;p&gt;Step 2. Create project in AppGallery Connect&lt;/p&gt;

&lt;p&gt;Step 3. Adding HMS Core SDK&lt;/p&gt;

&lt;p&gt;Let's start coding&lt;/p&gt;

&lt;p&gt;MainActivity.kt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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&amp;lt;String&amp;gt;()
    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) &amp;amp;&amp;amp; (resultCode == RESULT_OK) &amp;amp;&amp;amp; (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) &amp;amp;&amp;amp; (resultCode == RESULT_OK) &amp;amp;&amp;amp; (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&amp;lt;MLText&amp;gt; {
            override fun onSuccess(text: MLText) {
                progressDialog!!.setMessage("Initializing language detection..")
                textRecognized = text.stringValue.trim { it &amp;lt;= ' ' }
                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 -&amp;gt;
                        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", "#==&amp;gt;" + 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&amp;lt;Void?&amp;gt; {
                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&amp;lt;String&amp;gt; {
                        override fun onSuccess(translated: String) {
                            // Processing logic for detection success.
                            result.clear()
                            result.add(languageDetected.trim { it &amp;lt;= ' ' })
                            result.add(textRecognized.trim { it &amp;lt;= ' ' })
                            result.add(translated.trim { it &amp;lt;= ' ' })
                            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"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LoginViewModel.kt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
package com.huawei.hms.knowmyboard.dtse.activity.viewmodel

import android.app.Application
import com.huawei.hms.support.account.service.AccountAuthService
import android.graphics.Bitmap
import com.huawei.hms.location.LocationResult
import com.huawei.hms.site.api.model.Site
import android.widget.Toast
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.huawei.hms.common.ApiException
import com.huawei.hms.knowmyboard.dtse.R
import com.huawei.hms.support.account.request.AccountAuthParams
import com.huawei.hms.support.account.request.AccountAuthParamsHelper
import com.huawei.hms.support.account.AccountAuthManager
import com.huawei.hms.knowmyboard.dtse.activity.app.MyApplication
import java.util.ArrayList

class LoginViewModel(application: Application) : AndroidViewModel(application) {
    var service: AccountAuthService? = null
    val message = MutableLiveData&amp;lt;String&amp;gt;()
    val textRecongnized = MutableLiveData&amp;lt;ArrayList&amp;lt;String&amp;gt;&amp;gt;()
    val imagePath = MutableLiveData&amp;lt;Bitmap&amp;gt;()
    val locationResult = MutableLiveData&amp;lt;LocationResult&amp;gt;()
    val siteSelected = MutableLiveData&amp;lt;Site&amp;gt;()
    fun getSiteSelected(): LiveData&amp;lt;Site&amp;gt; {
        return siteSelected
    }

    fun setSiteSelected(siteSelected: Site) {
        this.siteSelected.value = siteSelected
    }

    fun sendData(msg: String) {
        message.value = msg
    }

    fun getMessage(): LiveData&amp;lt;String&amp;gt; {
        return message
    }

    fun setImage(imagePath: Bitmap) {
        this.imagePath.value = imagePath
    }

    fun setLocationResult(locationResult: LocationResult) {
        this.locationResult.value = locationResult
    }

    fun setTextRecongnized(textRecongnized: ArrayList&amp;lt;String&amp;gt;) {
        this.textRecongnized.value = textRecongnized
    }

    fun logoutHuaweiID() {
        if (service != null) {
            service!!.signOut()
            sendData("KnowMyBoard")
            Toast.makeText(getApplication(), "You are logged out from Huawei ID", Toast.LENGTH_LONG)
                .show()
        }
    }

    fun loginClicked() {
        val authParams =
            AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setAuthorizationCode()
                .createParams()
        service = AccountAuthManager.getService(MyApplication.activity, authParams)
        MyApplication.activity!!.startActivityForResult(service!!.signInIntent, 8888)
    }

    fun cancelAuthorization() {
        if (service != null) {
            // service indicates the AccountAuthService instance generated using the getService method during the sign-in authorization.
            service!!.cancelAuthorization().addOnCompleteListener { task -&amp;gt;
                if (task.isSuccessful) {
                    // Processing after a successful authorization cancellation.
                    sendData(getApplication&amp;lt;Application&amp;gt;().resources.getResourceName(R.string.app_name))
                    Toast.makeText(getApplication(), "Cancelled authorization", Toast.LENGTH_LONG)
                        .show()
                } else {
                    // Handle the exception.
                    val exception = task.exception
                    if (exception is ApiException) {
                        val statusCode = exception.statusCode
                        Toast.makeText(
                            getApplication(),
                            "Failed to cancel authorization. status code $statusCode",
                            Toast.LENGTH_LONG
                        ).show()
                    }
                }
            }
        } else {
            Toast.makeText(getApplication(), "Login required", Toast.LENGTH_LONG).show()
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SearchFragment.kt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.huawei.hms.knowmyboard.dtse.activity.fragments

import androidx.navigation.Navigation.findNavController
import com.huawei.hms.knowmyboard.dtse.activity.viewmodel.LoginViewModel
import androidx.navigation.NavController
import com.huawei.hms.site.api.SearchService
import com.huawei.hms.knowmyboard.dtse.activity.adapter.SitesAdapter
import com.huawei.hms.site.api.model.Site
import com.huawei.hms.location.LocationResult
import com.huawei.hms.knowmyboard.dtse.activity.intefaces.ItemClickListener
import android.view.WindowManager
import android.view.LayoutInflater
import android.view.ViewGroup
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.widget.SearchView
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.huawei.hms.knowmyboard.dtse.R
import com.huawei.hms.knowmyboard.dtse.activity.util.Constants
import com.huawei.hms.knowmyboard.dtse.databinding.FragmentSearchBinding
import com.huawei.hms.site.api.SearchServiceFactory
import com.huawei.hms.site.api.model.TextSearchRequest
import com.huawei.hms.site.api.model.Coordinate
import com.huawei.hms.site.api.SearchResultListener
import com.huawei.hms.site.api.model.TextSearchResponse
import com.huawei.hms.site.api.model.SearchStatus
import com.huawei.hms.site.api.model.NearbySearchRequest
import com.huawei.hms.site.api.model.HwLocationType
import com.huawei.hms.site.api.model.NearbySearchResponse
import java.io.UnsupportedEncodingException
import java.lang.Exception
import java.net.URLEncoder
import java.util.ArrayList

class SearchFragment : Fragment() {
    var binding: FragmentSearchBinding? = null
    var loginViewModel: LoginViewModel? = null

    //View view;
    var navController: NavController? = null
    private var searchService: SearchService? = null
    var adapter: SitesAdapter? = null
    var siteArrayList = ArrayList&amp;lt;Site&amp;gt;()
    var locationResult: LocationResult? = null
   /* var siteClicklistener = ItemClickListener { vh, site, pos -&amp;gt;
        requireActivity().window.setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
        )
        loginViewModel!!.setSiteSelected(site)
        navController!!.navigate(R.id.loginFragment)
    }*/

    var siteClicklistener = object : ItemClickListener{
        override fun onItemClicked(vh: RecyclerView.ViewHolder?, item: Site?, pos: Int) {
            requireActivity().window.setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
            )
            loginViewModel!!.setSiteSelected(item!!)
            navController!!.navigate(R.id.loginFragment)
        }

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        requireActivity().window.setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
        )
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_search, container, false)
        loginViewModel = ViewModelProvider(requireActivity()).get(
            LoginViewModel::class.java
        )
        val searchView = binding!!.edSearch
        val recyclerView = binding!!.suggestionRv
        navController = findNavController(requireActivity(), R.id.nav_host_fragment)
        searchView.isFocusable = true
        searchView.onActionViewExpanded()
        adapter = SitesAdapter(siteArrayList, context, siteClicklistener)
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(context)
        recyclerView.setHasFixedSize(true)
        loginViewModel!!.locationResult.observeForever { locationResult1 -&amp;gt;
            locationResult = locationResult1
        }
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String): Boolean {
                return false
            }

            override fun onQueryTextChange(newText: String): Boolean {
                if (newText.length &amp;gt; 4) {
                    nearByPlacesSearch(newText)
                }
                return false
            }
        })
        return binding!!.root
    }

    fun keywordSearch(search: String?) {
        try {
            val key = URLEncoder.encode(Constants.API_KEY, "UTF-8")
            // Instantiate the SearchService object.
            searchService = SearchServiceFactory.create(context, key)
            // Create a request body.
            val request = TextSearchRequest()
            request.query = search
            if (locationResult != null) {
                val location = Coordinate(
                    locationResult!!.lastHWLocation.latitude,
                    locationResult!!.lastHWLocation.longitude
                )
                request.location = location
            }
            request.radius = 1000
            //request.setHwPoiType(HwLocationType.HOTEL_MOTEL);
            request.countryCode = "IN"
            request.language = "en"
            request.pageIndex = 1
            request.pageSize = 5
            request.isChildren = false
            // request.setCountries(Arrays.asList("en", "fr", "cn", "de", "ko","in"));
            // Create a search result listener.
            val resultListener: SearchResultListener&amp;lt;TextSearchResponse?&amp;gt; =
                object : SearchResultListener&amp;lt;TextSearchResponse?&amp;gt; {
                    // Return search results upon a successful search.
                    override fun onSearchResult(results: TextSearchResponse?) {
                        if (results == null || results.totalCount &amp;lt;= 0) {
                            return
                        }
                        val sites = results.sites
                        if (sites == null || sites.size == 0) {
                            return
                        }
                        siteArrayList.clear()
                        for (site in sites) {
                            siteArrayList.add(site)
                        }
                        siteArrayList.addAll(sites)
                        adapter!!.notifyDataSetChanged()
                    }

                    // Return the result code and description upon a search exception.
                    override fun onSearchError(status: SearchStatus) {
                        Log.i("TAG", "Error : " + status.errorCode + " " + status.errorMessage)
                    }
                }
            // Call the keyword search API.
            searchService!!.textSearch(request, resultListener)
        } catch (e: UnsupportedEncodingException) {
            e.printStackTrace()
        }
    }

    fun nearByPlacesSearch(newText: String?) {
        try {
            val key = URLEncoder.encode(Constants.API_KEY, "UTF-8")
            // Instantiate the SearchService object.
            searchService = SearchServiceFactory.create(context, key)
            // Create a request body.
            val request = NearbySearchRequest()
            if (locationResult != null) {
                val location = Coordinate(
                    locationResult!!.lastHWLocation.latitude,
                    locationResult!!.lastHWLocation.longitude
                )
                request.location = location
            }
            request.query = newText
            request.radius = 1000
            request.hwPoiType = HwLocationType.ADDRESS
            request.language = "en"
            request.pageIndex = 1
            request.pageSize = 5
            request.strictBounds = false
            // Create a search result listener.
            val resultListener: SearchResultListener&amp;lt;NearbySearchResponse?&amp;gt; =
                object : SearchResultListener&amp;lt;NearbySearchResponse?&amp;gt; {
                    // Return search results upon a successful search.
                    override fun onSearchResult(results: NearbySearchResponse?) {
                        if (results == null || results.totalCount &amp;lt;= 0) {
                            return
                        }
                        val sites = results.sites
                        if (sites == null || sites.size == 0) {
                            return
                        }
                        siteArrayList.clear()
                        for (site in sites) {
                            siteArrayList.add(site)
                        }
                        siteArrayList.addAll(sites)
                        adapter!!.notifyDataSetChanged()
                    }

                    // Return the result code and description upon a search exception.
                    override fun onSearchError(status: SearchStatus) {
                        Log.i("TAG", "Error : " + status.errorCode + " " + status.errorMessage)
                    }
                }
            // Call the nearby place search API.
            searchService!!.nearbySearch(request, resultListener)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RequestLocationData.kt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
package com.huawei.hms.knowmyboard.dtse.activity.util

import android.Manifest
import com.huawei.hms.knowmyboard.dtse.activity.viewmodel.LoginViewModel
import android.app.Activity
import android.content.Context
import android.os.Build
import android.content.pm.PackageManager
import android.os.Looper
import android.location.Geocoder
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.fragment.app.FragmentActivity
import com.huawei.hms.location.*
import java.io.IOException
import java.lang.StringBuilder
import java.util.*

class RequestLocationData(
    context: Context?,
    activity: FragmentActivity?,
    loginViewModel: LoginViewModel?
) {
    private var settingsClient: SettingsClient? = null
    private var isLocationSettingSuccess = 0
    private var myLocationRequest: LocationRequest? = null

    // Define a fusedLocationProviderClient object.
    private var fusedLocationProviderClient: FusedLocationProviderClient? = null
    private var myLocationCallback: LocationCallback? = null
    var context: Context? = null
    var activity: Activity? = null
    private var locationResult: LocationResult? = null
    var loginViewModel: LoginViewModel? = null
    fun initFusionLocationProviderClint() {
        // Instantiate the fusedLocationProviderClient object.
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(activity)
        this.settingsClient = LocationServices.getSettingsClient(activity)
    }

    fun checkDeviceLocationSettings() {
        val builder = LocationSettingsRequest.Builder()
        myLocationRequest = LocationRequest()
        builder.addLocationRequest(myLocationRequest)
        val locationSettingsRequest = builder.build()
        // Check the device location settings.
        settingsClient!!.checkLocationSettings(locationSettingsRequest) // Define the listener for success in calling the API for checking device location settings.
            .addOnSuccessListener { locationSettingsResponse: LocationSettingsResponse -&amp;gt;
                val locationSettingsStates = locationSettingsResponse.locationSettingsStates
                val stringBuilder = StringBuilder()
                // Check whether the location function is enabled.
                stringBuilder.append(",\nisLocationUsable=")
                    .append(locationSettingsStates.isLocationUsable)
                // Check whether HMS Core (APK) is available.
                stringBuilder.append(",\nisHMSLocationUsable=")
                    .append(locationSettingsStates.isHMSLocationUsable)
                Log.i(TAG, "checkLocationSetting onComplete:$stringBuilder")
                // Set the location type.
                myLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
                // Set the number of location updates to 1.
                myLocationRequest!!.numUpdates = 1
                isLocationSettingSuccess = 1
            } // Define callback for failure in checking the device location settings.
            .addOnFailureListener { e -&amp;gt; Log.i(TAG, "checkLocationSetting onFailure:" + e.message) }
    }

    @RequiresApi(Build.VERSION_CODES.S)
    fun checkPermission() {
        // Dynamically apply for required permissions if the API level is 28 or lower.
        if (Build.VERSION.SDK_INT &amp;lt;= Build.VERSION_CODES.P) {
            Log.i(TAG, "android sdk &amp;lt;= 28 Q")
            if (ActivityCompat.checkSelfPermission(
                    context!!,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED
                &amp;amp;&amp;amp; ActivityCompat.checkSelfPermission(
                    context!!,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                val strings = arrayOf(
                    Manifest.permission.CAMERA,
                    Manifest.permission.MANAGE_MEDIA,
                    Manifest.permission.MEDIA_CONTENT_CONTROL,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                )
                ActivityCompat.requestPermissions(activity!!, strings, 1)
            }
        } else {
            // Dynamically apply for the android.permission.ACCESS_BACKGROUND_LOCATION permission in addition to the preceding permissions if the API level is higher than 28.
            if (ActivityCompat.checkSelfPermission(
                    activity!!,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED &amp;amp;&amp;amp; ActivityCompat.checkSelfPermission(
                    context!!,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED &amp;amp;&amp;amp; ActivityCompat.checkSelfPermission(
                    context!!,
                    "android.permission.ACCESS_BACKGROUND_LOCATION"
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                val strings = arrayOf(
                    Manifest.permission.CAMERA,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.MEDIA_CONTENT_CONTROL,
                    Manifest.permission.MANAGE_MEDIA,
                    "android.permission.ACCESS_BACKGROUND_LOCATION"
                )
                ActivityCompat.requestPermissions(activity!!, strings, 2)
            }
        }
    }

    fun refreshLocation(): LocationResult? {
        Log.d(TAG, "Refreshing location")
        if (isLocationSettingSuccess == 1) {
            myLocationCallback = object : LocationCallback() {
                private var locationResult: LocationResult? = null
                override fun onLocationResult(locationResult: LocationResult) {
                    if (locationResult != null) {
                        // Gson gson = new Gson();
                        //Log.d(TAG, " Location data :" + locationResult.getLastLocation().getLatitude() + " : " + locationResult.getLastLocation().getLongitude());
                        //Log.d(TAG, " Location data :" + gson.toJson(locationResult.getLastHWLocation()));
                        //Log.d(TAG, " Location data :" + locationResult.getLastHWLocation().getCountryName());
                        Log.d(TAG, " Location data :" + locationResult.lastHWLocation.latitude)
                        Log.d(TAG, " Location data :" + locationResult.lastHWLocation.longitude)
                        // binding.textDetected.setText("Latitude " + locationResult.getLastHWLocation().getLatitude() + " Longitude " + locationResult.getLastHWLocation().getLongitude());
                        //getGeoCoderValues(locationResult.getLastHWLocation().getLatitude(),locationResult.getLastHWLocation().getLongitude());
                        this.locationResult = locationResult
                        loginViewModel!!.setLocationResult(locationResult)
                    }
                }
            }
            fusedLocationProviderClient!!.requestLocationUpdates(
                myLocationRequest,
                myLocationCallback,
                Looper.getMainLooper()
            )
        } else {
            Log.d(TAG, "Failed to get location settings")
        }
        return locationResult
    }

    fun disableLocationData() {
        fusedLocationProviderClient!!.disableBackgroundLocation()
        fusedLocationProviderClient!!.removeLocationUpdates(myLocationCallback)
    }

    private fun getGeoCoderValues(latitude: Double, longitude: Double) {
        getAddress(context, latitude, longitude)
        /*  Geocoder geocoder;
        List&amp;lt;Address&amp;gt; addresses;
        Locale locale = new Locale("en", "IN");
        geocoder = new Geocoder(getContext(), locale);

        try {
            addresses = geocoder.getFromLocation(latitude, longitude, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
            Gson gson=new Gson();
            Log.d(TAG,"Geo coder :"+gson.toJson(addresses));
        String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
        String city = addresses.get(0).getLocality();
        String state = addresses.get(0).getAdminArea();
        String country = addresses.get(0).getCountryName();
        String postalCode = addresses.get(0).getPostalCode();
        String knownName = addresses.get(0).getFeatureName();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"Error while fetching Geo coder :"+e.getMessage());
        }*/
        /* Locale locale = new Locale("en", "IN");
        GeocoderService geocoderService =
                LocationServices.getGeocoderService(getActivity().getBaseContext(), locale);
        // Request reverse geocoding.
        GetFromLocationRequest getFromLocationRequest = new GetFromLocationRequest(latitude, longitude, 5);
        // Initiate reverse geocoding.
        geocoderService.getFromLocation(getFromLocationRequest)
                .addOnSuccessListener(hwLocation -&amp;gt; {
                    Gson gson=new Gson();
                    Log.d(TAG,"Geo coder :"+gson.toJson(hwLocation));

                })
                .addOnFailureListener(e -&amp;gt; {

                    Log.e(TAG,"Error while fetching Geo coder :"+e.getMessage());
                });*/
    }

    companion object {
        var TAG = "TAG"
        fun getAddress(context: Context?, LATITUDE: Double, LONGITUDE: Double) {
            //Set Address
            try {
                val geocoder = Geocoder(context, Locale.getDefault())
                val addresses = geocoder.getFromLocation(LATITUDE, LONGITUDE, 1)
                if (addresses != null &amp;amp;&amp;amp; addresses.size &amp;gt; 0) {
                    val address =
                        addresses[0].getAddressLine(0) // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
                    val city = addresses[0].locality
                    val state = addresses[0].adminArea
                    val country = addresses[0].countryName
                    val postalCode = addresses[0].postalCode
                    val knownName = addresses[0].featureName // Only if available else return NULL
                    Log.d(TAG, "getAddress:  address$address")
                    Log.d(TAG, "getAddress:  city$city")
                    Log.d(TAG, "getAddress:  state$state")
                    Log.d(TAG, "getAddress:  postalCode$postalCode")
                    Log.d(TAG, "getAddress:  knownName$knownName")
                }
            } catch (e: IOException) {
                e.printStackTrace()
                Log.e(TAG, "Error while fetching Geo coder :" + e.message)
            }
        }
    }

    init {
        this@RequestLocationData.context = context
        this@RequestLocationData.activity = activity
        this@RequestLocationData.loginViewModel = loginViewModel
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;navigation_graph.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/navigation_graph"
    app:startDestination="@id/loginFragment"&amp;gt;
    &amp;lt;fragment
        android:id="@+id/loginFragment"
        android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.LoginFragment"
        android:label="LoginFragment"/&amp;gt;
    &amp;lt;fragment
        android:id="@+id/mainFragment"
        android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.MainFragment"
        android:label="MainFragment"/&amp;gt;
    &amp;lt;fragment
        android:id="@+id/searchFragment"
        android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.SearchFragment"
        android:label="fragment_search"
        tools:layout="@layout/fragment_search" /&amp;gt;
&amp;lt;/navigation&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;bottom_navigation_menu.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"&amp;gt;
    &amp;lt;item
        android:id="@+id/searchFragment"
        android:icon="@android:drawable/ic_menu_search"
        android:title="@string/search" /&amp;gt;
    &amp;lt;item
        android:id="@+id/loginFragment"
        android:icon="@android:drawable/ic_menu_agenda"
        android:title="Home" /&amp;gt;
    &amp;lt;item
        android:id="@+id/mainFragment"
        app:showAsAction="always"
        android:icon="@android:drawable/ic_menu_gallery"
        android:title="Gallery" /&amp;gt;
&amp;lt;/menu&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B3CbuLJX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndjhqaawy00svlqfxiui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B3CbuLJX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndjhqaawy00svlqfxiui.png" alt="Image description" width="320" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tricks and Tips
&lt;/h2&gt;

&lt;p&gt;Makes sure that agconnect-services.json file added.&lt;br&gt;
Make sure required dependencies are added&lt;br&gt;
Make sure that service is enabled in AGC&lt;br&gt;
Enable data binding in gradle.build file&lt;br&gt;
Make sure bottom navigation id's should be same as fragment id's in navigation graph&lt;br&gt;
Conclusion&lt;/p&gt;

&lt;p&gt;In this article, we have learnt how to integrate Huawei Site Kit, Map kit, Location kit in Android application KnowMyBoard. Hoping that the Map kit capabilities are helpful to you as well, like this sample, you can make use of Site kit as per your requirement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;Map Kit – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101590716045317017"&gt;Training video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Site Kit – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101582996919057158"&gt;Training video&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>huawei</category>
      <category>hms</category>
    </item>
    <item>
      <title>Client Server Messaging App Using Socket in Android With Huawei Account Kit for Easy Login</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Fri, 29 Jul 2022 12:35:06 +0000</pubDate>
      <link>https://dev.to/hmscommunity/client-server-messaging-app-using-socket-in-android-with-huawei-account-kit-for-easy-login-3am6</link>
      <guid>https://dev.to/hmscommunity/client-server-messaging-app-using-socket-in-android-with-huawei-account-kit-for-easy-login-3am6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we will learn how to integrate Huawei Account kit in Android application. Account Kit provides you with simple, secure, and quick sign-in and authorization functions. Instead of entering accounts and passwords and waiting for authentication, users can just tap the button to quickly and securely sign in to your app with their HUAWEI IDs. It helps app user seamless login functionality to the app with large user base.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supported Devices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2HT6nU0d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0g4ju5jrhiyzd6zwmzt.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2HT6nU0d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0g4ju5jrhiyzd6zwmzt.PNG" alt="Image description" width="878" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need to install Android Studio IDE and I assume that you have prior knowledge of Android application development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardware Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A computer (desktop or laptop) running Windows 10.&lt;br&gt;
Android phone (with the USB cable), which is used for debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java JDK 1.8 or later.&lt;/li&gt;
&lt;li&gt;Android Studio software installed.&lt;/li&gt;
&lt;li&gt;HMS Core (APK) 4.X or later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integration steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Huawei developer account and complete identity verification in Huawei developer website, refer to register Huawei ID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; Create project in AppGallery Connect&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3.&lt;/strong&gt; Adding HMS Core SDK&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's start coding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;How do I call sign in method?&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void signInWithHuaweiID() {

AccountAuthParams authParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setAuthorizationCode().createParams();
service = AccountAuthManager.getService(ClientActivity.this, authParams);
startActivityForResult(service.getSignInIntent(), 1212);

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I get sign in result?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
// Process the authorization result to obtain the authorization code from AuthAccount.
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == 1212) {
Task&amp;lt;AuthAccount&amp;gt; authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
if (authAccountTask.isSuccessful()) {

// The sign-in is successful, and the user's ID information and authorization code are obtained.
AuthAccount authAccount = authAccountTask.getResult();
Log.i("TAG", "serverAuthCode:" + authAccount.getAuthorizationCode());
userName = authAccount.getDisplayName();
makeConnect();

} else {
// The sign-in failed.
Log.e("TAG", "sign in failed:" + ((ApiException) authAccountTask.getException()).getStatusCode());

}
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I start server?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wManager = (WifiManager) getSystemService(WIFI_SERVICE);

serverIP = Formatter.formatIpAddress(wManager.getConnectionInfo().getIpAddress());

ip_txt.setText(serverIP);

class ServerThread implements Runnable {

@Override

public void run() {

try {

while (true) {

serverSocket = new ServerSocket(POST_NUMBER);

socket = serverSocket.accept();

output = new PrintWriter(socket.getOutputStream());

input = new BufferedReader(new InputStreamReader(socket.getInputStream()));

Log.d("TAG", " here ");

runOnUiThread(new Runnable() {

@Override

public void run() {

tv_status.setText("Waiting for conn at " + POST_NUMBER);

}

});

handler.post(new Runnable() {

@Override

public void run() {

tv_status.setText("Connected");

}

});

}

} catch (Exception e) {

e.printStackTrace();

}

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I send message using socket?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SendMessage implements Runnable {

private String message;

SendMessage(String message) {

this.message = message;

}

@Override

public void run() {

output.write(message+"\r");

output.flush();

runOnUiThread(new Runnable() {

@Override

public void run() {

tv_chat.append("\n New Message: " + message);

ed_message.setText("");

}

});

Thread.interrupted();

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;How do I receive message using socket?&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private class ReadMessage implements Runnable {

@Override

public void run() {

while (true) {

try {

// Log.d("TAG","Server: Listening for message");

if(input!=null){

final String message = input.readLine();

if (message != null) {

handler.post(new Runnable() {

@Override

public void run() {

tv_chat.append("\n" + message );

}

});

}

}

} catch (IOException e) {

// Log.e("TAG","Error while receiving message");

e.printStackTrace();

}

}

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Close the Socket and other connections&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override

protected void onPause() {

super.onPause();

if (socket != null) {

try {

output.close();

input.close();

socket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I revoke auth permission?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(service!=null){

// service indicates the AccountAuthService instance generated using the getService method during the sign-in authorization.

service.cancelAuthorization().addOnCompleteListener(new OnCompleteListener&amp;lt;Void&amp;gt;() {
@Override
public void onComplete(Task&amp;lt;Void&amp;gt; task) {

if (task.isSuccessful()) {
// Processing after a successful authorization cancellation.
Log.i("TAG", "onSuccess: ");
} else {
// Handle the exception.
Exception exception = task.getException();
if (exception instanceof ApiException){
int statusCode = ((ApiException) exception).getStatusCode();
Log.i("TAG", "onFailure: " + statusCode);
}
}
}
});
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LF3YzlTS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/adfjtr777ev3khmux7qk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LF3YzlTS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/adfjtr777ev3khmux7qk.gif" alt="Image description" width="320" height="694"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dhVT2WGD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgcdtn92ulsbehze3h7r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dhVT2WGD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgcdtn92ulsbehze3h7r.gif" alt="Image description" width="320" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tricks and Tips&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Makes sure that agconnect-services.json file added.&lt;br&gt;
Make sure required dependencies are added&lt;br&gt;
Make sure that service is enabled in AGC&lt;br&gt;
Add required permissions &lt;br&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we have learnt how to integrate Huawei Account kit in Client Server messaging using Socket in Android application. You can check the desired result in the result section. Hoping Huawei Analytics kit capabilities are helpful to you as well, like this sample, you can make use of Huawei kits as per your requirement.&lt;/p&gt;

&lt;p&gt;Thank you so much for reading. I hope this article helps you to understand the integration of Huawei Account kit in Android application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/introduction-0000001050048870"&gt;Huawei Account Kit&lt;/a&gt; – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101584324766101108"&gt;Training video&lt;/a&gt;&lt;br&gt;
&lt;a href="https://forums.developer.huawei.com/forumPortal/en/topic/0202944747417630152"&gt;Checkout in forum&lt;/a&gt;&lt;/p&gt;

</description>
      <category>huaweiaccountkit</category>
      <category>huaweideveloper</category>
      <category>hmscore</category>
      <category>java</category>
    </item>
    <item>
      <title>Search the hospitals using Huawei Map Kit, Site Kit and Location Kit in Patient Tracking Android app (Kotlin) – Part 5</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Mon, 25 Jul 2022 07:17:00 +0000</pubDate>
      <link>https://dev.to/hmscommunity/search-the-hospitals-using-huawei-map-kit-site-kit-and-location-kit-in-patient-tracking-android-app-kotlin-part-5-5320</link>
      <guid>https://dev.to/hmscommunity/search-the-hospitals-using-huawei-map-kit-site-kit-and-location-kit-in-patient-tracking-android-app-kotlin-part-5-5320</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YbdfkDM_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgj4381s4anrkuhg76r3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YbdfkDM_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgj4381s4anrkuhg76r3.png" alt="Image description" width="602" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
In this article, we can learn how to search the hospitals located by source and destination address with HMS Core Kits such as &lt;strong&gt;Map&lt;/strong&gt;, &lt;strong&gt;Site&lt;/strong&gt;, and &lt;strong&gt;Location Kits&lt;/strong&gt;. Map kit is to display maps, it covers map data of more than &lt;strong&gt;200&lt;/strong&gt; countries and regions for searching any location address. &lt;strong&gt;Location kit&lt;/strong&gt; provides to get the current location and location updates, and it provides flexible location based services &lt;strong&gt;globally&lt;/strong&gt; to the users. &lt;strong&gt;Site kit&lt;/strong&gt; provides with convenient and secure access to diverse, place-related services to users.&lt;/p&gt;

&lt;p&gt;So, I will provide a series of articles on this Patient Tracking App, in upcoming articles I will integrate other Huawei Kits.&lt;/p&gt;

&lt;p&gt;If you are new to this application, follow my previous articles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forums.developer.huawei.com/forumPortal/en/topic/0201902220661040078"&gt;https://forums.developer.huawei.com/forumPortal/en/topic/0201902220661040078&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forums.developer.huawei.com/forumPortal/en/topic/0201908355251870119"&gt;https://forums.developer.huawei.com/forumPortal/en/topic/0201908355251870119&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forums.developer.huawei.com/forumPortal/en/topic/0202914346246890032"&gt;https://forums.developer.huawei.com/forumPortal/en/topic/0202914346246890032&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forums.developer.huawei.com/forumPortal/en/topic/0202920411340450018"&gt;https://forums.developer.huawei.com/forumPortal/en/topic/0202920411340450018&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Map Kit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Map Kit covers map data of more than 200 countries and regions, and supports over &lt;strong&gt;70&lt;/strong&gt; languages. User can easily integrate map-based functions into your apps using SDK. It optimizes and enriches the map detail display capability. Map Kit supports gestures including &lt;strong&gt;zoom&lt;/strong&gt;, &lt;strong&gt;rotation&lt;/strong&gt;, &lt;strong&gt;moving&lt;/strong&gt; and tilt gestures to ensure smooth interaction experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Location Kit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Location Kit combines the &lt;strong&gt;GPS&lt;/strong&gt;, &lt;strong&gt;Wi-Fi&lt;/strong&gt; and &lt;strong&gt;base station&lt;/strong&gt; location functionalities in your app to build up global positioning capabilities, allows to provide flexible location-based services targeted at users around globally. Currently, it provides three main capabilities: &lt;strong&gt;fused location&lt;/strong&gt;, &lt;strong&gt;activity&lt;/strong&gt; &lt;strong&gt;identification&lt;/strong&gt; and &lt;strong&gt;geo-fence&lt;/strong&gt;. You can call one or more of these capabilities as required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Site Kit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Site Kit&lt;/strong&gt; provides the place related services for apps. It provides that to search places with keywords, find nearby place, place suggestion for user search, and find the place details using the unique id.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Any operating system (MacOS, Linux and Windows).&lt;/li&gt;
&lt;li&gt;Must have a Huawei phone with HMS 4.0.0.300 or later.&lt;/li&gt;
&lt;li&gt;Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.&lt;/li&gt;
&lt;li&gt;Minimum API Level 24 is required.&lt;/li&gt;
&lt;li&gt;Required EMUI 9.0.0 and later version devices.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to integrate HMS Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a &lt;a href="https://developer.huawei.com/consumer/en/doc/start/registration-and-verification-0000001053628148"&gt;Huawei ID&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a project in android studio, &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#1"&gt;refer Creating an Android Studio Project&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To generate &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt;. On right-upper corner of android project click &lt;strong&gt;Gradle&lt;/strong&gt;, choose &lt;strong&gt;Project Name &amp;gt; Tasks &amp;gt; android&lt;/strong&gt;, and then click &lt;strong&gt;signingReport&lt;/strong&gt;, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ndKOxL9F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/apc0rtsm9cfkkb6ihcxa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ndKOxL9F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/apc0rtsm9cfkkb6ihcxa.png" alt="Image description" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Project Name depends on the user created name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#0"&gt;Create an App in AppGallery Connect&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;strong&gt;agconnect-services.json&lt;/strong&gt; file from &lt;strong&gt;App information&lt;/strong&gt;, copy and paste in android &lt;strong&gt;Project&lt;/strong&gt; under &lt;strong&gt;app&lt;/strong&gt; directory, as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7HYYoQbi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpfnvdmr8i95nwrm48pu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7HYYoQbi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpfnvdmr8i95nwrm48pu.png" alt="Image description" width="464" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter &lt;strong&gt;SHA-256 certificate fingerprint&lt;/strong&gt; and click &lt;strong&gt;Save&lt;/strong&gt; button, as follows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CnVuX9Rs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qrb2ugdz4dngw6qysm04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CnVuX9Rs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qrb2ugdz4dngw6qysm04.png" alt="Image description" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Manage API&lt;/strong&gt;s tab and enable &lt;strong&gt;Map Kit&lt;/strong&gt;, &lt;strong&gt;Site Kit&lt;/strong&gt; and &lt;strong&gt;Location Kit&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the below maven URL in &lt;strong&gt;build.gradle(Project)&lt;/strong&gt; file under the repositories of &lt;strong&gt;buildscript&lt;/strong&gt;, &lt;strong&gt;dependencies&lt;/strong&gt; and &lt;strong&gt;allprojects&lt;/strong&gt;, refer &lt;a href="https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#6"&gt;Add Configuration&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add the below plugin and dependencies in &lt;strong&gt;build.gradle(Module)&lt;/strong&gt; file.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apply plugin: 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Huawei Map
implementation 'com.huawei.hms:maps:6.2.0.301'
// Huawei Site Kit
implementation 'com.huawei.hms:site:6.2.0.301'
// Huawei Location Kit
implementation 'com.huawei.hms:location:6.2.0.300'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now Sync the gradle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the required permission to the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name="android.permission.INTERNET"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/&amp;gt;
&amp;lt;uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/&amp;gt;
// To obtain the coarse longitude and latitude of a user with Wi-Fi network or base station.
&amp;lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/&amp;gt;
// To receive location information from satellites through the GPS chip.
&amp;lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Let us move to development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have created a project on Android studio with empty activity let us start coding.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;SearchActivity.kt&lt;/strong&gt; we can find the business logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SearchActivity : AppCompatActivity(), OnMapReadyCallback, View.OnClickListener {

    private lateinit var hmap: HuaweiMap
    private lateinit var mMapView: MapView
    private var mMarker: Marker? = null
    private var mCircle: Circle? = null
    private var isSourceAddressField: Boolean = false
    private var pickupLat: Double = 0.0
    private var pickupLng: Double = 0.0
    private var dropLat: Double = 0.0
    private var dropLng: Double = 0.0
    private var searchService: SearchService? = null
    private var searchIntent: SearchIntent? = null
    private lateinit var mFusedLocationProviderClient: FusedLocationProviderClient
    companion object {
        private const val TAG = "MapViewDemoActivity"
        private const val MAPVIEW_BUNDLE_KEY = "MapViewBundleKey"
        private val LAT_LNG = LatLng(12.9716, 77.5946)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_search)

        // Get mapView
        mMapView = findViewById(R.id.mapView)
        var mapViewBundle: Bundle? = null
        if (savedInstanceState != null) {
            mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY)
        }
        // Add "Your API key" in api_key field value
        MapsInitializer.setApiKey("DAEDADRgIFzXbAJpOqImvjRAGRkmm3wGTux0O6JBiaddIPMNTJ4SawIN8ZHWu28dtc1f1H3Cqzh0LC1cgYIvBnl1edWVuWkjciH4NA==")
        mMapView.onCreate(mapViewBundle)
        // get map by async method
        mMapView.getMapAsync(this)
        //Checking permission
        checkLocationPermission()
        // Location service
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        //Initialize Search Service
        getLocationFromService()
        //Initialize OnClickListener
        customCurrentLocation.setOnClickListener(this)
        pickUpLocation.setOnClickListener(this)
        dropLocation.setOnClickListener(this)

    }

    override fun onMapReady(map: HuaweiMap?) {
        Log.d(TAG, "onMapReady: ")
        // Get the HuaweiMap instance in this call back method.
        hmap = map!!
        // Move camera by CameraPosition param, latlag and zoom params can set here.
        val build = CameraPosition.Builder().target(LatLng(13.0827, 80.2707)).zoom(10f).build()
        val cameraUpdate = CameraUpdateFactory.newCameraPosition(build)
        hmap.animateCamera(cameraUpdate)
        hmap.setMaxZoomPreference(10f)
        hmap.setMinZoomPreference(1f)
        // Marker can be add by HuaweiMap
        mMarker = hmap.addMarker(
            MarkerOptions().position(LAT_LNG)
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.garden_icon))
                .clusterable(true))
        mMarker?.showInfoWindow()
        // circle can be add by HuaweiMap
        mCircle = hmap.addCircle(
            CircleOptions().center(LatLng(28.7041, 77.1025)).radius(45000.0).fillColor(Color.GREEN))
        mCircle?.fillColor = Color.TRANSPARENT

    }

    override fun onStart() {
        super.onStart()
        mMapView.onStart()
    }
    override fun onStop() {
        super.onStop()
        mMapView.onStop()
    }
    override fun onDestroy() {
        super.onDestroy()
        mMapView.onDestroy()
    }
    override fun onPause() {
        mMapView.onPause()
        super.onPause()
    }
    override fun onResume() {
        super.onResume()
        mMapView.onResume()
    }

    private fun checkLocationPermission() {
        // check location permission
        if (Build.VERSION.SDK_INT &amp;lt;= Build.VERSION_CODES.P) {
            if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                &amp;amp;&amp;amp; ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                val strings = arrayOf(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION)
                ActivityCompat.requestPermissions(this, strings, 1)
            }
        }  else {
            if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                &amp;amp;&amp;amp; ActivityCompat.checkSelfPermission(this,ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                &amp;amp;&amp;amp; ActivityCompat.checkSelfPermission(this,"android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
                val strings = arrayOf(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION,
                    "android.permission.ACCESS_BACKGROUND_LOCATION")
                ActivityCompat.requestPermissions(this, strings, 2)
            }
        }
    }

    private fun getLocationFromService() {
        // Add your API Key in encode
        searchService = SearchServiceFactory.create(this,
            URLEncoder.encode("Add your api_key"))
    }

    override fun onClick(v: View?) {
        val id = v?.id
        if (id == R.id.pickUpLocation) {
            locationBox(100)
        } else if (id == R.id.dropLocation) {
            locationBox(101)
        } else if (id == R.id.customCurrentLocation) {
            getLastLocation()
        }
    }

    private fun locationBox(requestcode: Int) {
        searchIntent = SearchIntent()
        searchIntent!!.setApiKey(URLEncoder.encode("DAEDADRgIFzXbAJpOqImvjRAGRkmm3wGTux0O6JBiaddIPMNTJ4SawIN8ZHWu28dtc1f1H3Cqzh0LC1cgYIvBnl1edWVuWkjciH4NA==", "utf-8"))
        val intent = searchIntent!!.getIntent(this)
        startActivityForResult(intent, requestcode)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, @Nullable data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 100) {
            if (SearchIntent.isSuccess(resultCode)) {
                isSourceAddressField = true
                val site: Site = searchIntent!!.getSiteFromIntent(data)
                pickUpLocation.setText(site.name)
                querySuggestion()
            }
        }
        if (requestCode == 101) {
            if (SearchIntent.isSuccess(resultCode)) {
                isSourceAddressField = false
                val site: Site = searchIntent!!.getSiteFromIntent(data)
                dropLocation.setText(site.name)
                querySuggestion()
            }
        }
    }

    private fun querySuggestion() {
        val request = QuerySuggestionRequest()
        val query: String?
        if (isSourceAddressField) {
            query = pickUpLocation?.text.toString()
        }else{
            query = dropLocation?.text.toString()
        }
        if (!TextUtils.isEmpty(query)) {
            request.query = query
        }
        searchService?.querySuggestion(
            request,
            searchResultListener as SearchResultListener&amp;lt;QuerySuggestionResponse&amp;gt;?
        )
    }

    private var searchResultListener =
        object : SearchResultListener&amp;lt;QuerySuggestionResponse&amp;gt; {
            override fun onSearchResult(results: QuerySuggestionResponse?) {
                val stringBuilder = StringBuilder()
                results?.let {
                    val sites = results.sites
                    if (sites != null &amp;amp;&amp;amp; sites.size &amp;gt; 0) {
                        for (site in sites) {
                            val location = site.location
                            if (isSourceAddressField) {
                                pickupLat = location.lat
                                pickupLng = location.lng
                                moveCamera(LatLng(pickupLat, pickupLng))
                            } else {
                                dropLat = location.lat
                                dropLng = location.lng
                                moveCamera(LatLng(dropLat, dropLng))
                            }
                            break
                        }
                    } else {
                        stringBuilder.append("0 results")
                    }
                }
            }
            override fun onSearchError(status: SearchStatus) {
            }
        }

    private fun getLastLocation() {
        try {
            val lastLocation = mFusedLocationProviderClient.lastLocation
            lastLocation.addOnSuccessListener(OnSuccessListener { location -&amp;gt;
                if (location == null) {
                    return@OnSuccessListener
                }
                moveCamera(LatLng(location.latitude, location.longitude))
                return@OnSuccessListener
            }).addOnFailureListener { e -&amp;gt;
            }
        } catch (e: Exception) {
        }
    }

    private fun moveCamera(latLng: LatLng) {
        hmap!!.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f))
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;activity_search.xml&lt;/strong&gt; we can create the UI screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".search.SearchActivity"&amp;gt;

    &amp;lt;com.huawei.hms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"&amp;gt;
    &amp;lt;/com.huawei.hms.maps.MapView&amp;gt;

    &amp;lt;RelativeLayout
        android:id="@+id/startpoint"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="42dp"
        android:layout_marginTop="42dp"
        android:layout_marginRight="62dp"
        android:background="@drawable/blue_border_rounded_cornwe"&amp;gt;

        &amp;lt;EditText
            android:id="@+id/pickUpLocation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/start_loc"
            android:background="@android:color/transparent"
            android:hint="Choose starting point "
            android:maxLines="1"
            android:paddingLeft="17dp"
            android:paddingTop="15dp"
            android:paddingBottom="15dp"
            android:textSize="13sp"&amp;gt;
        &amp;lt;/EditText&amp;gt;
        &amp;lt;ImageView
            android:id="@+id/start_loc"
            android:layout_width="20dp"
            android:layout_height="17dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="17dp"
            android:src="@drawable/start_icon" /&amp;gt;
    &amp;lt;/RelativeLayout&amp;gt;

    &amp;lt;RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="42dp"
        android:layout_marginTop="23dp"
        android:layout_marginRight="62dp"
        android:layout_below="@+id/startpoint"
        android:background="@drawable/blue_border_rounded_cornwe"&amp;gt;
        &amp;lt;EditText
            android:id="@+id/dropLocation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/dest_loc"
            android:background="@android:color/transparent"
            android:hint="Password"
            android:maxLines="1"
            android:paddingLeft="17dp"
            android:paddingTop="15dp"
            android:paddingBottom="15dp"
            android:textSize="13sp"&amp;gt;
        &amp;lt;/EditText&amp;gt;
        &amp;lt;ImageView
            android:id="@+id/dest_loc"
            android:layout_width="20dp"
            android:layout_height="17dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="17dp"
            android:src="@drawable/dest_icon" /&amp;gt;
    &amp;lt;/RelativeLayout&amp;gt;

    &amp;lt;ImageView
        android:id="@+id/customCurrentLocation"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginRight="10dp"
        android:baselineAlignBottom="true"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:src="@drawable/location_icon"/&amp;gt;

&amp;lt;/RelativeLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nj1LCMq1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9nifb36bi0cn86qfwy91.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nj1LCMq1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9nifb36bi0cn86qfwy91.gif" alt="Image description" width="216" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips and Tricks&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure you are already registered as Huawei developer.&lt;/li&gt;
&lt;li&gt;Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.&lt;/li&gt;
&lt;li&gt;Make sure you have added the agconnect-services.json file to app folder.&lt;/li&gt;
&lt;li&gt;Make sure you have added SHA-256 fingerprint without fail.&lt;/li&gt;
&lt;li&gt;Make sure all the dependencies are added properly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we can learn how to search the hospitals located by source and destination address with HMS Core Kits such as Map, Site, and Location Kits. Map kit is to display maps, it covers map data of more than 200 countries and regions for searching any location address. Location kit provides to get the current location and location updates, and it provides flexible location based services globally to the users. Site kit provides with convenient and secure access to diverse, place-related services to users.&lt;/p&gt;

&lt;p&gt;I hope you have read this article. If you found it is helpful, please provide likes and comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Map Kit&lt;/strong&gt; - &lt;a href="https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-brief-introduction-0000001061991343"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Map Kit&lt;/strong&gt; – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101590716045317017"&gt;Training Video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Location Kit&lt;/strong&gt; – &lt;a href="https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/introduction-0000001050706106"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Location Kit&lt;/strong&gt; – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101590715236705018"&gt;Training Video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-introduction-0000001050158571"&gt;Site Kit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>map</category>
      <category>location</category>
      <category>site</category>
    </item>
    <item>
      <title>Adding Custom Events in Android App KnowMyBoard Using Huawei Analytics Kit</title>
      <dc:creator>HMS Community</dc:creator>
      <pubDate>Fri, 22 Jul 2022 14:51:39 +0000</pubDate>
      <link>https://dev.to/hmscommunity/adding-custom-events-in-android-app-knowmyboard-using-huawei-analytics-kit-1f28</link>
      <guid>https://dev.to/hmscommunity/adding-custom-events-in-android-app-knowmyboard-using-huawei-analytics-kit-1f28</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we will learn how to integrate Huawei Analytics kit in Android application KnowMyBoard. Account Kit provides seamless login functionality to the app with large user base.&lt;/p&gt;

&lt;p&gt;Huawei Analytics kit provides very easy and convenient way to add custom events, custom events can be used to meet personalized analysis requirements that cannot be met by automatically collected events or predefined events. Analytics Kit allows you to customize events and extend event parameters, or add personalized parameters for predefined events.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supported Devices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VgFbeMXP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvfetctwfc2hu0y69ipt.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VgFbeMXP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvfetctwfc2hu0y69ipt.PNG" alt="Image description" width="827" height="598"&gt;&lt;/a&gt;Restrictions&lt;/p&gt;

&lt;p&gt;Number of events: A maximum of 500 events are supported.&lt;br&gt;
Number of event parameters: You can register a maximum of 25 parameters for each event, and a maximum of 500 event parameters for each project.&lt;br&gt;
&lt;strong&gt;Development Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need to install Android Studio IDE and I assume that you have prior knowledge of Android application development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardware Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A computer (desktop or laptop) running Windows 10.&lt;br&gt;
Android phone (with the USB cable), which is used for debugging.&lt;br&gt;
&lt;strong&gt;Software Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Java JDK 1.8 or later.&lt;br&gt;
Android Studio software or Visual Studio or Code installed.&lt;br&gt;
HMS Core (APK) 4.X or later&lt;br&gt;
Integration steps&lt;/p&gt;

&lt;p&gt;Step 1. Huawei developer account and complete identity verification in Huawei developer website, refer to register Huawei ID.&lt;/p&gt;

&lt;p&gt;Step 2. Create project in AppGallery Connect&lt;/p&gt;

&lt;p&gt;Step 3. Adding HMS Core SDK&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's start coding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Add Custom Event in AGC?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Login to AppGallery Connect Console, select projects and choose your project and navigate to Events&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UffE9PvU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e933g8ihcv44vnm8gpd0.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UffE9PvU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e933g8ihcv44vnm8gpd0.PNG" alt="Image description" width="880" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U6eHoB0k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzh021npn56ess0w22nj.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U6eHoB0k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzh021npn56ess0w22nj.PNG" alt="Image description" width="880" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H-hYT9OY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/syfqzii0ps0dst5jboqt.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H-hYT9OY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/syfqzii0ps0dst5jboqt.PNG" alt="Image description" width="741" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to initialize Analytics Kit?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MyApplication extends Application {
    public static Activity myactivity;
    static HiAnalyticsInstance instanceAnalytics;
    @Override
    public void onCreate() {
        super.onCreate();
        MLApplication.initialize(this);
        //initialize Analytics Kit
        instanceAnalytics = HiAnalytics.getInstance(this);
        MLApplication.getInstance().setApiKey(Constants.API_KEY);
        MapsInitializer.setApiKey(Constants.API_KEY);
    }
   public static HiAnalyticsInstance getAnalyticsInstance(){
      return  instanceAnalytics;
    }
    public static void setActivity(Activity activity) {
        myactivity= activity;
    }
    public static Activity getActivity() {
        return myactivity;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to send Custom Events?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void sendEvent(String eventName,String eventType) {
Bundle bundle = new Bundle();
bundle.putString(eventType,eventType);
bundle.putString( "event_time", getTime());
MyApplication.getAnalyticsInstance().onEvent(eventName, bundle);

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VweUwP2M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hzjkuh6x3zdww3z6xdi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VweUwP2M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hzjkuh6x3zdww3z6xdi.gif" alt="Image description" width="221" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PdPFoWI2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gag5oxmxgpj6zkndzcss.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PdPFoWI2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gag5oxmxgpj6zkndzcss.PNG" alt="Image description" width="880" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--adeRfTdI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bxr8pqjt3erk23d7tsyv.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--adeRfTdI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bxr8pqjt3erk23d7tsyv.PNG" alt="Image description" width="880" height="225"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Tricks and Tips&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Makes sure that agconnect-services.json file added.&lt;br&gt;
Make sure required dependencies are added&lt;br&gt;
Make sure that service is enabled in AGC&lt;br&gt;
Enable data binding in gradle.build file&lt;br&gt;
Enable debug mode to see events details in get App debugging hit this command in terminal &lt;/p&gt;

&lt;p&gt;adb shell setprop debug.huawei.hms.analytics.app pkg_name&lt;br&gt;
Copy codeCopy code&lt;br&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, we have learnt how to integrate Huawei Analytics kit in Android application KnowMyBoard. You can check the desired result in the result section. You can also go through previous article part-5 here. Hoping Huawei Analytics kit capabilities are helpful to you as well, like this sample, you can make use as per your requirement.&lt;/p&gt;

&lt;p&gt;Thank you so much for reading. I hope this article helps you to understand the integration of Huawei Analytics kit in Android application KnowMyBoard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/introduction-0000001050745149"&gt;Huawei Analytics Kit&lt;/a&gt; – &lt;a href="https://developer.huawei.com/consumer/en/training/course/video/101582991973534154"&gt;Training video&lt;/a&gt;&lt;/p&gt;

</description>
      <category>huaweianalyticskit</category>
      <category>huaweidevelopers</category>
      <category>hmscore</category>
    </item>
  </channel>
</rss>
