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配置文件
登录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.**{*;}
5、设计UI
6、集成云函数
需要在handler.js文件中写入发送通知的函数。
在AppGallery Connect中创建函数。
输入函数名,上传创建的handler.js文件,并保存设置。
函数创建完成后,添加HTTP触发器。
7、初始化云数据库
初始化云数据库。
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)) } }
产品列表由云数据库提供。用户在产品列表中选择某个产品时,售卖该产品的商店的经纬度发送到快递员的界面上。
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() }
8、使用Location和Directions API
查看权限。
<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" />
在Android Studio页面,选择File > Sync Project with Gradle Files同步项目。
根据用户位置信息,通过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
当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) } }
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()}
10、恭喜您
祝贺您,您已经成功完成本codelab并学到了:
如何继承云数据库和云函数。
如何通过HTTP触发器发送通知。
11、参考文件
您可以下载源代码。
欲了解更多更全技术文章,欢迎访问https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh