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

求助:需获取定位的Android App启动即崩溃(Logcat无报错)

定位App崩溃问题排查与修复方案

嘿,我帮你找出了几个直接导致App崩溃的核心问题,咱们一步步来解决:

1. 成员变量初始化时机错误导致空指针崩溃

你把TextView txtLocation = findViewById(R.id.txtLocation);放在了类的成员变量位置,这时候Activity还没执行onCreate方法,布局也还没通过setContentView加载完成,findViewById肯定会返回null。后续调用txtLocation.setText()的时候,就会触发NullPointerException直接崩溃。

修复:

把TextView的初始化移到setContentView之后,放在onCreate方法内部:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // 移到这里,布局加载完成后再获取控件
    TextView txtLocation = findViewById(R.id.txtLocation);
    // 后续定位逻辑...
}

2. 权限判断逻辑写反,且未处理权限申请流程

你当前的权限判断条件逻辑有误:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_DENIED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_DENIED)

虽然!= PERMISSION_DENIED等同于== PERMISSION_GRANTED,但这种写法不规范,更重要的是:如果用户没授权权限,你直接跳过了定位逻辑,但没有触发权限申请流程,用户永远无法授权,而且后续也没有重试机制。

修复:

先检查权限是否已授予,未授予则主动申请,申请后处理回调:

// 把LocationListener定义为Activity成员变量,方便权限回调复用
private LocationListener locationListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TextView txtLocation = findViewById(R.id.txtLocation);
    LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            String locationText = String.format("Latitude: %s et longitude: %s", location.getLatitude(), location.getLongitude());
            Log.d("GPS", locationText);
            txtLocation.setText(locationText);
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {}

        @Override
        public void onProviderEnabled(String provider) {}

        @Override
        public void onProviderDisabled(String provider) {}
    };

    // 正确的权限判断逻辑
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED 
        || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        // 已有权限,启动定位
        assert locationManager != null;
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 10, locationListener);
    } else {
        // 无权限,申请定位权限
        ActivityCompat.requestPermissions(this, 
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 
            1001); // 1001是自定义请求码,可自行修改
    }
}

// 重写权限申请回调方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1001) {
        boolean hasGranted = false;
        // 检查是否有至少一个权限被授予
        for (int result : grantResults) {
            if (result == PackageManager.PERMISSION_GRANTED) {
                hasGranted = true;
                break;
            }
        }
        if (hasGranted) {
            // 授权成功,重新启动定位
            LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
            assert locationManager != null;
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 10, locationListener);
        } else {
            // 权限被拒绝,提示用户
            Toast.makeText(this, "需要定位权限才能获取位置信息", Toast.LENGTH_SHORT).show();
        }
    }
}

3. setText传入错误参数类型导致资源找不到崩溃

你写的这行代码有问题:

txtLocation.setText(Log.d("GPS", String.format("Latitude%s et longitude %s", location.getLatitude(), location.getLongitude())));

Log.d()的返回值是int类型(返回日志写入的字符数),而TextView.setText(int)会把这个int当成字符串资源的ID,系统找不到对应ID的资源时,就会抛出Resources$NotFoundException导致崩溃。

修复:

把日志打印和setText分开,先格式化好字符串,再分别处理:

String locationText = String.format("Latitude: %s et longitude: %s", location.getLatitude(), location.getLongitude());
Log.d("GPS", locationText);
txtLocation.setText(locationText);

额外注意事项

  • 别忘了在AndroidManifest.xml中声明定位权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  • 真机测试时要打开GPS,模拟器可以通过开发者选项模拟定位信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:28:48