1、介绍

总览

通过无缝数据库结构,在保证数据的可用性、一致性、安全性外,云数据库能够实现数据在客户端和云端之间的无缝同步。云函数提供serverless环境,AppGallery Connect的其他服务为云函数提供事件源。监听事件源可以触发相关函数。

您将建立什么

在本次codelab中,您将建立一个示例项目用于体验云数据库和云函数。云数据库中数据发生变化时,云函数HTTP触发器触发函数发送通知。流程如下:

  • 商品下单。

  • 获取商品订单信息。

  • 商品送货时,发送通知。

您将学会什么

在本次codelab中,您将学习:

  • 如何在AppGallery Connect中创建项目和新建应用。

  • 如何集成云数据库和云函数。

  • 如何使用云函数并且使用HTTP触发器发送通知。

2、您需要什么

硬件需求

  • 一台笔记本或台式电脑。

  • 一部装有EMUI 8.0或以上版本的华为手机,运行HMS Core (APK) 5.0.1.301或以上版本;或一部装有安卓7.0或以上版本的非华为手机,运行HMS Core (APK) 5.0.1.301或以上版本。该手机用于demo的运行和调测。

软件需求

  • JDK版本:1.8或以上

  • Android Studio版本:3.X或以上

  • SDK平台版本:24或以上

  • targetSdkVersion:29

  • compileSdkVersion:29

  • Gradle版本:4.6或以上

必备知识

安卓应用开发基础知识

3、能力接入准备

集成前,需要完成以下准备工作:

在进行准备前,请先注册开发者帐号

  • 在AppGallery Connect中创建项目和应用。

  • 创建Android Studio项目。

  • 生成签名证书。

  • 生成签名证书指纹。

  • 在AppGallery Connect中将签名指纹添加到应用中。

  • 添加必要配置。

  • 配置项目签名。

  • 同步项目。

详情请参见HUAWEI HMS Core集成准备

4、集成HMS Core SDK

添加您应用的AppGallery Connect配置文件

  1. 登录AppGallery Connect,点击“我的项目”,在项目列表中找到并点击您的项目。

  2. 在“项目设置”页面选择“常规”页签。

  3. 在“项目”区域下点击“数据处理位置”后的“启用”。

    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

  4. 点击“应用”区域的“agconnect-services.json”下载配置文件。

    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

  5. 把agconnect-services.json文件拷贝到项目的应用级根目录下。

    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

添加编译依赖

  1. 打开应用级的“build.gradle”文件。

  2. 在dependencies中添加如下编译依赖。

    dependencies { 
        //添加云函数和云数据库依赖。
        implementation 'com.huawei.agconnect:agconnect-cloud-database:{version}'
        implementation 'com.huawei.agconnect:agconnect-function-ktx:{version}'
    }
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

    注意:

    将{version}替换为云数据库的最新版本号,例如,com.huawei.agconnect:agconnect-cloud-database:1.5.3.300。最新的版本号请参见SDK版本更新说明

    将{version}替换为云函数的最新版本号,例如,com.huawei.agconnect:agconnect-function-ktx 1.7.1.300。最新的版本号请参见SDK版本更新说明

  3. 在build.gradle文件中,设置Java源代码的兼容性模式。

    compileOptions { 
    sourceCompatibility = 1.8 
    targetCompatibility = 1.8
    }
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP
  4. 在应用级build.gradle文件中设置minSdkVersion。

    android {
     ... 
       defaultConfig {
          ... 
       minSdkVersion 26 
          ... 
      }
       ... 
    }
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP
  5. 检查是否已添加AppGallery Connect插件。如没有,在应用级build.gradle文件中添加该插件。

    apply plugin: 'com.huawei.agconnect'
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

配置混淆脚本

编译APK前需要配置混淆脚本,避免混淆HMS Core SDK。如果出现混淆,HMS Core SDK可能无法正常工作。

Android Studio开发环境里的混淆脚本是“proguard-rules.pro”。

  1. 加入排除HMS SDK的混淆配置。

    -ignorewarnings 
    -keepattributes *Annotation* 
    -keepattributes Exceptions 
    -keepattributes InnerClasses 
    -keepattributes Signature 
    -keepattributes SourceFile,LineNumberTable 
    -keep class com.huawei.hianalytics.**{*;} 
    -keep class com.huawei.updatesdk.**{*;} 
    -keep class com.huawei.hms.**{*;}
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

5、设计UI

一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

6、集成云函数

  1. 需要在handler.js文件中写入发送通知的函数。

  2. 在AppGallery Connect中创建函数。

  3. 输入函数名,上传创建的handler.js文件,并保存设置。

  4. 函数创建完成后,添加HTTP触发器。

