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

Android获取用户当前位置并在MapView添加标记问题求助

Hey Paul, let's break down why your current location marker isn't working and fix it properly.

a) Why Your Code Isn't Working

Here are the key issues in your current implementation:

  • Unused & Deprecated API: You declared GoogleApiClient but never initialized or used it. Worse, this API is deprecated—Google recommends using FusedLocationProviderClient for location updates now.
  • Unconnected Location Callback: Your onLocationChanged method is custom, but you never registered it with the system. Android won't automatically call this method unless you set up a location listener.
  • Incomplete Permission Handling: You request location permissions in onCreate, but you don't handle the user's response (allow/deny) with onRequestPermissionsResult. If the user grants permission after your initial request, your code won't trigger a location refresh.
  • No Location Update Request: Even if permissions are granted, you never tell the system you want to receive location data. There's no code to request periodic or one-time location updates.
  • Missing "My Location" Setup: You didn't enable the built-in "My Location" layer on the map (via mMap.setMyLocationEnabled(true)), which is the simplest way to show the user's current position, or implement logic to add a marker once you have location data.

b) Fixed Implementation

Here's the revised code with all issues addressed. I've added comments to explain each change:

import android.Manifest;
import android.content.Intent;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

public class fthactivity extends AppCompatActivity implements OnMapReadyCallback {
    private GoogleMap mMap;
    private FusedLocationProviderClient fusedLocationClient;
    private LocationCallback locationCallback;
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 3;

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

        // Initialize modern location API client
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

        // Set up callback to handle incoming location updates
        locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(@NonNull LocationResult locationResult) {
                if (locationResult == null) {
                    return;
                }
                // Get latest location and update map if available
                Location location = locationResult.getLastLocation();
                if (location != null && mMap != null) {
                    updateUserLocationMarker(location);
                }
            }
        };

        // Initialize map fragment
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.fthmap);
        mapFragment.getMapAsync(this);

        // Phone dialer button logic (unchanged)
        findViewById(R.id.fthphone).setOnClickListener(v -> dialContactPhone("1234567890"));

        // Web link button logic (unchanged)
        Button btn = findViewById(R.id.fthweb);
        btn.setOnClickListener(v -> {
            Intent myWebLink = new Intent(Intent.ACTION_VIEW);
            myWebLink.setData(Uri.parse("http://google.ca/"));
            startActivity(myWebLink);
        });

        // Check location permissions on launch
        checkLocationPermissions();
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add your fixed marker (unchanged)
        LatLng fthloc = new LatLng(51.036585, -114.066152);
        mMap.addMarker(new MarkerOptions().position(fthloc).title("Certain Location"));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(fthloc, 18.0f));

        // Re-check permissions after map is ready to enable location features
        checkLocationPermissions();
    }

    private void checkLocationPermissions() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PERMISSION_GRANTED) {
            // Request permission if not granted
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    LOCATION_PERMISSION_REQUEST_CODE);
        } else {
            // Permissions granted: enable built-in location dot and request updates
            if (mMap != null) {
                mMap.setMyLocationEnabled(true); // Shows blue dot for current location
            }
            startLocationUpdates();
        }
    }

    private void startLocationUpdates() {
        // Configure location update settings
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setInterval(10000); // Update every 10 seconds
        locationRequest.setFastestInterval(5000); // Fastest allowed update interval
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        // Request location updates (only if permissions are granted)
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PERMISSION_GRANTED) {
            fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
        }
    }

    private void updateUserLocationMarker(Location location) {
        LatLng userLoc = new LatLng(location.getLatitude(), location.getLongitude());
        // Add custom marker for user's current location
        mMap.addMarker(new MarkerOptions().position(userLoc).title("Your Location"));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLoc, 18.0f));
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
                // Permission granted: set up location features
                checkLocationPermissions();
            } else {
                // Permission denied: add logic here (e.g., show a toast explaining why permission is needed)
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Stop location updates when activity is paused to save battery
        fusedLocationClient.removeLocationUpdates(locationCallback);
    }

    @Override
    protected void onResume() {
        super.onResume();
        // Resume location updates when activity is active again
        checkLocationPermissions();
    }

    private void dialContactPhone(final String phoneNumber) {
        startActivity(new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumber, null)));
    }
}

Additional Required Step: Update AndroidManifest.xml

Make sure you've added these permissions to your manifest file (inside the <manifest> tag, outside <application>):

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- For Android 10+, add this if you need background location (optional for your use case) -->
<!-- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> -->

Key Improvements Explained:

  • Modern Location API: Uses FusedLocationProviderClient instead of deprecated GoogleApiClient for reliable, optimized location data.
  • Proper Callback Registration: The LocationCallback is connected to the system, so it will receive location updates automatically.
  • Complete Permission Flow: onRequestPermissionsResult handles user choices and triggers location setup if permission is granted.
  • Lifecycle-Aware Updates: Location updates stop when the activity is paused (saves battery) and resume when it's active again.
  • Built-in Location Layer: Enables the default blue dot for current location (you can keep this or use only your custom marker, or both).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:07:35