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

Android API26下仅用GPS无网络获取经纬度及代码问题排查

Hey there! Let's break down the issues in your code and fix it to meet your requirement of getting location only via GPS (no internet/GPRS) for API 26.

Key Issues in Your Current Code

  1. Unwanted Network Location Logic
    Your GPSTracker still includes code for NETWORK_PROVIDER (checking network status, requesting network updates, getting network-based last known location). This goes against your "no network" requirement and might prioritize network over GPS.

  2. Missing Runtime Permission Handling
    API 26 (Android 8.0) falls under the API 23+ range where ACCESS_FINE_LOCATION is a dangerous permission. You need to request this permission at runtime—your current code skips this, which will cause location requests to fail silently.

  3. Incomplete GPS Location Handling
    You only fetch getLastKnownLocation() for GPS, which can be null (e.g., first app launch with no prior GPS fix). Also, your onLocationChanged() method is empty, so you won't receive real-time GPS updates when they become available.

  4. Unnecessary Service Inheritance
    GPSTracker extends Service, but you're only using it within an Activity. This adds unnecessary system overhead and redundant lifecycle code that you don't need for foreground GPS requests.


Fixed Code Implementation

1. Updated MainActivity.java (with Permission Handling)

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private Button GetLocation;
    private TextView coor;
    private GPSTracker gps;
    private static final int REQUEST_LOCATION_PERMISSION = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GetLocation = findViewById(R.id.GetLocation);
        coor = findViewById(R.id.text);

        // Initialize GPS tracker with callback for real-time updates
        gps = new GPSTracker(MainActivity.this, new GPSTracker.GPSLocationListener() {
            @Override
            public void onLocationReceived(Location location) {
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();
                coor.append("\n" + latitude + ", " + longitude);
            }

            @Override
            public void onGPSDisabled() {
                gps.showSettingsAlert();
            }
        });

        GetLocation.setOnClickListener(view -> {
            // Check for location permission first
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        REQUEST_LOCATION_PERMISSION);
            } else {
                // Permission granted, start GPS fetch
                if (gps.canGetLocation()) {
                    Location lastKnownLocation = gps.getLastKnownLocation();
                    if (lastKnownLocation != null) {
                        double latitude = lastKnownLocation.getLatitude();
                        double longitude = lastKnownLocation.getLongitude();
                        coor.append("\n" + latitude + ", " + longitude);
                    } else {
                        coor.append("\nWaiting for GPS fix...");
                    }
                    gps.startGPSUpdates();
                } else {
                    gps.showSettingsAlert();
                }
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_LOCATION_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Retry location fetch after permission is granted
                if (gps.canGetLocation()) {
                    Location lastKnownLocation = gps.getLastKnownLocation();
                    if (lastKnownLocation != null) {
                        double latitude = lastKnownLocation.getLatitude();
                        double longitude = lastKnownLocation.getLongitude();
                        coor.append("\n" + latitude + ", " + longitude);
                    }
                    gps.startGPSUpdates();
                } else {
                    gps.showSettingsAlert();
                }
            } else {
                coor.append("\nLocation permission is required to get GPS data");
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Stop GPS updates to save battery
        gps.stopUsingGPS();
    }
}

2. Rewritten GPSTracker.java (GPS-Only Logic)

import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.provider.Settings;
import android.app.AlertDialog;
import android.content.DialogInterface;

public class GPSTracker implements LocationListener {

    private final Context mContext;
    private GPSLocationListener gpsCallback;
    private LocationManager locationManager;
    private Location lastKnownLocation;
    private boolean isGPSEnabled;
    private boolean canGetLocation;

    // Minimum distance to trigger update (10 meters)
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
    // Minimum time between updates (30 seconds)
    private static final long MIN_TIME_BW_UPDATES = 1000 * 30;

    // Callback to notify Activity of location changes
    public interface GPSLocationListener {
        void onLocationReceived(Location location);
        void onGPSDisabled();
    }

    public GPSTracker(Context context, GPSLocationListener callback) {
        this.mContext = context;
        this.gpsCallback = callback;
        initLocationManager();
    }

    private void initLocationManager() {
        locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
        checkGPSStatus();
    }

    private void checkGPSStatus() {
        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        canGetLocation = isGPSEnabled;
        if (!isGPSEnabled) {
            gpsCallback.onGPSDisabled();
        }
    }

    public void startGPSUpdates() {
        if (isGPSEnabled && locationManager != null) {
            try {
                locationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES,
                        this);
                lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            } catch (SecurityException e) {
                e.printStackTrace();
            }
        }
    }

    public Location getLastKnownLocation() {
        return lastKnownLocation;
    }

    public boolean canGetLocation() {
        return canGetLocation;
    }

    public void stopUsingGPS() {
        if (locationManager != null) {
            locationManager.removeUpdates(this);
        }
    }

    public void showSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
        alertDialog.setTitle("GPS Settings");
        alertDialog.setMessage("GPS is disabled. Do you want to enable it?");
        alertDialog.setPositiveButton("Settings", (dialog, which) -> {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
        });
        alertDialog.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
        alertDialog.show();
    }

    @Override
    public void onLocationChanged(Location location) {
        // Update last known location and notify Activity
        lastKnownLocation = location;
        if (gpsCallback != null) {
            gpsCallback.onLocationReceived(location);
        }
    }

    @Override
    public void onProviderDisabled(String provider) {
        if (provider.equals(LocationManager.GPS_PROVIDER)) {
            isGPSEnabled = false;
            canGetLocation = false;
            gpsCallback.onGPSDisabled();
        }
    }

    @Override
    public void onProviderEnabled(String provider) {
        if (provider.equals(LocationManager.GPS_PROVIDER)) {
            isGPSEnabled = true;
            canGetLocation = true;
            startGPSUpdates();
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // Optional: Handle GPS status changes (e.g., out of service)
    }
}

3. Required Permissions in AndroidManifest.xml

Add these lines inside the <manifest> tag:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" android:required="true" />

Key Improvements

  • GPS-Only Logic: All network provider code is removed, ensuring no internet/GPRS is used.
  • Runtime Permissions: Proper handling of ACCESS_FINE_LOCATION for API 23+.
  • Real-Time Updates: onLocationChanged() is implemented to receive live GPS fixes.
  • Battery Optimization: GPS updates are stopped in onDestroy() to save power.
  • User Feedback: Clear alerts for disabled GPS and permission denial.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:32:00