简介

华为情景感知服务(Huawei Awareness Kit)为您提供获取用户当前时空、活动状态、耳机状态、信标等情景感知组合能力。调用这些能力,您的App可以通过更高效的方式,洞悉用户当前所处的情景,为用户提供更加智慧和贴心的体验。
您可以调用Capture API或Barrier API:

您将建立什么

在这个Codelab中,你将创建一个调用华为情景感知服务的应用。

您将会学到什么

硬件要求

EMUI 7.0及以上的华为手机或者预装HMS Core的Android 7.0及以上的非华为手机(部分能力仅支持华为手机),用于调试、运行情景感知服务App。手机要求参见《支持的设备》。

软件要求

集成HUAWEI HMS Core能力,需要完成以下准备工作:

具体操作,请按照《HUAWEI HMS Core集成准备》中详细说明来完成。

针对Android Studio开发环境,华为提供了Maven仓集成方式的HMS Core SDK包。在开始开发前,您需要将HMS Core SDK集成到您的Android Studio开发环境中。

在Android Studio开发环境中添加当前应用的AppGallery Connect配置文件。

  1. 登录 AppGallery Connect网站,单击"我的项目"。
  2. 在项目列表中找到您的项目,在项目中点击需要集成HMS Core SDK的应用。
  3. 在"项目设置 > 常规"页面的"应用"区域,点击"agconnect-services.json"下载配置文件。
  4. 将agconnect-services.json文件拷贝到应用级根目录下。

配置HMS Core SDK的Maven仓地址。

  1. 打开Android Studio项目级build.gradle文件。
  2. 添加HUAWEI agcp插件以及Maven代码库。
    • 在"allprojects > repositories"中配置HMS Core SDK的Maven仓地址。
    • 在"buildscript > repositories"中配置HMS Core SDK的Maven仓地址。
    • 如果App中添加了"agconnect-services.json"文件则需要在"buildscript > dependencies"中增加agcp配置。
      buildscript { repositories { google() jcenter() maven {url 'https://developer.huawei.com/repo/'} } dependencies { ... classpath 'com.huawei.agconnect:agcp:1.4.2.300' } } allprojects { repositories { google() jcenter() maven {url 'https://developer.huawei.com/repo/'} } }

添加编译依赖。

  1. 打开应用级的"build.gradle"文件。
  2. 在build.gradle文件中增加如下配置。
    compileOptions { sourceCompatibility = 1.8 targetCompatibility = 1.8 }
  3. 在dependencies中添加如下编译依赖,{version}需要替换为实际的SDK版本号,如:implementation ‘com.huawei.hms:awareness:1.0.8.300'。
    dependencies{ implementation 'com.huawei.hms:awareness:{version}' }
  4. 在文件头apply plugin: ‘com.android.application'下一行添加如下配置。
    apply plugin: 'com.huawei.agconnect'
  5. 在完成以上的配置后,点击工具栏中的gradle同步图标,完成"build.gradle"文件的同步,将相关依赖下载到本地。

配置混淆脚本

您编译APK前需要配置混淆配置文件,避免混淆HMS Core SDK导致功能异常。

  1. 在应用级根目录下打开混淆配置文件"proguard-rules.pro",加入排除HMS Core SDK的混淆配置脚本。
    Awareness SDK 1.0.7.300及之后的版本无需加入排除HMS Core 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.**{*;}
  2. 如果您使用了AndResGuard,需要在应用级的"build.gradle"文件中加入AndResGuard允许清单。
    "R.string.hms*", "R.string.connect_server_fail_prompt_toast", "R.string.getting_message_fail_prompt_toast", "R.string.no_available_network_prompt_toast", "R.string.third_app_*", "R.string.upsdk_*", "R.layout.hms*", "R.layout.upsdk_*", "R.drawable.upsdk*", "R.color.upsdk*", "R.dimen.upsdk*", "R.style.upsdk*", "R.string.agc*"

在Manifest指定权限

在调用情景感知能力时,开发者需要先在Manifest中指定相应的权限。使用不同情景感知能力需指定不同的权限,具体所需权限请参阅《开发指南》。例如,使用耳机状态感知能力,需要开启设备的蓝牙功能,需要在Manifest中申请蓝牙权限:

<!-- 蓝牙权限(Android 12以下) --> <uses-permission android:name="android.permission.BLUETOOTH" /> <!-- 蓝牙权限(Android 12及以上) --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

导入接口类

在调用不同的情景感知能力时,开发者需要导入相应的能力接口类。不同能力所需的类的路径和类名不同,具体请参阅《API参考》。例如,使用耳机状态感知能力,除需要导入情景感知服务的公共能力类外,还需要导入耳机状态相关的类。

import com.huawei.hmf.tasks.OnFailureListener; import com.huawei.hmf.tasks.OnSuccessListener; import com.huawei.hms.kit.awareness.Awareness; // 导入耳机快照相关类 import com.huawei.hms.kit.awareness.capture.HeadsetStatusResponse; import com.huawei.hms.kit.awareness.status.HeadsetStatus; // 导入耳机围栏相关类 import com.huawei.hms.kit.awareness.barrier.AwarenessBarrier; import com.huawei.hms.kit.awareness.barrier.BarrierStatus; import com.huawei.hms.kit.awareness.barrier.HeadsetBarrier; import com.huawei.hms.kit.awareness.barrier.BarrierUpdateRequest;

