npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

expo-qq-location

v0.2.1

Published

A React Native Expo module for Tencent Location SDK with continuous location tracking

Downloads

35

Readme

Expo QQ Location

License Platform SDK

🚀 一个基于腾讯地图定位SDK的Expo Native Module,为React Native应用提供高精度定位功能。

✨ 特性

  • 🎯 高精度定位 - 基于腾讯地图定位SDK v7.6.1
  • 📱 连续定位 - 支持按间隔连续获取位置信息
  • 🎯 单次定位 - 支持按需获取一次最新位置(不必启动连续定位)
  • ♻️ 幂等启动 - 相同参数重复调用不会重复启动,参数变更才会可控重启
  • 🏢 丰富的地址信息 - 包含行政区划、POI等详细信息
  • 🔒 隐私合规 - 完全符合Android隐私政策要求
  • ⚙️ 自动配置 - 内置Config Plugin自动配置权限和API Key
  • 📊 状态监听 - 实时监听GPS、WiFi、Cell状态变化
  • 🔧 TypeScript支持 - 完整的类型定义

📦 安装

npm install expo-qq-location
# 或
yarn add expo-qq-location

🛠️ 配置

1. 配置API Key

在您的 app.jsonapp.config.js 中添加plugin配置:

{
  "expo": {
    "plugins": [
      [
        "expo-qq-location",
        {
          "apiKey": "your_tencent_map_api_key_here"
        }
      ]
    ]
  }
}

2. 重新构建项目

npx expo prebuild --clean
npx expo run:android

🚀 快速开始

import React, { useEffect, useState } from 'react';
import { Alert } from 'react-native';
import ExpoQqLocationModule, {
  LocationChangedEvent,
  setUserAgreePrivacy,
  startLocationUpdates,
  stopLocationUpdates,
  addLocationListener,
  addLocationErrorListener,
  RequestLevel,
  LocationMode
} from 'expo-qq-location';

export default function LocationExample() {
  const [location, setLocation] = useState<LocationChangedEvent | null>(null);

  useEffect(() => {
    // 1. 设置隐私协议同意(必须)
    setUserAgreePrivacy(true);

    // 2. 添加定位监听器
    const locationSubscription = addLocationListener((event) => {
      setLocation(event);
      console.log('定位成功:', event);
    });

    // 3. 添加错误监听器
    const errorSubscription = addLocationErrorListener((event) => {
      Alert.alert('定位失败', event.reason);
    });

    // 4. 开始定位
    const startLocation = async () => {
      try {
        const result = await startLocationUpdates({
          interval: 5000, // 5秒间隔
          requestLevel: RequestLevel.REQUEST_LEVEL_ADMIN_AREA,
          allowGPS: true,
          locMode: LocationMode.HIGH_ACCURACY_MODE
        });

        if (result === 0) {
          console.log('定位启动成功');
        }
      } catch (error) {
        console.error('定位启动失败:', error);
      }
    };

    startLocation();

    // 5. 清理
    return () => {
      locationSubscription?.remove();
      errorSubscription?.remove();
      stopLocationUpdates();
    };
  }, []);

  return (
    // 您的UI组件
  );
}

📚 API 参考

核心方法

setUserAgreePrivacy(isAgree: boolean)

设置用户是否同意隐私协议(必须先调用)

setUserAgreePrivacy(true);

setDeviceID(deviceId: string)

设置设备唯一标识(可选)

setDeviceID('unique-device-id');

startLocationUpdates(request?: LocationRequest): Promise<number>

开始连续定位。该方法为幂等行为:

  • 同参数重复调用:直接返回成功,不重复启动
  • 参数变化调用:自动执行一次 stop + restart
const result = await startLocationUpdates({
  interval: 3000,                                    // 定位间隔(毫秒)
  requestLevel: RequestLevel.REQUEST_LEVEL_ADMIN_AREA, // 请求级别
  allowGPS: true,                                    // 允许GPS
  allowDirection: true,                              // 获取方向信息
  indoorLocationMode: true,                          // 室内定位
  locMode: LocationMode.HIGH_ACCURACY_MODE,          // 定位模式
  gpsFirst: true,                                    // GPS优先
  gpsTimeOut: 8000,                                  // GPS超时时间
  allowCache: true                                   // 允许缓存定位结果
});

isLocationRunning(): boolean

查询当前连续定位是否处于运行态

const running = isLocationRunning();
console.log('连续定位运行中:', running);

requestSingleFreshLocation(request?: LocationRequest): Promise<SingleLocationResult>

请求一次最新位置,适合“选地址/只取一次当前点位”场景。

const location = await requestSingleFreshLocation({
  requestLevel: RequestLevel.REQUEST_LEVEL_NAME,
  allowGPS: true,
  allowCache: true,
  locMode: LocationMode.HIGH_ACCURACY_MODE,
});

stopLocationUpdates()

停止定位

stopLocationUpdates();

hasLocationPermission(): Promise<boolean>

检查是否有定位权限

const hasPermission = await hasLocationPermission();

requestLocationPermission(): Promise<boolean>

检查当前定位权限状态(在 Expo 环境下通常由系统/框架处理权限弹窗)

const granted = await requestLocationPermission();

事件监听

addLocationListener(listener): Subscription

监听定位成功事件

const subscription = addLocationListener((event: LocationChangedEvent) => {
  console.log('纬度:', event.latitude);
  console.log('经度:', event.longitude);
  console.log('地址:', event.address);
});

