You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在基于Fused Location API的校园APP中集成SMS Manager发送位置URL

集成SMS Manager并发送位置URL的完整方案

嘿,很高兴你已经搞定了Fused Location API的位置获取部分!接下来把位置转成可点击的地图URL并通过SMS发送,其实只需要几步就能完成,我给你梳理清楚:

1. 先搞定必要的权限

首先得确保你的应用拥有发送短信的权限,在AndroidManifest.xml里添加:

<uses-permission android:name="android.permission.SEND_SMS" />
<!-- 你已经添加的位置权限可以保留,比如ACCESS_FINE_LOCATION -->

注意:从Android 6.0(API 23)开始,SEND_SMS属于危险权限,所以你需要在运行时请求权限,不能只靠清单文件。可以在启动发送功能前先检查权限:

// 以Kotlin为例,Java写法逻辑一致
private const val SMS_PERMISSION_REQUEST_CODE = 1001

private fun checkSmsPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.SEND_SMS), SMS_PERMISSION_REQUEST_CODE)
    } else {
        // 权限已授予,直接执行发送逻辑
        sendLocationSms()
    }
}

// 处理权限请求结果
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == SMS_PERMISSION_REQUEST_CODE) {
        if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            sendLocationSms()
        } else {
            // 用户拒绝了权限,可以提示需要权限才能发送短信
            Toast.makeText(this, "需要短信权限才能发送位置", Toast.LENGTH_SHORT).show()
        }
    }
}

2. 把位置坐标转成可点击的地图URL

当你通过Fused Location API获取到Location对象后,可以把经纬度拼接成通用的地图URL(接收方点击就能直接打开地图定位):

private fun getLocationUrl(location: Location): String {
    val latitude = location.latitude
    val longitude = location.longitude
    // 这个格式兼容大部分地图应用,安卓/iOS用户点击都能直接跳转
    return "https://www.google.com/maps?q=$latitude,$longitude"
}

3. 用SMS Manager发送短信

接下来就是核心的发送逻辑,获取SmsManager实例,然后发送包含位置URL的短信:

// 先定义一个全局变量存储获取到的位置
private var currentLocation: Location? = null

private fun sendLocationSms() {
    currentLocation?.let { location ->
        val locationUrl = getLocationUrl(location)
        val phoneNumber = "目标手机号" // 这里可以改成用户输入的号码或预设号码
        val smsContent = "我的当前位置:$locationUrl"

        val smsManager = SmsManager.getDefault()
        // 可选:监听短信发送状态
        val sentIntent = PendingIntent.getBroadcast(this, 0, Intent("SMS_SENT"), PendingIntent.FLAG_IMMUTABLE)
        val deliveredIntent = PendingIntent.getBroadcast(this, 0, Intent("SMS_DELIVERED"), PendingIntent.FLAG_IMMUTABLE)

        smsManager.sendTextMessage(phoneNumber, null, smsContent, sentIntent, deliveredIntent)
    } ?: run {
        Toast.makeText(this, "无法获取当前位置", Toast.LENGTH_SHORT).show()
    }
}

如果需要监听发送是否成功,可以注册一个广播接收器:

private val smsSentReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        when (resultCode) {
            Activity.RESULT_OK -> {
                Toast.makeText(context, "位置短信发送成功", Toast.LENGTH_SHORT).show()
            }
            SmsManager.RESULT_ERROR_GENERIC_FAILURE -> {
                Toast.makeText(context, "发送失败:未知错误", Toast.LENGTH_SHORT).show()
            }
            SmsManager.RESULT_ERROR_NO_SERVICE -> {
                Toast.makeText(context, "发送失败:无信号", Toast.LENGTH_SHORT).show()
            }
            // 其他错误码可按需扩展
        }
    }
}

// 在onCreate里注册接收器
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ...其他初始化代码
    registerReceiver(smsSentReceiver, IntentFilter("SMS_SENT"))
}

// 在onDestroy里注销接收器
override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(smsSentReceiver)
}

4. 结合你现有的位置获取逻辑

把上面的代码和你已经实现的“点击按钮获取位置”功能结合起来:

// 假设你的获取位置按钮点击事件
findViewById<Button>(R.id.btn_get_location).setOnClickListener {
    // 这里是你已有的Fused Location获取逻辑
    fusedLocationClient.lastLocation.addOnSuccessListener { location ->
        currentLocation = location
        // 获取到位置后,检查权限并发送
        checkSmsPermission()
    }.addOnFailureListener {
        Toast.makeText(this, "获取位置失败", Toast.LENGTH_SHORT).show()
    }
}

一些实用提示

  • 测试一定要用真实安卓设备,模拟器通常无法发送真实短信。
  • 如果需要发送给多个号码,可以循环调用sendTextMessage,长短信可使用sendMultipartTextMessage(咱们这个场景基本用不上)。
  • 记得处理位置为null的情况(比如用户关闭了位置服务)。

内容的提问来源于stack exchange,提问作者LJ Ca-ong

火山引擎 最新活动