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

Android Studio获取位置真机失效求助(模拟器正常)

安卓定位真机无法运行的解决方案

1. 补全权限申请的回调处理

当前代码仅在onCreate中发起权限申请,但未处理用户授权后的结果。如果用户拒绝权限,后续点击按钮调用getLocation()时仍会触发权限异常,且无任何提示。

修改步骤:

  • 添加权限回调方法,处理用户授权结果:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 100) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 权限已授予,可正常执行定位
        } else {
            Toast.makeText(this, "需要定位权限才能获取位置信息", Toast.LENGTH_SHORT).show();
        }
    }
}
  • 在getLocation()开头再次校验权限,避免无权限时执行定位逻辑:
@SuppressLint("MissingPermission")
private void getLocation() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        Toast.makeText(this, "请先授予定位权限", Toast.LENGTH_SHORT).show();
        return;
    }
    try {
        locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,5,MainActivity.this);
    }catch (Exception e){
        e.printStackTrace();
    }
}

2. 避免仅依赖GPS定位源

真机环境下(尤其是室内)GPS信号可能极弱甚至无信号,仅依赖GPS_PROVIDER会导致无法获取位置。建议同时启用网络定位,或直接使用Google推荐的FusedLocationProviderClient(适配性更强、稳定性更高)。

方案A:同时启用GPS与网络定位

修改getLocation()方法:

@SuppressLint("MissingPermission")
private void getLocation() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        Toast.makeText(this, "请先授予定位权限", Toast.LENGTH_SHORT).show();
        return;
    }
    try {
        locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
        // 同时监听GPS和网络定位源
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,5,this);
        }
        if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,5000,5,this);
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}

方案B:切换到FusedLocationProviderClient(推荐)

LocationManager是较旧的API,FusedLocationProviderClient整合了多种定位源,适配性更强。

  1. 在build.gradle中添加依赖:
implementation 'com.google.android.gms:play-services-location:21.0.1'
  1. 修改定位实现代码:
private FusedLocationProviderClient fusedLocationClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView_location = findViewById(R.id.text_location);
    button_location = findViewById(R.id.button_location);
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

    // 保留原权限申请逻辑...

    button_location.setOnClickListener(v -> getLocationWithFused());
}

private void getLocationWithFused() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        Toast.makeText(this, "请先授予定位权限", Toast.LENGTH_SHORT).show();
        return;
    }
    fusedLocationClient.getLastLocation()
            .addOnSuccessListener(location -> {
                if (location != null) {
                    updateLocationUI(location);
                } else {
                    // 无缓存位置,请求实时更新
                    LocationRequest locationRequest = LocationRequest.create();
                    locationRequest.setInterval(5000);
                    locationRequest.setFastestInterval(5000);
                    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

                    fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
                }
            })
            .addOnFailureListener(e -> {
                e.printStackTrace();
                Toast.makeText(this, "定位失败", Toast.LENGTH_SHORT).show();
            });
}

private LocationCallback locationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(LocationResult locationResult) {
        if (locationResult == null) return;
        for (Location location : locationResult.getLocations()) {
            updateLocationUI(location);
            fusedLocationClient.removeLocationUpdates(this);
        }
    }
};

private void updateLocationUI(Location location) {
    Toast.makeText(this, location.getLatitude() + "," + location.getLongitude(), Toast.LENGTH_SHORT).show();
    try {
        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
        if (addresses != null && !addresses.isEmpty()) {
            String address = addresses.get(0).getAddressLine(0);
            textView_location.setText(address);
        } else {
            textView_location.setText("无法获取地址信息");
        }
    } catch (Exception e) {
        e.printStackTrace();
        textView_location.setText("地址解析失败");
    }
}

3. 检测并引导用户开启系统位置服务

真机上用户可能未开启系统位置服务,导致定位失败。添加检测逻辑:

private boolean isLocationEnabled() {
    LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) 
            || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}

// 在getLocation()中调用
if (!isLocationEnabled()) {
    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    startActivity(intent);
    Toast.makeText(this, "请开启位置服务", Toast.LENGTH_SHORT).show();
    return;
}

4. 完善Geocoder的空值处理

Geocoder在无网络或部分机型上可能返回null/空列表,直接调用addresses.get(0)会崩溃,需添加判空逻辑(上述FusedLocation方案已包含该处理)。


内容的提问来源于stack exchange,提问作者Sanjith Kumar M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 13:20:33