Capture能力开发

  1. 获取Awareness Kit的"Capture Client"。
  2. 通过"Capture Client"调用耳机状态查询能力接口查询情景状态。
  3. 监听情景感知服务结果返回,进行应用的业务处理。
    Java示例代码:
    Awareness.getCaptureClient(this).getHeadsetStatus() .addOnSuccessListener(new OnSuccessListener<HeadsetStatusResponse>() { @Override public void onSuccess(HeadsetStatusResponse headsetStatusResponse) { HeadsetStatus headsetStatus = headsetStatusResponse.getHeadsetStatus(); int status = headsetStatus.getStatus(); String stateStr = "Headsets are " + (status == HeadsetStatus.CONNECTED ? "connected" : "disconnected"); Log.i(TAG, stateStr); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.e(TAG, "get Headsets Capture failed", e); } });

    Kotlin示例代码:

    Awareness.getCaptureClient(this).headsetStatus .addOnSuccessListener { headsetStatusResponse: HeadsetStatusResponse -> val headsetStatus = headsetStatusResponse.headsetStatus val status = headsetStatus.status val stateStr = "Headsets are " +if (status == HeadsetStatus.CONNECTED) "connected" else "disconnected" Log.i(TAG, stateStr) } .addOnFailureListener { e: Exception? -> Log.e(TAG, "get Headsets Capture failed", e) }

Barrier能力开发

以下以开发耳机"Connecting"的Barrier为例(耳机插入后触发Barrier)。

  1. 定义Barrier。
    Java示例代码:
    AwarenessBarrier headsetBarrier = HeadsetBarrier.connecting();

    Kotlin示例代码:

    var headsetBarrier : AwarenessBarrier = HeadsetBarrier.connecting()
  2. 定义Barrier状态改变时触发的"PendingIntent",本示例中为发送一个广播,同时新建一个广播接收器用来接收这个广播。
    Java示例代码:
    final String BARRIER_RECEIVER_ACTION = getApplication().getPackageName() + "HEADSET_BARRIER_RECEIVER_ACTION"; Intent intent = new Intent(BARRIER_RECEIVER_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); HeadsetBarrierReceiver barrierReceiver = new HeadsetBarrierReceiver(); registerReceiver(barrierReceiver, new IntentFilter(BARRIER_RECEIVER_ACTION));

    Kotlin示例代码:

    val BARRIER_RECEIVER_ACTION = application.packageName + "HEADSET_BARRIER_RECEIVER_ACTION" val intent = Intent(BARRIER_RECEIVER_ACTION) val pendingIntent = PendingIntent.getBroadcast(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT) val barrierReceiver = HeadsetBarrierReceiver() registerReceiver(barrierReceiver, IntentFilter(BARRIER_RECEIVER_ACTION))
  3. 定义Barrier对应的标签Label,然后添加Barrier。
    Java示例代码:
    String headsetBarrierLabel = "headset connecting barrier"; BarrierUpdateRequest.Builder builder = new BarrierUpdateRequest.Builder(); BarrierUpdateRequest request = builder.addBarrier(headsetBarrierLabel, headsetBarrier,pendingIntent).build(); Awareness.getBarrierClient(context).updateBarriers(request) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Toast.makeText(getApplicationContext(), "add barrier success", Toast.LENGTH_SHORT).show(); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Toast.makeText(getApplicationContext(), "add barrier failed", Toast.LENGTH_SHORT).show(); Log.e(TAG, "add barrier failed", e); } });

    Kotlin示例代码:

    val headsetBarrierLabel = "headset connecting barrier" val builder = BarrierUpdateRequest.Builder() val request = builder.addBarrier(headsetBarrierLabel, headsetBarrier, pendingIntent).build() Awareness.getBarrierClient(context).updateBarriers(request) .addOnSuccessListener { Toast.makeText(applicationContext, "add barrier success", Toast.LENGTH_SHORT).show() } .addOnFailureListener { e -> Toast.makeText(applicationContext, "add barrier failed", Toast.LENGTH_SHORT).show() Log.e(TAG, "add barrier failed", e) }
  4. 定义广播接收器,用于监听Barrier事件,收到事件后进行应用的业务处理。
    Java示例代码:
    class HeadsetBarrierReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { BarrierStatus barrierStatus = BarrierStatus.extract(intent); String label = barrierStatus.getBarrierLabel(); switch(barrierStatus.getPresentStatus()) { case BarrierStatus.TRUE: Log.i(TAG, label + " status:true"); break; case BarrierStatus.FALSE: Log.i(TAG, label + " status:false"); break; case BarrierStatus.UNKNOWN: Log.i(TAG, label + " status:unknown"); break; } } }

    Kotlin示例代码:

    internal inner class HeadsetBarrierReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val barrierStatus = BarrierStatus.extract(intent) val label = barrierStatus.barrierLabel when (barrierStatus.presentStatus) { BarrierStatus.TRUE -> Log.i(TAG, "$label status:true") BarrierStatus.FALSE -> Log.i(TAG, "$label status:false") BarrierStatus.UNKNOWN -> Log.i(TAG, "$label status:unknown") } } }

当您集成SDK后,可以通过日志和实际情况的对比,来判断调用是否成功。例如,当您的耳机处于为未连接状态,且点击"get Headset Status"按钮后日志显示为"Headsets are disconnected",说明调用Capture成功。

干得好,你已经成功完成了Codelab并学到了:

如需了解更多与华为Awareness Kit相关的信息,请关注我们的官方网站。开发过程中如果遇见问题,请参考我们的常见问题解答

您可以阅读下面链接,了解更多相关的信息。

相关文档
本Codelab中所用Demo源码下载地址如下:

源码下载

Code copied