讲师中心 微信公众号

工具推荐

视频效率加速
Seko
Seko

AI短剧一键生成成片

立刻MV
立刻MV

低成本歌曲 MV、视频生成

Laper
Laper

剧本策划到成片协作

updream

一键生成高质量推广成片

Android Studio 中正确获取设备实时位置并发送含地理坐标的短信教程

秋辰大大_4435

秋辰大大_4435

发布时间:2026-03-04 23:56:03

|

379人浏览过

|

来源于php中文网

原创

Android Studio 中正确获取设备实时位置并发送含地理坐标的短信教程

本文详解如何在 android 应用中通过 locationmanager 正确获取设备当前经纬度(避免返回 0,0),并将其嵌入 url 后通过 sms 发送给联系人,涵盖权限申请、定位请求、异步处理与最佳实践。

本文详解如何在 android 应用中通过 locationmanager 正确获取设备当前经纬度(避免返回 0,0),并将其嵌入 url 后通过 sms 发送给联系人,涵盖权限申请、定位请求、异步处理与最佳实践。

在您提供的代码中,核心问题在于以下两行:

Location object = new Location("service Provider");
double lat = object.getLatitude(); double lng = object.getLongitude();

这行代码并未实际获取设备位置,而是手动创建了一个空的 Location 实例——其默认经纬度恒为 (0.0, 0.0)。要真正获取用户当前位置,必须借助系统定位服务(如 FusedLocationProviderClient 或传统 LocationManager),并主动发起定位请求。

✅ 正确做法:使用 FusedLocationProviderClient(推荐,适用于 Android Oreo 及以上)

FusedLocationProviderClient 是 Google Play Services 提供的现代、高效、省电的定位 API,兼容 Android O(8.0)及以上版本(您当前使用的系统),且比原生 LocationManager 更可靠、更易集成。

1. 添加依赖(确保 app/build.gradle 中包含)

implementation 'com.google.android.gms:play-services-location:21.3.0'

2. 声明必要权限(AndroidManifest.xml)

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- Android 10+ 需额外声明后台定位(若需持续追踪) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

⚠️ 注意:ACCESS_FINE_LOCATION 是获取高精度经纬度的必需权限;仅申请 ACCESS_COARSE_LOCATION 在多数设备上仍会返回 (0,0)。

3. 动态申请权限(优化版)

您原代码中存在两个关键缺陷:

Android Control
Android Control

通过命令行工具(uiautomator、screencap、input、am)控制安卓设备。优先尝试非 root 执行,失败后自动回退至 root...

下载
  • 权限请求逻辑混乱(如 ACCESS_COARSE_LOCATION 检查却申请 ACCESS_FINE_LOCATION);
  • Android Q+ 的 ACCESS_BACKGROUND_LOCATION 不应与前台权限混用同一 requestCode。

修正后的权限请求逻辑如下:

private static final int LOCATION_PERMISSION_REQUEST_CODE = 101;
private static final int SMS_CONTACT_PERMISSION_REQUEST_CODE = 102;

private void requestLocationPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                LOCATION_PERMISSION_REQUEST_CODE);
    } else {
        startLocationRequest();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startLocationRequest();
        } else {
            Toast.makeText(this, "定位权限被拒绝,无法发送位置信息", Toast.LENGTH_SHORT).show();
        }
    }
}

4. 获取实时位置(关键步骤)

使用 FusedLocationProviderClient 请求一次最新位置:

private FusedLocationProviderClient fusedLocationClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

    // ... 其他初始化代码(ListView、DB 等)...

    send.setOnClickListener(v -> {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            getCurrentLocation();
        } else {
            requestLocationPermission();
        }
    });
}

private void getCurrentLocation() {
    LocationRequest locationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setNumUpdates(1) // 仅获取一次
            .setInterval(10000);

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
            == PackageManager.PERMISSION_GRANTED) {
        fusedLocationClient.requestLocationUpdates(locationRequest,
                locationCallback,
                Looper.getMainLooper());
    }
}

private final LocationCallback locationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(@NonNull LocationResult locationResult) {
        if (locationResult != null && locationResult.getLastLocation() != null) {
            Location currentLocation = locationResult.getLastLocation();
            double lat = currentLocation.getLatitude();
            double lng = currentLocation.getLongitude();

            // ✅ 此时 lat/lng 为真实坐标,非 0,0
            String uri = String.format("https://maps.google.com/maps?q=%f,%f", lat, lng);
            sendLocationSms(uri);
        } else {
            Toast.makeText(MainActivity.this, "无法获取位置,请检查 GPS 是否开启", Toast.LENGTH_LONG).show();
        }
    }
};

