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

调用FusedLocationProviderClient.getLastLocation()时空指针崩溃求助

问题诊断与修复

崩溃原因

报错java.lang.NullPointerException: 尝试对空对象引用调用虚拟方法 'com.google.android.gms.tasks.Task com.google.android.gms.location.FusedLocationProviderClient.getLastLocation()',核心原因是fusedLocationClient对象未完成初始化,处于null状态时调用了它的方法。

导致初始化失败的直接原因:MyFirebaseMessagingService中的onCreate方法使用了protected修饰符,而Service类的onCreate方法是public的,系统无法正确触发这个方法,导致fusedLocationClient = LocationServices.getFusedLocationProviderClient(...)这行代码从未执行。

另外,代码中sharedPref也未初始化,后续调用sharedPref.getString()也会触发空指针异常,需要一并修复。

修复步骤

1. 修正Service生命周期方法的修饰符并完成初始化

将onCreate方法的修饰符改为public,同时在该方法中完成fusedLocationClient和sharedPref的初始化:

@Override
public void onCreate() {
    super.onCreate();
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    sharedPref = getSharedPreferences("sendnow_prefs", Context.MODE_PRIVATE);
}

注意:必须添加@Override注解确保重写父类方法,同时调用super.onCreate()保证Service的正常初始化流程。

2. 将网络请求移至后台线程

handleNow方法中的HttpURLConnection网络请求不能在主线程执行(Android 3.0+禁止),需要将这部分逻辑放到子线程中:

if (location != null) {
    // 其他获取数据的逻辑不变
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                URL url = new URL(urlString);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setDoOutput(true);

                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8"));
                writer.write(params);
                writer.flush();
                writer.close();

                // 获取响应码,判断请求是否成功
                int responseCode = urlConnection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "位置数据发送成功");
                } else {
                    Log.e(TAG, "位置数据发送失败,响应码:" + responseCode);
                }
                urlConnection.disconnect();
            } catch (Exception e) {
                Log.e(TAG, "网络请求异常:", e);
            }
        }
    }).start();
}

3. 权限处理优化

当前代码中仅判断权限是否存在,若无权限直接返回。可以考虑在权限缺失时,记录日志提示用户开启权限,或者通过广播通知前端页面发起权限请求。

完整修改后的核心代码片段

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private SharedPreferences sharedPref;
    private static final String TAG = "MyFirebaseMsgService";
    private FusedLocationProviderClient fusedLocationClient;

    @Override
    public void onCreate() {
        super.onCreate();
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        sharedPref = getSharedPreferences("sendnow_prefs", Context.MODE_PRIVATE);
    }

    private void handleNow() {
        Log.d(TAG, "Short lived task is done.");

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.w(TAG, "位置权限未授予,无法获取位置");
            return;
        }

        fusedLocationClient.getLastLocation()
                .addOnSuccessListener(new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        if (location != null) {
                            boolean isCharging = MyFirebaseMessagingService.getCharging(getApplicationContext());
                            float batteryLevel = MyFirebaseMessagingService.getBatteryLevel(getApplicationContext());

                            String username = sharedPref.getString("sendnow_username", "nativestorage_null");
                            String userId = sharedPref.getString("sendnow_user_id", "nativestorage_null");
                            String licenseholderId = sharedPref.getString("sendnow_licenseholder_id", "nativestorage_null");

                            String urlString = "URL"; // 替换为实际服务器地址
                            String params = "username=" + username + "&user_id=" + userId + "&licenseholder_id=" + licenseholderId +
                                    "&altitude=" + location.getAltitude() + "&speed=" + location.getSpeed() + "&location=" +
                                    location.getLatitude() + "," + location.getLongitude() + "&lastGpsUpdate=" + location.getTime() +
                                    "&charging=" + isCharging + "&batteryLevel=" + batteryLevel;

                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        URL url = new URL(urlString);
                                        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                                        urlConnection.setRequestMethod("POST");
                                        urlConnection.setDoOutput(true);

                                        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8"));
                                        writer.write(params);
                                        writer.flush();
                                        writer.close();

                                        int responseCode = urlConnection.getResponseCode();
                                        if (responseCode == HttpURLConnection.HTTP_OK) {
                                            Log.d(TAG, "位置数据发送成功");
                                        } else {
                                            Log.e(TAG, "发送失败,响应码:" + responseCode);
                                        }
                                        urlConnection.disconnect();
                                    } catch (Exception e) {
                                        Log.e(TAG, "网络请求出错:", e);
                                    }
                                }
                            }).start();
                        } else {
                            Log.w(TAG, "获取到的位置为null");
                        }
                    }
                });
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:25:27