7、初始化云数据库

  1. 初始化云数据库。

    override suspend fun initialize(): Result<Unit> {
            handler = CompletableDeferred()
            AGConnectCloudDB.initialize(context)
            initializeCloudDB()
            initializeZone()
            handler?.let { return it.await() }
                ?: run { return Result.Error() }
        }
    
        private fun initializeCloudDB() {
            val instance = AGConnectInstance.buildInstance(
                AGConnectOptionsBuilder().setRoutePolicy(
                    AGCRoutePolicy.GERMANY
                ).build(context)
            )
            mCloudDB = AGConnectCloudDB.getInstance(instance, AGConnectAuth.getInstance())
            mCloudDB.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo())
        }
    
    
    
    private fun initializeZone() {
            val mConfig = CloudDBZoneConfig(
                "CourierDbZone", 
                CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE,
                CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC
            )
            mConfig.persistenceEnabled = true
            val task = mCloudDB.openCloudDBZone2(mConfig, true)
            task.addOnSuccessListener {
                cloudDBZone = it
                handler?.complete(Result.Success(Unit))
            }.addOnFailureListener {
                handler?.complete(Result.Error(it.message))
            }
        }
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP
  2. 产品列表由云数据库提供。用户在产品列表中选择某个产品时,售卖该产品的商店的经纬度发送到快递员的界面上。

    override suspend fun getOrders(): List<Order> {
            val result = CompletableDeferred<List<Order>>()
            cloudDBZone?.let { dbZone ->
                dbZone.executeQuery(
                    CloudDBZoneQuery.where(Order::class.java),
                    CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_DEFAULT
                ).addOnCompleteListener{
                    if(it.isSuccessful) {
                        val cursor = it.result.snapshotObjects
                        val orders = mutableListOf<Order>()
                        while(cursor.hasNext()) {
                            orders.add(cursor.next())
                        }
                        result.complete(orders)
                    }else {
                        throw it.exception
                    }
                }
            }?: run {
                throw Exception("Cloud DB not initialized.")
            }
            return result.await()
        }
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

8、使用Location和Directions API

  1. 查看权限。

    <uses-permission android:name="android.permission.INTERNET"/> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP
  2. 在Android Studio页面,选择File > Sync Project with Gradle Files同步项目。

  3. 根据用户位置信息,通过Directions API创建路径。

    private fun getLastLocation() {
            val mLocationRequest = LocationRequest()
            mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            mLocationRequest.numUpdates = 1
            fusedLocationProviderClient.requestLocationUpdates(
                mLocationRequest,
                mLocationCallback,
                Looper.getMainLooper()
            )
    }
    private val mLocationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                courierTrackingViewModel.createRoute(
                    args.storeLocation,
                    locationResult.lastLocation,
                    DirectionType.DRIVING
                )
            }
        }
    @POST("{type}")
        suspend fun getDirections(
            @Path(value = "type",encoded = true) type : String,
            @Body directionRequest: DirectionsRequest,
            @Query("key") api_key: String,
        ): DirectionsNetwork
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP
  4. 当Directions API返回成功结果后,标记用户和商店位置。

    private fun addMarker(latLng: LatLng, title: String, icon: Int): Marker? {
            val options = MarkerOptions()
                .position(latLng)
                .title(title)
                .icon(BitmapDescriptorFactory.fromResource(icon))
            return hMap?.addMarker(options)
        }
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP
  5. 在地图上,用折现添加Directions API返回的经纬度信息。

    private fun addPolylines(route: Route) {
            route.pathPoints?.let { pathPoints ->
                val options = PolylineOptions()
                pathPoints.forEach { latLng ->
                    options.add(latLng)
                }
                options.color(
                    ContextCompat.getColor(
                        requireContext(), R.color.yellow_700
                    )
                )
                options.width(5f)
                hMap?.addPolyline(options)
            }
    }
    一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

9、HTTP触发器场景

您可以指定云函数的HTTP触发器给用户发送消息,通知他们快递员已到达。用户可以在地图上查看订单位置。

private suspend fun starSimulation(pathPoints: List<LatLng>?) {
        var marker: Marker?
        pathPoints?.let { paths ->
            paths.forEach { latLng ->
                marker = addMarker(latLng,"Courier",R.drawable.scooter_icon_128)
                animateCamera(latLng)
                delay(100)
                marker?.remove()
            }
        }
        sendNotification()
    }
    private fun sendNotification() {
        val pushToken = activity?.getSharedPreferences(
            "device_token", Context.MODE_PRIVATE
        )?.getString("device_token",null)
        pushToken?.let { token ->
            val parameterMap: HashMap<String, String> = HashMap()
            parameterMap["deviceToken"] = token
            AGConnectFunction.getInstance()
                .wrap("courier-tracking-notification-\$latest")  
                .call(parameterMap)}
         findNavController().popBackStack()}
一个帖子教你实现 商品下单、获取商品订单信息、商品送货时发送通知 一体化功能-LMLPHP

10、恭喜您

祝贺您,您已经成功完成本codelab并学到了:

  • 如何继承云数据库和云函数。

  • 如何通过HTTP触发器发送通知。

11、参考文件

您可以下载源代码

欲了解更多更全技术文章,欢迎访问https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh

12-13 10:11