5. 发送含位置的短信

将生成的 Google Maps 链接嵌入短信正文,并批量发送:

private void sendLocationSms(String mapUrl) {
    SmsManager smsManager = SmsManager.getDefault();
    DbHelper db = new DbHelper(this);
    List<ContactModel> contacts = db.getAllContacts();

    for (ContactModel contact : contacts) {
        String message = String.format(
                "紧急求助!我正处在危险中,请速来支援。\n我的实时位置:%s\n(点击链接可直接在地图中查看)",
                mapUrl
        );
        try {
            smsManager.sendTextMessage(contact.getPhoneNo(), null, message, null, null);
        } catch (Exception e) {
            Log.e("SMS", "发送失败:" + contact.getPhoneNo(), e);
            Toast.makeText(this, "向 " + contact.getName() + " 发送失败", Toast.LENGTH_SHORT).show();
        }
    }
    Toast.makeText(this, "位置已发送至所有联系人", Toast.LENGTH_SHORT).show();
}

? 补充说明与注意事项

  • 模拟器调试提示:Android Studio 模拟器需在 Extended Controls → Location 中手动设置经纬度,否则 FusedLocationProviderClient 无法返回有效值。
  • GPS 硬件状态:真机测试前,请确认设备已开启「定位服务」且模式设为「高精确度」(Wi-Fi + 蓝牙 + GPS)。
  • Android 12+ 变更:从 API 31 起,SEND_SMS 权限被归类为“特殊权限”,需引导用户手动开启(ACTION_MANAGE_OVERLAY_PERMISSION 不适用,应跳转设置页)。
  • 用户体验优化建议:
    • 添加加载状态(如 ProgressBar 或 Toast “正在获取位置…”);
    • 对 onLocationResult 增加超时机制(如 Handler.postDelayed);
    • 使用 Intent.ACTION_VIEW + Uri.parse(mapUrl) 提供一键地图跳转按钮,提升可操作性。

通过以上重构,您的应用将彻底告别 (0,0) 坐标陷阱,稳定、准确地获取用户当前位置,并安全、合规地完成紧急求助短信分发。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

5144

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

6697

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

2642

2024.11.28

location.assign
location.assign

在前端开发中,我们经常需要使用JavaScript来控制页面的跳转和数据的传递。location.assign就是JavaScript中常用的一个跳转方法。通过location.assign,我们可以在当前窗口或者iframe中加载一个新的URL地址,并且可以保存旧页面的历史记录。php中文网为大家带来了location.assign的相关知识、以及相关文章等内容,供大家免费下载使用。

3342

2023.06.27

android开发三大框架
android开发三大框架

android开发三大框架是XUtil框架、volley框架、ImageLoader框架。本专题为大家提供android开发三大框架相关的各种文章、以及下载和课程。

942

2023.08.14

android是什么系统
android是什么系统

Android是一种功能强大、灵活可定制、应用丰富、多任务处理能力强、兼容性好、网络连接能力强的操作系统。本专题为大家提供android相关的文章、下载、课程内容,供大家免费下载体验。

2827

2023.08.22

android权限限制怎么解开
android权限限制怎么解开

android权限限制可以使用Root权限、第三方权限管理应用程序、ADB命令和Xposed框架解开。详细介绍:1、Root权限,通过获取Root权限,用户可以解锁所有权限,并对系统进行自定义和修改;2、第三方权限管理应用程序,用户可以轻松地控制和管理应用程序的权限;3、ADB命令,用户可以在设备上执行各种操作,包括解锁权限;4、Xposed框架,用户可以在不修改系统文件的情况下修改应用程序的行为和权限。

5717

2023.09.19

android重启应用的方法有哪些
android重启应用的方法有哪些

android重启应用有通过Intent、PendingIntent、系统服务、Runtime等方法。本专题为大家提供Android相关的文章、下载、课程内容,供大家免费下载体验。

745

2023.10.18

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 45.7万人学习

Java 教程
Java 教程

共578课时 | 199.1万人学习

Uniapp从零开始实现新闻资讯应用
Uniapp从零开始实现新闻资讯应用

共64课时 | 9.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn