Android提供了两种位置权限: ACCESS_COARSE_LOCATION(粗略的位置权限) 和ACCESS_FINE_LOCATION(精确的位置权限)。 需要在Manifest文件中申请权限:
- <!--Fused Location-->
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
在Android Q版本中,如果您需要应用程序在后台执行时也具备持续定位能力,需要在Manifest文件中申请ACCESS_BACKGROUND_LOCATION权限:
- <!--Fused Location-->
- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
为定位模块定义的Java类是RNFusedLocationModule,该类导出到React Native的名称是FusedLocation。
- import HMSLocation from 'react-native-hms-location';
- const FusedLocation = {
- Native: HMSFusedLocation,
- Data: LocationData,
- Request: LocationRequest,
- SettingsRequest: LocationSettingsRequest,
- PriorityConstants: HMSFusedLocation.PriorityConstants,
- Events: {
- addFusedLocationEventListener,
- removeFusedLocationEventListener,
- },
- };
设备的相关定位设置会影响华为定位服务的定位结果,例如位置开关选项处于关闭状态时,将无法获取到位置信息。 因此,建议您在持续获取位置信息之前,先检查设备设置是否满足定位条件。 华为定位服务提供了检查设备定位相关设置的能力。
当设置不满足定位需求时,将为您提供解决方案以提示用户打开对应的权限(HMS Core服务定位权限必须打开,Android Q版本中必须选择“始终允许”)。
您可以通过checkLocationSettings( locationSettingsRequest )方法获取定位设置。
locationSettingsRequest对象是方法的入参,包含三个属性:locationRequest、alwaysShow和needBle。
可通过如下代码创建locationRequest属性:
- const locationRequest = HMSLocation.FusedLocation.Request.configure({
- id: 'e0048e' + Math.random() * 10000,
- priority: HMSLocation.FusedLocation.PriorityConstants.PRIORITY_HIGH_ACCURACY,
- interval: 3,
- numUpdates: 10,
- fastestInterval: 1000.0,
- expirationTime: 200000.0,
- expirationTimeDuration: 200000.0,
- smallestDisplacement: 0.0,
- maxWaitTime: 2000000.0,
- needAddress: true,
- language: 'en',
- countryCode: 'en',
- }).build();
然后,可通过如下代码创建locationSettingsRequest对象:
- const locationSettingsRequest =
- HMSLocation.FusedLocation.SettingsRequest.configure({
- locationRequests: [locationRequest],
- alwaysShow: false,
- needBle: false,
- }).build();
needBle属性表示是否需要开启BLE扫描。 取值包括true(需要)和false(不需要)。
alwaysShow属性表示继续使用app是否需要位置信息。 取值包括true(需要)和false(不需要)。
最后,调用checkLocationSettings()方法来回复定位设置。 该方法会返回一个响应。
- HMSLocation.FusedLocation.Native.checkLocationSettings(locationSettingsRequest)
- .then(res => setLocationSettings(res))
- .catch(ex => console.log("Error while getting location settings. " + ex))
使用华为定位服务API,您的应用程序可以获取设备最后的已知位置,大多情况下,该位置即为设备的当前位置。
调用getLastLocation()方法获取最后的已知位置的代码样例如下:
该方法无入参,会返回一个包含位置数据的响应。
- import HMSLocation from 'react-native-hms-location';
- const getLocation = useCallback(() => {
- HMSLocation.FusedLocation.Native.getLastLocation()
- .then(pos => setPosition(pos))
- .catch(err => console.log('Failed to get last location', err));
- }, []);
- return (
- <View style={styles.spaceBetweenRow}>
- <Text style={styles.sectionTitle}>Location Info</Text>
- <Button title="Get last location" onPress={getLocation} />
- </View>
- );
如果您希望应用可以持续获取设备位置,可以使用华为定位服务提供的requestLocationUpdatesWithCallback()和addFusedLocationEventListener ()接口。
首先需要创建一个locationRequest对象。具体创建方法请参见“定位设置”示例。 然后,调用requestLocationUpdatesWithCallback()方法。
该方法用于通过指定的Looper线程上的回调来请求位置更新,如果请求成功,则返回位置请求的ID。
- import HMSLocation from 'react-native-hms-location';
- const requestLocationUpdate = useCallback(() => {
- const LocationRequest = HMSLocation.FusedLocation.Request.configure({
- id: 'e0048e' + Math.random() * 10000,
- /**
- * other such properties
- */
- }).build();
- HMSLocation.FusedLocation.Native
- .requestLocationUpdatesWithCallback(LocationRequest)
- .then(({ id }) => setLocationUpdateId(id))
- .catch(ex => console.log("Exception while requestLocationUpdatesWithCallback " + ex))
- }, []);
然后,为周期性位置更新添加事件监听器,该监听器包含一个定义的handler用来处理更新事件。
- const handleLocationUpdate = useCallback(location => {
- console.log(location);
- setPosition(location);
- }, []);
- const addFusedLocationEventListener = useCallback(() => {
- requestLocationUpdate();
- HMSLocation.FusedLocation.Events.addFusedLocationEventListener(
- handleLocationUpdate,
- );
- setAutoUpdateEnabled(true);
- }, []);
- const removeFusedLocationEventListener = useCallback(() => {
- HMSLocation.FusedLocation.Events.removeFusedLocationEventListener(
- locationUpdateId,
- handleLocationUpdate,
- );
- setAutoUpdateEnabled(false);
- }, [locationUpdateId]);
使用模拟位置信息功能,可打开“设置 -> 系统和更新 -> 开发人员选项 ->选择模拟位置信息应用”,选择要使用模拟位置的应用。 (如果没有发现“开发人员选项”,请打开“设置->关于手机->版本号”,连续点击“版本号”7次,“开发人员选项”会出现在“系统与更新”页面,再重复上述操作。) 示例代码如下:
可通过setMockMode( boolean )方法来开启或关闭模拟位置特性。
该方法的入参为boolean,表示是否开启或关闭模拟位置特性。
方法返回一个包含结果的响应。
- import HMSLocation from 'react-native-hms-location';
- const [lat, setLat] = useState("41.3");
- const [long, setLong] = useState("29.1");
- const enableMockLocation = () => {
- HMSLocation.FusedLocation.Native.setMockMode(true)
- .then(res => console.log('Mock mode ', res))
- .catch(err => console.log(err));
- };
- return (
- <View style={styles.sectionContainer}>
- <Button
- title="Enable"
- onPress={enableMockLocation}
- />
- </View>
- );
模拟位置的坐标可通过setMockLocation({ latitude, longitude })方法设置。
该方法入参为一个单一对象,包含经纬度属性。 此外,该方法返回一个响应消息。
- const setMockLocation = () => {
- HMSLocation.FusedLocation.Native.setMockLocation(
- {
- latitude: parseFloat(lat),
- longitude: parseFloat(long)
- }
- )
- .then(res => { console.log('MOCK SET', res); })
- .catch(err => { console.log(err); });
- };
- return (
- <View style={styles.sectionContainer}>
- <Button
- title="Set"
- onPress={setMockLocation}
- />
- </View>
- );
模拟位置属性开启并设置后,您的手机在尝试获取最后已知位置时应返回具体的位置数据
在Android Q以下版本使用活动识别服务,需要在manifest文件中配置以下权限:
- <!--Activity Identification-->
- <uses-permission android:name="com.huawei.hms.permission.ACTIVITY_RECOGNITION" />
在Android Q及以上版本中,需要在Manifest文件中申请以下权限:
- <!--Activity Identification-->
- <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
为定位模块定义的Java类名称是RNActivityIdentificationModule,该类导出到React Native的名称是ActivityIdentification。
- import HMSLocation from 'react-native-hms-location';
- const ActivityIdentification = {
- Native: HMSActivityIdentification,
- ConversionInfo: ActivityConversionInfo,
- ConversionData: ActivityConversionData,
- ConversionRequest: ActivityConversionRequest,
- ConversionResponse: ActivityConversionResponse,
- IdData: ActivityIdentificationData,
- IdResponse: ActivityIdentificationResponse,
- Activities: HMSActivityIdentification.Activities,
- ActivityConversions: HMSActivityIdentification.ActivityConversions,
- Events: {
- addActivityIdentificationEventListener,
- removeActivityIdentificationEventListener,
- addActivityConversionEventListener,
- removeActivityConversionEventListener
- }
- }
使用活动识别服务,首先需要您注册活动识别更新来检测用户当前是步行、骑自行车或者静止等状态。
您可以使用createActivityIdentificationUpdates(duration)方法创建活动识别更新。
该方法的唯一入参为更新间隔,方法将返回一个包含生成的请求ID的响应。
- import HMSLocation from 'react-native-hms-location';
- const [idReqCode, setIdReqCode] = useState();
- const createActivityIdentification = useCallback(() => {
- HMSLocation.ActivityIdentification.Native
- .createActivityIdentificationUpdates(2000)
- .then(res => {
- console.log(res);
- setIdReqCode(res.requestCode);
- })
- .catch(err => console.log('ERROR: Activity identification failed', err));
- }, []);
该请求ID后续可以用来删除创建的活动识别更新。
- const removeActivityIdentification = useCallback(idReqCode => {
- HMSLocation.ActivityIdentification.Native
- .deleteActivityIdentificationUpdates(idReqCode)
- .then(res => {
- console.log(res);
- setIdReqCode(null);
- })
- .catch(err =>
- console.log('ERROR: Activity identification deletion failed', err));
- }, []);
您可以通过addActivityIdentificationEventListener (handlerMethod)方法来监听活动识别时间并接受事件数据。
该方法的唯一入参是一个在发送活动识别事件时调用的handler方法。
- const [identificationSubscribed,
- setIdentificationSubscribed] = useState(false);
- const handleActivityIdentification = useCallback(act => {
- console.log('ACTIVITY : ', act);
- setIdentificationResponse(act);
- }, []);
- const addActivityIdentificationEventListener = useCallback(() => {
- HMSLocation.ActivityIdentification.Events
- .addActivityIdentificationEventListener(
- handleActivityIdentification,
- );
- setIdentificationSubscribed(true);
- }, []);
可以使用removeActivityIdentificationEventListener (handlerMethod)方法来移除定义的监听器。
该方法仅有一个入参,和上面方法的一样。
- const removeActivityIdentificationEventListener = useCallback(() => {
- HMSLocation.ActivityIdentification.Events
- .removeActivityIdentificationEventListener(
- handleActivityIdentification,
- );
- setIdentificationSubscribed(false);
- }, []);
- return (
- <View style={styles.centralizeContent}>
- <Button
- title={identificationSubscribed ? "Unsubscribe" : "Subscribe"}
- onPress={() => {
- if (identificationSubscribed) {
- removeActivityIdentificationEventListener()
- } else {
- addActivityIdentificationEventListener()
- }
- }} />
- );
接口提供检测活动转换条件(进入,退出)的功能。 例如,需要检测用户从站立不动变为行走状态时:
您可以通过createActivityConversionUpdates(conversionRequest)方法创建活动转换更新。
该方法的唯一入参是一个对象,表示待检测的活动类型和转换类型。 如下是该对象的一个举例:
- const conversionRequest =
- HMSLocation.ActivityIdentification.ConversionRequest.configure([
- // STILL
- {
- conversionType:
- HMSLocation.ActivityIdentification
- .ActivityConversions.ENTER_ACTIVITY_CONVERSION,
- activityType:
- HMSLocation.ActivityIdentification.Activities.STILL
- },
- // ON FOOT
- {
- conversionType:
- HMSLocation.ActivityIdentification
- .ActivityConversions.ENTER_ACTIVITY_CONVERSION,
- activityType:
- HMSLocation.ActivityIdentification.Activities.FOOT
- }
- ]).build();
createActivityConversionUpdates方法返回一个包含发送请求的ID的响应。
- const createConversionUpdates = useCallback(conversionRequest => {
- HMSLocation.ActivityIdentification
- .Native.createActivityConversionUpdates(conversionRequest)
- .then(res => {
- console.log(res);
- setConvReqCode(res.requestCode);
- })
- .catch(err =>
- console.log('ERROR: Activity Conversion creation failed', err));
- }, []);
该ID后续可用来移除创建的转换更新。
- const deleteConversionUpdates = useCallback(convReqCode => {
- HMSLocation.ActivityIdentification
- .Native.deleteActivityConversionUpdates(convReqCode)
- .then(res => {
- console.log(res);
- setConvReqCode(null);
- })
- .catch(err =>
- console.log('ERROR: Activity Conversion deletion failed', err));
- }, []);
您可以通过addActivityConversionEventListener (handlerMethod)方法监听活动识别事件并接收事件数据。
该方法的唯一入参是一个在发送活动识别事件时调用的handler方法。
- const [conversionSubscribed,
- setConversionSubscribed] = useState(false);
- const handleActivityIdentification = useCallback(act => {
- console.log('ACTIVITY : ', act);
- setIdentificationResponse(act);
- }, []);
- const addActivityConversionEventListener = useCallback(() => {
- HMSLocation.ActivityIdentification
- .Events.addActivityConversionEventListener(
- handleActivityConversion,
- );
- setConversionSubscribed(true);
- }, []);
你可以通过removeActivityConversionEventListener (handlerMethod)方法来移除定义的监听器。
该方法仅有一个入参,和上面方法的一样。
- const removeActivityConversionEventListener = useCallback(() => {
- HMSLocation.ActivityIdentification
- .Events.removeActivityConversionEventListener(
- handleActivityConversion,
- );
- setConversionSubscribed(false);
- }, []);
- return (
- <View style={styles.centralizeContent}>
- <Button
- title={identificationSubscribed ? "Unsubscribe" : "Subscribe"}
- onPress={() => {
- if (identificationSubscribed) {
- addActivityConversionEventListener()
- } else {
- addActivityIdentificationEventListener()
- }
- }} />
- </View>
- );
如果需要使用地理围栏服务API,需要在Manifest文件中申请ACCESS_FINE_LOCATION权限:
- <!--Geofence-->
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
在Android Q版本中,需要在Manifest文件中申请ACCESS_BACKGROUND_LOCATION权限:
- <!--Geofence-->
- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
为定位模块定义的Java类名称是RNGeofenceModule,该类导出到React Native的名称是Geofence。
- import HMSLocation from 'react-native-hms-location';
- const Geofence = {
- Native: HMSGeofence,
- Builder: GeofenceBuilder,
- Data: GeofenceData,
- Request: GeofenceRequest,
- GeofenceRequestConstants: HMSGeofence.GeofenceRequestConstants,
- GeofenceConstants: HMSGeofence.GeofenceConstants,
- ErrorCodes: HMSGeofence.ErrorCodes,
- Events: {
- addGeofenceEventListener,
- removeGeofenceEventListener
- }
- };
您可以先创建地理围栏实例,并构建添加地理围栏的请求。
可通过如下方法创建地理围栏列表:
createGeofenceList( geofences, conversions, coordinateType )
该方法具有三个入参:
- Geofences:待添加的地理围栏列表。
- Conversions:初始转换。
- Coordinate Type:坐标类型。
可以通过提供的builder来创建地理围栏实例,如下所示:
- const geofence1 = HMSLocation.Geofence.Builder.configure({
- longitude: 42.0,
- latitude: 29.0,
- radius: 20.0,
- uniqueId: 'e00322',
- conversions: 1,
- validContinueTime: 10000.0,
- dwellDelayTime: 10,
- notificationInterval: 1,
- }).build();
通过提供的builder创建一个geofenceRequest对象,如下所示:
- const geofenceRequest = HMSLocation.Geofence.Request.configure({
- geofences: [geofence1, geofence2],
- conversions: 1,
- coordinate: 1,
- }).build();
最后,通过创建的请求对象调用createGeofenceList方法。该方法返回一个包含发送请求的ID的响应。
- const createGeofenceList = useCallback(() => {
- HMSLocation.Geofence.Native.createGeofenceList(
- geofenceRequest.geofences,
- geofenceRequest.conversions,
- geofenceRequest.coordinate,
- )
- .then(res => {
- console.log(res);
- setReqCode(parseInt(res.requestCode));
- })
- .catch(err => {
- console.log(err);
- });
- })
该ID后续可用来移除创建的转换更新。
- const deleteGeofenceList = useCallback(reqCode => {
- HMSLocation.Geofence.Native.deleteGeofenceList(reqCode)
- .then(res => {
- console.log(res);
- setReqCode(null);
- })
- .catch(err => console.log('ERROR: GeofenceList deletion failed', err))
- }, []);
可以通过addGeofenceEventListener ( handlerMethod )方法来监听活动地理围栏事件以及接收事件数据。
该方法的唯一入参是一个在发送地理围栏事件时调用的handler方法。
- import HMSLocation from 'react-native-hms-location';
- const [geoSubscribed, setGeoSubscribed] = useState(false);
- const handleGeofenceEvent = useCallback(geo => {
- console.log('GEOFENCE : ', geo);
- setGeofenceResponse(geo);
- });
- const addGeofenceEventListener = useCallback(() => {
- HMSLocation.Geofence.Events.addGeofenceEventListener(
- handleGeofenceEvent,
- );
- setGeoSubscribed(true);
- }, []);
可以通过removeGeofenceEventListener ( handlerMethod )方法来移除定义的监听器。
该方法仅有一个入参,和上面方法的一样。
- const removeGeofenceEventListener = useCallback(() => {
- HMSLocation.Geofence.Events.removeGeofenceEventListener(
- handleGeofenceEvent,
- )
- setGeoSubscribed(false);
- })
- return (
- <View style={styles.centralizeContent}>
- <Button
- title={geoSubscribed ? "Unsubscribe" : "Subscribe"}
- onPress={() => {
- if (geoSubscribed) {
- removeGeofenceEventListener()
- } else {
- addGeofenceEventListener()
- }
- }} />
- </View>
- );