代码之家  ›  专栏  ›  技术社区  ›  ttattini

使用MapsActivity中的当前位置填充标记

  •  0
  • ttattini  · 技术社区  · 6 年前

    我已经成功开发了一个程序,可以在用户旅行时更新标记,但是文本只会显示“当前位置”

    我还想在点击时向用户填充地址信息。下面是一些代码片段,强调了我的意图,如有任何帮助,将不胜感激!非常感谢。

    这是我目前的地图活动。JAVA

     import android.Manifest;
        import android.content.pm.PackageManager;
        import android.graphics.Camera;
        import android.location.Address;
        import android.location.Geocoder;
        import android.location.Location;
        import android.os.Build;
        import android.support.annotation.NonNull;
        import android.support.annotation.Nullable;
        import android.support.v4.app.ActivityCompat;
        import android.support.v4.app.FragmentActivity;
        import android.os.Bundle;
        import android.support.v4.content.ContextCompat;
        import android.view.View;
        import android.widget.EditText;
        import android.widget.TextView;
        import android.widget.Toast;
    
        import com.google.android.gms.common.ConnectionResult;
        import com.google.android.gms.common.api.GoogleApiClient;
        import com.google.android.gms.location.LocationListener;
        import com.google.android.gms.location.LocationRequest;
        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.BitmapDescriptorFactory;
        import com.google.android.gms.maps.model.LatLng;
        import com.google.android.gms.maps.model.Marker;
        import com.google.android.gms.maps.model.MarkerOptions;
    
        import java.io.IOException;
        import java.util.List;
    
        public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
                GoogleApiClient.ConnectionCallbacks,
                GoogleApiClient.OnConnectionFailedListener,
                LocationListener {
    
            private GoogleMap mMap;
            private GoogleApiClient client;
            private LocationRequest locationRequest;
            private Location lastLocation;
            private Marker currentLocationMarker;
            public static final int REQUEST_LOCATION_CODE = 99;
            TextView textView;
            Geocoder geocoder;
            List<Address> addresses;
    
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_maps);
    
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                    checkLocationPermission();
                }
    
                // Obtain the SupportMapFragment and get notified when the map is ready to be used.
                SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                        .findFragmentById(R.id.map);
                mapFragment.getMapAsync(this);
            }
    
            @Override
            public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
               switch(requestCode)
               {
                   case REQUEST_LOCATION_CODE:
                       if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
                       {
                           //permission is granted
                           if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                               if(client == null){
                                   buildGoogleApiClient();
                               }
                               mMap.setMyLocationEnabled(true);
                           }
                       }
                   else  {
                           Toast.makeText(this, "Permission Denied!", Toast.LENGTH_LONG).show();
                           //Permission is denied
                       }
                       return;
               }
            }
    
            @Override
            public void onMapReady(GoogleMap googleMap) {
                Toast.makeText(this, "Click Icon in Top right for Current Location", Toast.LENGTH_LONG).show();
                mMap = googleMap;
                LatLng Phoenix = new LatLng(33.6056711, -112.4052378);
                mMap.addMarker(new MarkerOptions().position(Phoenix).title("Default Location: Phoenix, AZ"));
                mMap.moveCamera(CameraUpdateFactory.newLatLng(Phoenix));
    
    
               if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    buildGoogleApiClient();
                    mMap.setMyLocationEnabled(true);
    
                }
            }
    
                protected synchronized void buildGoogleApiClient(){
                     client = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
    
                     client.connect();
                }
    
    
            @Override
    public void onLocationChanged(Location location) {
        lastLocation = location;
    
        if(currentLocationMarker != null){
            currentLocationMarker.remove();
     }
    
     LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
     MarkerOptions markerOptions = new MarkerOptions();
     markerOptions.position(latLng);
     markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
    
    
        textView = (TextView) findViewById(R.id.textView);
        geocoder = new Geocoder(this, Locale.getDefault());
    
        try {
            addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
    
     String address = addresses.get(0).getAddressLine(0);
     String area = addresses.get(0).getLocality();
     String city = addresses.get(0).getAdminArea();
     String country = addresses.get(0).getCountryName();
     String postalcode = addresses.get(0).getPostalCode();
    
     String fullAddress = address+", "+area+", " +city+", " + country+ "," + postalcode;
    
            textView.setText(fullAddress);
    
     } catch (IOException e) {
     e.printStackTrace();
     }
    
    
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomBy(10));
    
        if(client != null){
     LocationServices.FusedLocationApi.removeLocationUpdates(client, this);
     }
    
    }
    
            @Override
            public void onConnected(@Nullable Bundle bundle) {
                locationRequest = new LocationRequest();
                locationRequest.setInterval(1000);
                locationRequest.setFastestInterval(1000);
                locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    
                if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    
                    LocationServices.FusedLocationApi.requestLocationUpdates(client, locationRequest, this);
                }
            }
    
            public boolean checkLocationPermission(){
                if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
                    {
                        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_CODE);
                    }
                    else {
                        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_CODE);
                    }
                    return false;
                }
                else
                    return true;
            }
    
            public void onZoom(View view) {
                if (view.getId() == R.id.zoomIn) {
                    mMap.animateCamera(CameraUpdateFactory.zoomIn());
                }
                if (view.getId() == R.id.zoomOut) {
                    mMap.animateCamera(CameraUpdateFactory.zoomOut());
                }
            }
    
            public void ChangeType(View view) {
                if (mMap.getMapType() == GoogleMap.MAP_TYPE_NORMAL) {
                    mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                    Toast.makeText(this, "Satellite Map Style", Toast.LENGTH_LONG).show();
    
                }
                else if (mMap.getMapType() == GoogleMap.MAP_TYPE_SATELLITE) {
                    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                    Toast.makeText(this, "Hybrid Map Style", Toast.LENGTH_LONG).show();
                }
                else if (mMap.getMapType() == GoogleMap.MAP_TYPE_HYBRID) {
                    mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
                    Toast.makeText(this, "Terrain Map Style", Toast.LENGTH_LONG).show();
                }
                else if (mMap.getMapType() == GoogleMap.MAP_TYPE_TERRAIN) {
                    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                    Toast.makeText(this, "Normal Map Style", Toast.LENGTH_LONG).show();
                }
                }
    
    
            @Override
            public void onConnectionSuspended(int i) {
    
            }
    
            @Override
            public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    
            }
        }
    

    以下是相应的xml文件:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/layout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/img_header" >
    
        <fragment
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.SupportMapFragment" />
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:text="Test"
            android:layout_centerHorizontal="true"
            android:textSize="22sp"/>
    </RelativeLayout>
    

    堆栈跟踪

    05-17 09:15:49.411 15842-15842/edu.phoenix.mbl402.week3apptt2163 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: edu.phoenix.mbl402.week3apptt2163, PID: 15842
    java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at edu.phoenix.mbl402.week3apptt2163.MapsActivity.onLocationChanged(MapsActivity.java:139)
        at com.google.android.gms.internal.location.zzay.notifyListener(Unknown Source:4)
        at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(Unknown Source:8)
        at com.google.android.gms.common.api.internal.ListenerHolder$zza.handleMessage(Unknown Source:16)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
    

    最终编辑:

    @Override
    public void onLocationChanged(Location location) {
        lastLocation = location;
    
        if(currentLocationMarker != null){
            currentLocationMarker.remove();
        }
    
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title(getAddressForLatLng());
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
    
        currentLocationMarker = mMap.addMarker((markerOptions));
    
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    
    }
    
    
    public static Address getAddressForLatLng(Context context, LatLng location) {
        final int MAX_RESULTS = 1;
        final Geocoder geocoder = new Geocoder(context, Locale.getDefault());
        Address address = new Address(Locale.getDefault());
        try {
            final List<Address> addresses = geocoder.getFromLocation(location.latitude, location.longitude, MAX_RESULTS);
            if (addresses != null && addresses.size() != 0) {
                address = addresses.get(0);
            }
            return address;
        } catch (IOException e) {
            Log.e("Geocoding", "Geocoding was not possible");
        }
        return address;
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Szychan    6 年前

    您不必在每次位置更新时从地图上删除标记。重用现有的标记存储引用。

    Marker mMarker = mMap.addMarker(new MarkerOptions()......)

    创建mMarkerObject后,刷新其在OnLocationChanged中的位置

    mMarker.setTitle() mMarker.setPosition(latLng);

    如果出于某种原因,您仍想实施点击操作 在MarkerclickListener上为您的主要活动添加界面,覆盖OnMarkerClick,并使用showInfoWindow或其他工具:)

    编辑:对于geocrush,请尝试以下操作->

    public static Address getAddressForLatLng(final Context context, final LatLng location) {
        final int MAX_RESULTS = 1;
        final Geocoder geocoder = new Geocoder(context, Locale.getDefault());
        Address address = new Address(Locale.getDefault());
        try {
            final List<Address> addresses = geocoder.getFromLocation(location.latitude, location.longitude, MAX_RESULTS);
            if (addresses != null && addresses.size() != 0) {
                address = addresses.get(0);
            }
            return address;
        } catch (IOException e) {
            Log.e("Geocoding", "Geocoding was not possible");
        }
        return address;
    }
    

    onLocationChanged()的简化版和更高效版

    @Override
    public void onLocationChanged(Location location) {
    lastLocation = location;
    
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    currentLocationMarker.setPosition(latLng);
    // make sure following setTitle gets String from getAddressForLatLng
    currentLocationMarker.setTitle(getAddressForLatLng(latLng));
    
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    }
    
        2
  •  0
  •   MannerPots    6 年前

    你可以用 reverse geocoding 从纬度和经度获取人类可读的地址字符串。 然后使用该地址作为标记标题,而不是 "Current Location" .
    明确地:

    addresses = geocoder.getFromLocation(
                    location.getLatitude(),
                    location.getLongitude(),
                    // In this sample, get just a single address.
                    1);
    address = adresses[0];
    markerOptions.title(address);
    

    (遗漏了错误处理等,请参见链接)。