Android Intent传递经纬度失败求助(含LocalBroadcastManager需求)
我来帮你拆解这两个问题的核心原因,再给你一套用LocalBroadcastManager的完整解决方案:
第一个问题:无法从启动服务的Intent获取经纬度
核心原因
你在接收端的getValues()方法里犯了一个本质错误:你新建了一个Intent用来启动GPSService,然后试图从这个自己创建的Intent里提取Extra数据。但这个Intent只是用来触发服务启动的指令,和服务后续在onLocationChanged里发送的广播完全是两个独立的对象,它根本不会携带服务更新的经纬度信息。
第二个问题:广播已接收但数据为空
核心原因
- 你在
getValues()里依然错误地从启动服务的Intent中获取"xxx"字段,这个Intent自始至终都没有被设置过这个值,所以test1必然是null; - 你在
onReceive方法里没有读取广播传递过来的Intent里的Extra,反而去打印之前的test1变量,自然拿不到服务发送的真实数据。
完整解决方案(使用LocalBroadcastManager)
LocalBroadcastManager是Android官方推荐的App内部广播方案,比全局广播更安全、高效,正好匹配你的需求。
第一步:修改服务端,发送本地广播
更新GPSService的onLocationChanged方法,用LocalBroadcastManager发送带Action和数据的广播:
@Override public void onLocationChanged(Location location) { mLastLocation = location; double latitude = location.getLatitude(); double longitude = location.getLongitude(); // 调试用Toast String msg = "GPSService has Updated the Location: " + latitude + "," + longitude; Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); Log.d("Loc updated GPSService","after 30"); // 构建广播Intent,指定唯一Action用于匹配接收器 Intent intent = new Intent("GPS_LOCATION_UPDATED"); // 携带经纬度数据 intent.putExtra("latitude", latitude); intent.putExtra("longitude", longitude); intent.putExtra("location_msg", msg); // 使用LocalBroadcastManager发送本地广播 LocalBroadcastManager.getInstance(this).sendBroadcast(intent); }
第二步:修改接收端,注册并处理本地广播
更新接收端Activity的代码,正确注册接收器并提取广播数据:
private BroadcastReceiver mLocationReceiver; private TextView textLat, textLong; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.geofire); textLat = (TextView) findViewById(R.id.lat); textLong = (TextView) findViewById(R.id.lon); // 初始化广播接收器,处理接收到的位置数据 mLocationReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 从广播Intent中提取真实的经纬度数据 double latDouble = intent.getDoubleExtra("latitude", 0.0); double lonDouble = intent.getDoubleExtra("longitude", 0.0); String locationMsg = intent.getStringExtra("location_msg"); // 打印日志验证 Log.d("Receiver", "Received location: " + latDouble + "," + lonDouble); Log.d("Receiver", locationMsg); // 更新UI显示 textLat.setText(String.valueOf(latDouble)); textLong.setText(String.valueOf(lonDouble)); // 拿到真实经纬度后再初始化地图(如果需要) // initGMaps(latDouble, lonDouble); } }; // 注册本地广播接收器,匹配服务端设置的Action IntentFilter filter = new IntentFilter("GPS_LOCATION_UPDATED"); LocalBroadcastManager.getInstance(this).registerReceiver(mLocationReceiver, filter); // 启动GPS服务 startService(new Intent(this, GPSService.class)); // 地图初始化可以先执行,拿到数据后再更新位置 // initGMaps(); } @Override protected void onDestroy() { super.onDestroy(); // 一定要在页面销毁时注销接收器,避免内存泄漏 LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocationReceiver); }
关键注意事项
- 永远不要混淆启动服务的Intent和广播传递的Intent:前者是启动指令,后者是服务主动推送的数据载体,两者没有关联;
- 使用
LocalBroadcastManager的广播只会在你的App内部传递,不会被其他App监听,也不会触发其他App的广播,安全性更高; - 必须保证服务端发送的Intent的Action和接收端
IntentFilter设置的Action完全一致,否则接收器无法匹配到广播; - 页面销毁时务必注销广播接收器,防止内存泄漏。
内容的提问来源于stack exchange,提问作者czane
相关产品推荐
相关产品推荐

