0

0

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

心靈之曲

心靈之曲

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

|

259人浏览过

|

来源于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. 动态申请权限(优化版)

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

Figma
Figma

Figma 是一款基于云端的 UI 设计工具,可以在线进行产品原型、设计、评审、交付等工作。

下载
  • 权限请求逻辑混乱(如 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工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

1940

2024.04.01

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

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

2116

2024.08.01

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

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

1150

2024.11.28

location.assign
location.assign

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

232

2023.06.27

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

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

332

2023.08.14

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

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

1798

2023.08.22

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

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

2119

2023.09.19

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

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

284

2023.10.18

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

4

2026.03.04

热门下载

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

精品课程

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

共162课时 | 19.9万人学习

Java 教程
Java 教程

共578课时 | 76.7万人学习

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

共64课时 | 6.9万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号