目录

活动识别开发

概述

如果您的应用需要获取设备的运动状态,例如:步行、跑步、骑自行车等。可以通过以下两种方式获取设备的运动状态:

约束条件

您需要确保您的设备已经下载并安装了HMS Core(APK),并将Location Kit的SDK集成到您的项目中。有关详细信息,请参见开发准备。以下仅为代码片段,详情请参见示例代码。

活动识别支持的手机内存(模拟机的支持情况不在如下范围内):3G以上。

如果您想提高活动识别的成功率,建议插SIM卡并打开5G/4G/3G/2G网络开关,活动识别的IN_VEHICLE、ON_BICYCLE模式使用到了cell(基站)信息,与移动数据网络的开启有一定的关系。目前海外版本手机活动识别不支持骑自行车和乘车。

指定应用权限

android.permission.ACTIVITY_RECOGNITION和com.huawei.hms.permission.ACTIVITY_RECOGNITION活动识别权限属于危险权限,使用时需要动态申请。

注册静态广播

示例代码中活动识别服务的活动状态更新信息需要广播接收,因此需要在“AndroidManifest.xml”文件中注册广播接收器。

<!--注册活动识别服务广播接收器-->
<receiver
    android:name=".location.fusedlocation.LocationBroadcastReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="com.huawei.hmssample.location.LocationBroadcastReceiver.ACTION_PROCESS_LOCATION" />
    </intent-filter>
</receiver>

初始化活动识别客户端

请在主线程中声明ActivityIdentificationService类对象,传入Context或Activity类型参数。
“Java”
private PendingIntent pendingIntent;
private ActivityIdentificationService activityIdentificationService;
// 获取activityIdentificationService实例
activityIdentificationService = ActivityIdentification.getService(this);
// 获取PendingIntent对象
pendingIntent = getPendingIntent();
“Kotlin”
private var pendingIntent: PendingIntent? = null
private var activityIdentificationService: ActivityIdentificationService? = null
// 获取activityIdentificationService实例
activityIdentificationService = ActivityIdentification.getService(this)
// 获取PendingIntent对象
pendingIntent = getPendingIntent()

识别活动状态

首先需要您调用活动识别状态更新接口,用于检测用户当前的状态是步行、骑自行车或静止等。

  1. 新建参数PendingIntent。
    “Java”
    // 获取自定义静态广播类LocationBroadcastReceiver关联的PendingIntent
    private PendingIntent getPendingIntent() {
        Intent intent = new Intent(this, LocationBroadcastReceiver.class);
        intent.setAction(LocationBroadcastReceiver.ACTION_PROCESS_LOCATION);
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
            return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        } else {
            // 针对android12及以上设备需要主动配置pendingIntent的可变性,默认配置PendingIntent.FLAG_MUTABLE
            // 如果compileSdkVersion为30及以下,可将PendingIntent.FLAG_MUTABLE用 1<<25 替换
            // buildToolsVersion为31及以上才可使用PendingIntent.FLAG_MUTABLE
            return PendingIntent.getBroadcast(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
        }
    }
    “Kotlin”
    // 获取自定义静态广播类LocationBroadcastReceiver关联的PendingIntent
    private fun getPendingIntent(): PendingIntent? {
        val intent = Intent(this, LocationBroadcastReceiver::class.java)
        intent.action = LocationBroadcastReceiver.ACTION_PROCESS_LOCATION
        return if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
            PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        } else {
            // 针对android12及以上设备需要主动配置pendingIntent的可变性,默认配置PendingIntent.FLAG_MUTABLE
            // 如果compileSdkVersion为30及以下,可将PendingIntent.FLAG_MUTABLE用 1<<25 替换
            // buildToolsVersion为31及以上才可使用PendingIntent.FLAG_MUTABLE
            PendingIntent.getBroadcast(
                this,
                0,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
            )
        }
    }
  2. 发起活动识别更新请求。
    通过调用createActivityIdentificationUpdates(long detectionIntervalMillis, PendingIntent callbackIntent)方法发起活动识别更新请求并监听结果回调。
    “Java”
    // 发起活动识别请求
    activityIdentificationService.createActivityIdentificationUpdates(5000, pendingIntent)
        // 请求成功监听回调
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                // TODO:发起活动识别成功处理
            }
        })
        // 请求失败监听回调
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                // TODO:发起活动识别失败处理
            }
        });
    “Kotlin”
    // 发起活动识别请求
    activityIdentificationService!!.createActivityIdentificationUpdates(
        5000,
        pendingIntent
    )
        // 请求成功监听回调
        .addOnSuccessListener {
            // TODO:发起活动识别成功处理
        }
        // 请求失败监听回调
        .addOnFailureListener { e ->
            // TODO:发起活动识别失败处理
        }

    参数说明

    参数

    类型

    描述

    备注

    detectionIntervalMillis

    long

    活动检测更新间隔,单位:毫秒,默认值为30000毫秒;

    值设置越大,活动检测越少,值设置越小,活动检测越频繁

    callbackIntent

    PendingIntent

    每个活动识别请求关联的pendingIntent,按时间间隔将活动识别结果通过广播通知用户

    构造PendingIntent时需设置Class、Action,不能构造空Intent。

  3. 获取活动识别结果
    通过广播接收器获取活动识别结果。
    “Java”
    // 活动识别广播接收者
    public class LocationBroadcastReceiver extends BroadcastReceiver {
        // 活动识别服务广播action
        public static final String ACTION_PROCESS_LOCATION = "com.huawei.hms.location.ACTION_PROCESS_LOCATION";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
                final String action = intent.getAction();
                if (ACTION_PROCESS_LOCATION.equals(action)) {
                    // 获取ActivityIdentificationResponse,从response中提取检测到的活动状态列表
                    ActivityIdentificationResponse activityIdentificationResponse = 
                        ActivityIdentificationResponse.getDataFromIntent(intent);
                    List<ActivityIdentificationData> list = 
                        activityIdentificationResponse.getActivityIdentificationDatas();
                    // TODO: 您可以对获取的活动状态列表,进行相应的处理
                }
            }
        }
    }
    “Kotlin”
    // 活动识别广播接收者
    class LocationBroadcastReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent != null) {
                val action = intent.action
                if (ACTION_PROCESS_LOCATION == action) {
                    // 获取ActivityIdentificationResponse,从response中提取检测到的活动状态列表
                    val activityIdentificationResponse =
                        ActivityIdentificationResponse.getDataFromIntent(intent)
                    val list =
                        activityIdentificationResponse.activityIdentificationDatas
                    // TODO: 您可以对获取的活动状态列表,进行相应的处理
                }
            }
        }
    
        companion object {
            // 活动识别服务广播action
            const val ACTION_PROCESS_LOCATION =
                "com.huawei.hms.location.ACTION_PROCESS_LOCATION"
        }
    }
  4. 移除活动识别更新。
    在使用完活动识别后需要进行移除操作。调用deleteActivityIdentificationUpdates(PendingIntent pendingIntent)移除活动识别定时监听,参数PendingIntent必须与createActivityIdentificationUpdates(long detectionIntervalMillis, PendingIntent callbackIntent)参数里的PendingIntent是同一个。
    “Java”
    activityIdentificationService.deleteActivityIdentificationUpdates(pendingIntent)
        // 移除回调成功监听回调
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                // TODO:移除活动识别成功处理
            }
        })
        // 移除回调失败监听回调
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                // TODO:移除活动识别失败处理
            }
        });
    “Kotlin”
    // 移除活动识别更新
    activityIdentificationService!!.deleteActivityIdentificationUpdates(pendingIntent)
        // 移除回调成功监听回调
        .addOnSuccessListener {
            // TODO:移除活动识别成功处理
    
        } // 移除回调失败监听回调
        .addOnFailureListener { e ->
            // TODO:移除活动识别失败处理
    
        }

监听活动转换

活动转换是指检测一种活动状态转换到另一种活动状态的过程,例如用户从走路状态转换到骑自行车状态。活动转换可以让应用通过调用createActivityConversionUpdates(ActivityConversionRequest request, PendingIntent pendingIntent)方法获取用户活动状态变化。

  1. 设置监听活动转换请求参数。
    “Java”
    // 创建一个静止状态进入活动转换信息对象
    ActivityConversionInfo activityConversionInfoStillEnter = new ActivityConversionInfo(
        ActivityIdentificationData.STILL, ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION);
    // 创建一个静止状态退出活动转换信息对象
    ActivityConversionInfo activityConversionInfoStillExit = new ActivityConversionInfo(
        ActivityIdentificationData.STILL, ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION);
    List<ActivityConversionInfo> activityConversionInfos = new ArrayList<>();
    activityConversionInfos.add(activityConversionInfoStillEnter);
    activityConversionInfos.add(activityConversionInfoStillExit);
    // 创建一个活动转换请求体实例
    ActivityConversionRequest request = new ActivityConversionRequest();
    request.setActivityConversions(activityConversionInfos);
    “Kotlin”
    // 创建一个静止状态进入活动转换信息对象
    val activityConversionInfoStillEnter = ActivityConversionInfo(
        ActivityIdentificationData.STILL,
        ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION
    )
    // 创建一个静止状态退出活动转换信息对象
    val activityConversionInfoStillExit = ActivityConversionInfo(
        ActivityIdentificationData.STILL,
        ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION
    )
    val activityConversionInfos: MutableList<ActivityConversionInfo> =
        ArrayList()
    activityConversionInfos.add(activityConversionInfoStillEnter)
    activityConversionInfos.add(activityConversionInfoStillExit)
    // 创建一个活动转换请求体实例
    val request = ActivityConversionRequest()
    request.activityConversions = activityConversionInfos
  2. 监听活动转换更新。
    “Java”
    // 监听活动识别状态转换
    Task<Void> task = activityIdentificationService.createActivityConversionUpdates(request, pendingIntent);
    // 任务成功监听回调
    task.addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            // TODO:请求活动转换成功处理
        }
    })
        // 任务失败监听回调
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                // TODO:请求活动转换失败处理
            }
        });
    “Kotlin”
    // 监听活动识别状态转换
    val task: Task<Void> =
       activityIdentificationService!!.createActivityConversionUpdates(request, pendingIntent)
    // 任务成功监听回调
    task.addOnSuccessListener(OnSuccessListener<Void?> {
        // TODO:请求活动转换成功处理
    })
        // 任务失败监听回调
        .addOnFailureListener(OnFailureListener { e ->
            // TODO:请求活动转换失败处理
        })

    参数说明

    参数

    类型

    描述

    备注

    request

    ActivtiyConversionRequest

    活动转换请求参数,设置需要监听的活动状态(行走、静止等)及相关活动转换进入、退出状态。

    构造的活动转换请求体

    pendingIntent

    PendingIntent

    每个活动过渡请求关联的pendingIntent,当检测到活动状态发现变化,将结果通过广播通知用户。

    构造PendingIntent时需设置Class、Action,不能构造空Intent。

  3. 广播接收活动转换结果。
    “Java”
    public class LocationBroadcastReceiver extends BroadcastReceiver {
        public static final String ACTION_PROCESS_LOCATION = "com.huawei.hms.location.ACTION_PROCESS_LOCATION";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
                final String action = intent.getAction();
                if (ACTION_PROCESS_LOCATION.equals(action)) {
                    // 从intent中获取ActivityConversionResponse,从response中提取活动转换事件列表
                    ActivityConversionResponse activityConversionResponse = ActivityConversionResponse.getDataFromIntent(intent);
                    List<ActivityConversionData> list = activityConversionResponse.getActivityConversionDatas();
                    // TODO: 您可以对获取的活动转换事件列表,进行相应的处理
                }
            }
        }
    }
    “Kotlin”
    class LocationBroadcastReceiver : BroadcastReceiver() {
        override fun onReceive(
            context: Context,
            intent: Intent
        ) {
            if (intent != null) {
                val action = intent.action
                if (ACTION_PROCESS_LOCATION == action) {
                    // 从intent中获取ActivityConversionResponse,从response中提取活动转换事件列表
                    val activityConversionResponse =
                        ActivityConversionResponse.getDataFromIntent(intent)
                    val list =
                        activityConversionResponse.activityConversionDatas
                    // TODO: 您可以对获取的活动转换事件列表,进行相应的处理
                }
            }
        }
    
        companion object {
            const val ACTION_PROCESS_LOCATION =
                "com.huawei.hms.location.ACTION_PROCESS_LOCATION"
        }
    }
  4. (可选)移除活动转换更新。
    不需要监听活动转换条件时,需要调用deleteActivityConversionUpdates(PendingIntent pendingIntent)进行移除操作。
    “Java”
    // 通过指定pendingIntent移除活动转换更新
    activityIdentificationService.deleteActivityConversionUpdates(pendingIntent)
        // 移除更新成功监听回调
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                // TODO:移除活动转换成功处理
            }
        })
        // 移除更新失败监听回调
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                // TODO:移除活动转换失败处理
            }
        });
    “Kotlin”
    // 通过指定pendingIntent移除活动转换更新
    activityIdentificationService!!.deleteActivityConversionUpdates(pendingIntent) 
        // 移除更新成功监听回调
        .addOnSuccessListener {
            // TODO:移除活动转换成功处理
        } 
        // 移除更新失败监听回调
        .addOnFailureListener { e ->
            // TODO:移除活动转换失败处理
        }