You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android定位服务广播数据未传递,LatLng对象赋值失败求助

问题分析与解决方案

看起来你的Google Map位置追踪应用遇到了两个核心问题:Service代码未执行,以及因currentLocation为null导致的LatLng初始化失败。我来帮你一步步排查修复:

一、先解决最紧急的NullPointerException问题

你的onResume方法里有一行代码会直接触发空指针异常:

Log.d(TAG, "onResume:"+ currentLocation.toString());

currentLocation初始值是null,在收到Service的广播前调用toString()会直接崩溃,导致后续的广播接收器注册逻辑都无法执行。先修改这行代码:

Log.d(TAG, "onResume:"+ (currentLocation != null ? currentLocation.toString() : "currentLocation is null"));

二、修复Service无法启动/执行的核心原因

1. 修正Activity onCreate的初始化顺序

你当前的onCreate逻辑有问题:如果isServicesOK()返回false,super.onCreate()和setContentView都不会执行,导致Activity上下文初始化失败,后续的startMyService()自然也无法正常工作。正确的顺序应该是:

@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    
    if (!isServicesOK()) {
        Toast.makeText(this, "Google Play Services不可用,请检查后重试", Toast.LENGTH_LONG).show();
        finish();
        return;
    }
    
    getLocationPermission(); 
    startMyService(); 
}

2. 适配Android 8.0+的后台Service限制

Android 8.0(API 26)及以上版本对后台Service有严格限制,普通后台Service会被系统快速回收。你需要:

  • 在AndroidManifest.xml中添加前台服务权限:
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    
  • 在MyService的onCreate方法中启动前台服务(必须显示一个通知):
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel("location_track", "位置追踪", NotificationManager.IMPORTANCE_LOW);
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(channel);
        
        Notification notification = new NotificationCompat.Builder(this, "location_track")
                .setContentTitle("正在追踪位置")
                .setContentText("应用正在后台获取你的位置")
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .build();
        
        startForeground(1, notification);
    }
    

3. 确保Service在Manifest中注册

检查AndroidManifest.xml是否添加了MyService的注册声明,放在<application>标签内:

<service android:name=".MyService" />

三、完善位置接收与地图更新逻辑

在广播接收器收到位置后,不仅要赋值currentLocation,还要直接更新地图(避免onMapReady时位置还未收到):

mBroadcastReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
        Log.d(TAG, "onReceive: 收到位置数据"); 
        Double latitude = (Double) intent.getExtras().get("latitude");
        Double longitude = (Double) intent.getExtras().get("longitude");
        
        if (latitude != null && longitude != null) {
            currentLocation = new LatLng(latitude, longitude);
            // 收到位置后立即更新地图
            if (mMap != null) {
                moveCamera(currentLocation, DEFAULT_ZOOM);
            }
        } else {
            Log.d(TAG, "onReceive: 经纬度数据为空");
        }
    } 
};

四、MyService的完整实现参考(你可能缺失的部分)

如果你的MyService还没有正确实现位置获取逻辑,这里提供一个基础版本:

public class MyService extends Service {
    private static final String TAG = "MyService";
    private FusedLocationProviderClient mFusedLocationClient;
    private LocationCallback mLocationCallback;

    @Override
    public void onCreate() {
        super.onCreate();
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        
        // 初始化位置回调
        mLocationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                if (locationResult == null) {
                    Log.d(TAG, "onLocationResult: 位置数据为空");
                    return;
                }
                for (Location location : locationResult.getLocations()) {
                    // 发送广播给Activity
                    Intent intent = new Intent("location");
                    intent.putExtra("latitude", location.getLatitude());
                    intent.putExtra("longitude", location.getLongitude());
                    sendBroadcast(intent);
                }
            }
        };
        
        // 启动前台服务(适配Android 8.0+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("location_track", "位置追踪", NotificationManager.IMPORTANCE_LOW);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
            
            Notification notification = new NotificationCompat.Builder(this, "location_track")
                    .setContentTitle("正在追踪位置")
                    .setContentText("应用正在后台获取你的位置")
                    .setSmallIcon(R.drawable.ic_launcher_foreground)
                    .build();
            
            startForeground(1, notification);
        }
        
        // 开始请求位置更新
        requestLocationUpdates();
    }

    private void requestLocationUpdates() {
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setInterval(10000); // 10秒更新一次
        locationRequest.setFastestInterval(5000);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            stopSelf();
            return;
        }
        mFusedLocationClient.requestLocationUpdates(locationRequest, mLocationCallback, Looper.getMainLooper());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY; // 服务被杀死后尝试重启
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mFusedLocationClient != null && mLocationCallback != null) {
            mFusedLocationClient.removeLocationUpdates(mLocationCallback);
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

最后需要检查的点

  1. 确保测试设备的位置服务已开启(GPS或网络定位);
  2. 确认用户已经授予应用位置权限(在系统设置中检查);
  3. Android 10+版本需要额外申请ACCESS_BACKGROUND_LOCATION权限,记得在Manifest中添加并在Activity中申请。

内容的提问来源于stack exchange,提问作者Danail Mihalkov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:31:46