addLocationErrorListener(listener): Subscription

监听定位错误事件

const subscription = addLocationErrorListener((event: LocationErrorEvent) => {
  console.log('错误码:', event.error);
  console.log('错误描述:', event.reason);
});

addStatusUpdateListener(listener): Subscription

监听状态更新事件

const subscription = addStatusUpdateListener((event: LocationStatusEvent) => {
  console.log('设备名:', event.name);
  console.log('状态:', event.status);
});

removeAllLocationListeners()

⚠️ @deprecated:仅建议用于全局兜底清理,不建议在普通页面中调用。

推荐在页面/组件销毁时,使用 addXxxListener 返回的订阅对象执行 subscription.remove(),避免误删其他页面的监听器。

类型定义

LocationChangedEvent

type LocationChangedEvent = {
  latitude: number;          // 纬度
  longitude: number;         // 经度
  altitude: number;          // 海拔
  accuracy: number;          // 精度(米)
  bearing: number;           // 方向角
  speed: number;             // 速度
  timestamp: number;         // 时间戳

  // 地址信息(可选)
  nation?: string;           // 国家
  province?: string;         // 省份
  city?: string;             // 城市
  district?: string;         // 区县
  town?: string;             // 城镇
  village?: string;          // 村庄
  street?: string;           // 街道
  streetNo?: string;         // 门牌号
  name?: string;             // 地点名称
  address?: string;          // 详细地址

  // POI信息(可选)
  poiList?: Array<{
    name: string;
    address: string;
    latitude: number;
    longitude: number;
  }>;
};

LocationRequest

type LocationRequest = {
  interval?: number;          // 定位间隔(毫秒,最小1000)
  requestLevel?: number;      // 请求级别(0-4)
  allowGPS?: boolean;         // 是否允许GPS
  allowDirection?: boolean;   // 是否获取方向
  indoorLocationMode?: boolean; // 室内定位模式
  locMode?: number;           // 定位模式(10-12)
  gpsFirst?: boolean;         // GPS优先
  gpsTimeOut?: number;        // GPS超时时间(毫秒)
  allowCache?: boolean;       // 是否允许缓存定位结果
};

常量

请求级别

RequestLevel.REQUEST_LEVEL_GEO        // 0: 仅坐标
RequestLevel.REQUEST_LEVEL_NAME       // 1: 坐标+地址
RequestLevel.REQUEST_LEVEL_ADMIN_AREA // 3: 坐标+行政区划
RequestLevel.REQUEST_LEVEL_POI        // 4: 坐标+行政区划+POI

定位模式

LocationMode.HIGH_ACCURACY_MODE  // 10: 高精度模式
LocationMode.ONLY_NETWORK_MODE   // 11: 仅网络定位
LocationMode.ONLY_GPS_MODE       // 12: 仅GPS定位

错误码

ErrorCodes.ERROR_OK       // 0: 定位成功
ErrorCodes.ERROR_NETWORK  // 1: 网络错误
ErrorCodes.ERROR_BAD_JSON // 2: GPS/WiFi/基站错误
ErrorCodes.ERROR_WGS84    // 4: 坐标转换错误
ErrorCodes.ERROR_UNKNOWN  // 404: 未知错误

🔧 配置选项

Config Plugin 选项

| 选项 | 类型 | 必需 | 描述 | |------|------|------|------| | apiKey | string | ✅ | 腾讯地图Android API Key | | iosApiKey | string | ❌ | 腾讯地图iOS API Key(未来支持) |

自动配置的权限

Plugin会自动添加以下Android权限:

<!-- 基础定位权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

<!-- 网络权限 -->
<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" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

<!-- 系统权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

⚠️ 注意事项

隐私合规

  1. 必须先调用 setUserAgreePrivacy(true) 才能使用定位功能
  2. Android 6.0+ 需要在运行时请求位置权限
  3. Android 10+ 需要额外的后台位置权限

权限处理

// 检查权限状态(requestLocationPermission 返回当前状态)
const checkPermissions = async () => {
  const hasPermission = await hasLocationPermission();
  if (!hasPermission) {
    const granted = await requestLocationPermission();
    if (!granted) {
      Alert.alert('权限提示', '请在设置中授予定位权限');
      return false;
    }
  }
  return true;
};

监听器清理建议

const locationSub = addLocationListener((event) => {
  console.log(event);
});

const errorSub = addLocationErrorListener((event) => {
  console.log(event);
});

return () => {
  locationSub.remove();
  errorSub.remove();
};

不要在普通页面调用 removeAllLocationListeners(),以免影响其他页面或模块仍在使用的监听器。

API Key获取

  1. 访问 腾讯位置服务
  2. 注册账号并创建应用
  3. 获取Android平台的API Key
  4. 在app.json中配置API Key

🐛 故障排除

常见问题

1. 定位失败

// 检查是否设置了隐私协议
setUserAgreePrivacy(true);

// 检查API Key是否正确
const apiKey = getApiKey();
console.log('API Key:', apiKey);

2. 权限被拒绝

// 检查权限状态
const hasPermission = await hasLocationPermission();
if (!hasPermission) {
  // 引导用户到设置页面
}

3. 模块未找到

# 重新构建项目
npx expo prebuild --clean
npx expo run:android

📄 许可证

MIT License - 详见 LICENSE 文件

🤝 贡献

欢迎提交 Issue 和 Pull Request!

📞 支持


⭐ 如果这个项目对您有帮助,请给个星星支持一下!