总览
通过无缝数据库结构,在保证数据的可用性、一致性、安全性外,云数据库能够实现数据在客户端和云端之间的无缝同步。云函数提供serverless环境,AppGallery Connect的其他服务为云函数提供事件源。监听事件源可以触发相关函数。
您将建立什么
在本次codelab中,您将建立一个示例项目用于体验云数据库和云函数。云数据库中数据发生变化时,云函数HTTP触发器触发函数发送通知。流程如下:
商品下单。
获取商品订单信息。
商品送货时,发送通知。
您将学会什么
在本次codelab中,您将学习:
如何在AppGallery Connect中创建项目和新建应用。
如何集成云数据库和云函数。
如何使用云函数并且使用HTTP触发器发送通知。
硬件需求
一台笔记本或台式电脑。
一部装有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或以上
必备知识
安卓应用开发基础知识
集成前,需要完成以下准备工作:
在进行准备前,请先注册开发者帐号。
在AppGallery Connect中创建项目和应用。
创建Android Studio项目。
生成签名证书。
生成签名证书指纹。
在AppGallery Connect中将签名指纹添加到应用中。
添加必要配置。
配置项目签名。
同步项目。
详情请参见HUAWEI HMS Core集成准备。
添加您应用的AppGallery Connect配置文件
登录AppGallery Connect,点击“我的项目”,在项目列表中找到并点击您的项目。
在“项目设置”页面选择“常规”页签。
在“项目”区域下点击“数据处理位置”后的“启用”。
点击“应用”区域的“agconnect-services.json”下载配置文件。
把agconnect-services.json文件拷贝到项目的应用级根目录下。
添加编译依赖
打开应用级的“build.gradle”文件。
在dependencies中添加如下编译依赖。
dependencies { //添加云函数和云数据库依赖。implementation 'com.huawei.agconnect:agconnect-cloud-database:{version}'implementation 'com.huawei.agconnect:agconnect-function-ktx:{version}'
}
注意:
将{version}替换为云数据库的最新版本号,例如,com.huawei.agconnect:agconnect-cloud-database:1.5.3.300。最新的版本号请参见SDK版本更新说明。
将{version}替换为云函数的最新版本号,例如,com.huawei.agconnect:agconnect-function-ktx 1.7.1.300。最新的版本号请参见SDK版本更新说明
在build.gradle文件中,设置Java源代码的兼容性模式。
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
在应用级build.gradle文件中设置minSdkVersion。
android {... defaultConfig {... minSdkVersion 26 ... }...
}
检查是否已添加AppGallery Connect插件。如没有,在应用级build.gradle文件中添加该插件。
apply plugin: 'com.huawei.agconnect'
配置混淆脚本
编译APK前需要配置混淆脚本,避免混淆HMS Core SDK。如果出现混淆,HMS Core SDK可能无法正常工作。
Android Studio开发环境里的混淆脚本是“proguard-rules.pro”。
加入排除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.**{*;}
需要在handler.js文件中写入发送通知的函数。
在AppGallery Connect中创建函数。
输入函数名,上传创建的handler.js文件,并保存设置。
函数创建完成后,添加HTTP触发器。
初始化云数据库。
override suspend fun initialize(): Result {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 = trueval task = mCloudDB.openCloudDBZone2(mConfig, true)task.addOnSuccessListener {cloudDBZone = ithandler?.complete(Result.Success(Unit))}.addOnFailureListener {handler?.complete(Result.Error(it.message))}}
产品列表由云数据库提供。用户在产品列表中选择某个产品时,售卖该产品的商店的经纬度发送到快递员的界面上。
override suspend fun getOrders(): List {val result = CompletableDeferred>()cloudDBZone?.let { dbZone ->dbZone.executeQuery(CloudDBZoneQuery.where(Order::class.java),CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_DEFAULT).addOnCompleteListener{if(it.isSuccessful) {val cursor = it.result.snapshotObjectsval orders = mutableListOf()while(cursor.hasNext()) {orders.add(cursor.next())}result.complete(orders)}else {throw it.exception}}}?: run {throw Exception("Cloud DB not initialized.")}return result.await()}
查看权限。
在Android Studio页面,选择File > Sync Project with Gradle Files同步项目。
根据用户位置信息,通过Directions API创建路径。
private fun getLastLocation() {val mLocationRequest = LocationRequest()mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACYmLocationRequest.numUpdates = 1fusedLocationProviderClient.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
当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)}
在地图上,用折现添加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)}
}
您可以指定云函数的HTTP触发器给用户发送消息,通知他们快递员已到达。用户可以在地图上查看订单位置。
private suspend fun starSimulation(pathPoints: List?) {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 = HashMap()parameterMap["deviceToken"] = tokenAGConnectFunction.getInstance().wrap("courier-tracking-notification-\$latest") .call(parameterMap)}findNavController().popBackStack()}
祝贺您,您已经成功完成本codelab并学到了:
如何继承云数据库和云函数。
如何通过HTTP触发器发送通知。
云数据库开发指南
云函数开发指南
云函数HTTP触发器
Push Kit开发指南
Map Kit开发指南
Location Kit开发指南
Directions API开发指南
您可以下载源代码。
欲了解更多更全技术文章,欢迎访问https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh