1

Я, в настоящее время получаю текущее местоположение устройства (lat, lng) в MapActivity. Теперь я хочу, чтобы пользователь перемещал карту, сохраняя маркер в центре. Это означает, что всякий раз, когда карта перемещается, текущее местоположение будет обновляться. (Правильно?)Android: перетащите карту, удерживая маркер в центре

Я следил за этим android How to move a map under a marker и How to attach a flexible marker on map something like Uber and Lyft?, но не смог понять мою концепцию.

Activity_map.xml (Здесь я добавил ImageView)

<RelativeLayout 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
xmlns:android="http://schemas.android.com/apk/res/android"> 

<fragment 
    android:id="@+id/map" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    class="com.google.android.gms.maps.MapFragment" 
    /> 

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerInParent="true" 
    android:src="@drawable/gps" 
    /> 

</RelativeLayout> 

Мой MapActivity выглядит следующим образом

public class MapActivity extends FragmentActivity implements  OnMapReadyCallback, 
    GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener, 
    LocationListener,GoogleMap.OnInfoWindowClickListener{ 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_map); 
    // int x =_st.jsonArray.length(); 
    if (android.os.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); 

    fragmentOnMap = (FragmentOnMap)getFragmentManager().findFragmentById(R.id.fragment_bottom); 
    getFragmentManager().beginTransaction().hide(fragmentOnMap); 

} 

@Override 
public void onMapReady(GoogleMap googleMap) { 


    //Get Last Known Location and convert into Current Longitute and Latitude 
    final LocationManager mlocManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
    final Location currentGeoLocation = mlocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

    double currentLat = currentGeoLocation.getLatitude(); 
    double currentLon = currentGeoLocation.getLongitude(); 

    LatLng currentLatLng = new LatLng(currentLat,currentLon); 
    //Toast.makeText(this,"Cur Lat" +currentLat+"Lon"+currentLon,Toast.LENGTH_LONG).show(); 

    // Get JSON String and Break it down into individual nodes 
    //double x=_location.getLatitude(); 
    //double y=_location.getLongitude(); 
    json_string = getIntent().getExtras().getString("JSON_DTA"); 
    LatLng latLng = null; 
    try { 
     int count = 0; 
     //jsonObject = new JSONObject(json_string); 
     jsonArray = new JSONArray(json_string); 

     while (count < jsonArray.length()) { 
      JSONObject JO = jsonArray.getJSONObject(count); 
      _id = JO.getInt("id"); 
      _doctorname = JO.getString("doctorname"); 
      _doclat = JO.getString("latitude"); 
      _doclong = JO.getString("longitude"); 

      count++; 

      Double d = Double.parseDouble(_doclat); 
      Double e = Double.parseDouble(_doclong); 
      latLng = new LatLng(d, e); 

      DecimalFormat df = new DecimalFormat("####0.0"); 

      DistanceBetweenPoints distanceBetweenPoints = new DistanceBetweenPoints(); 
      double distance = distanceBetweenPoints.CalculationByDistance(currentLatLng,latLng); 

      double distanceThreshHold = 7 ; 
      if(distance < distanceThreshHold ) 
      { 
       mMap = googleMap; 
       mMap.setOnInfoWindowClickListener(this); 
       MarkerOptions _markeroptions = new MarkerOptions() 
         .position(latLng) 
         .title(_doctorname+": " + df.format(distance) + " KM") 
         .icon(BitmapDescriptorFactory.fromResource(R.drawable.smallest_logo)); 
       mMap.addMarker(_markeroptions); 

       mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 


      } 
      else 
      { 
       mMap = googleMap; 
      } 

    } 


    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 

    //Initialize Google Play Services 
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
     if (ContextCompat.checkSelfPermission(this, 
       Manifest.permission.ACCESS_FINE_LOCATION) 
       == PackageManager.PERMISSION_GRANTED) { 
      buildGoogleApiClient(); 

      mMap.setMyLocationEnabled(true); 

     } 
    } else { 
     buildGoogleApiClient(); 
     mMap.setMyLocationEnabled(true); 
    } 
} 

protected synchronized void buildGoogleApiClient() { 
    mGoogleApiClient = new GoogleApiClient.Builder(this) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API) 
      .build(); 
    mGoogleApiClient.connect(); 
} 
@Override 
public void onConnected(@Nullable Bundle bundle) { 

    mLocationRequest = new LocationRequest(); 

    mLocationRequest.setInterval(1000); 
    mLocationRequest.setFastestInterval(1000); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
    if (ContextCompat.checkSelfPermission(this, 
      Manifest.permission.ACCESS_FINE_LOCATION) 
      == PackageManager.PERMISSION_GRANTED) { 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
    } 

} 

@Override 
public void onConnectionSuspended(int i) { 

} 


@Override 
public void onLocationChanged(Location location) { 

     mLastLocation = location; 
     if (mCurrLocationMarker != null) { 
      mCurrLocationMarker.remove(); 
     } 


     //Place current location marker 
     LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); 
     MarkerOptions markerOptions = new MarkerOptions(); 
     markerOptions.position(latLng); 
     markerOptions.title("Current Position"); 
     markerOptions.draggable(true); 

     markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); 
     mCurrLocationMarker = mMap.addMarker(markerOptions); 


     // Toast.makeText(this, "Current" + latLng, Toast.LENGTH_LONG).show(); 
     String tag = null; 
     Log.d(tag, "lon: " + location.getLongitude() + " ----- lat: " + location.getLatitude()); 


     //move map camera 
     mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
     mMap.animateCamera(CameraUpdateFactory.zoomTo(11)); 


     //stop location updates 
     if (mGoogleApiClient != null) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
     } 


    } 




@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 

} 

public boolean checkLocationPermission(){ 
    if (ContextCompat.checkSelfPermission(this, 
      Manifest.permission.ACCESS_FINE_LOCATION) 
      != PackageManager.PERMISSION_GRANTED) { 

     // Asking user if explanation is needed 
     if (ActivityCompat.shouldShowRequestPermissionRationale(this, 
       Manifest.permission.ACCESS_FINE_LOCATION)) { 

      // Show an expanation to the user *asynchronously* -- don't block 
      // this thread waiting for the user's response! After the user 
      // sees the explanation, try again to request the permission. 

      //Prompt the user once explanation has been shown 
      ActivityCompat.requestPermissions(this, 
        new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
        MY_PERMISSIONS_REQUEST_LOCATION); 


     } else { 
      // No explanation needed, we can request the permission. 
      ActivityCompat.requestPermissions(this, 
        new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
        MY_PERMISSIONS_REQUEST_LOCATION); 
     } 
     return false; 
    } else { 
     return true; 
    } 
} 
@Override 
public void onRequestPermissionsResult(int requestCode, 
             String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case MY_PERMISSIONS_REQUEST_LOCATION: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 
        && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

       // Permission was granted. 
       if (ContextCompat.checkSelfPermission(this, 
         Manifest.permission.ACCESS_FINE_LOCATION) 
         == PackageManager.PERMISSION_GRANTED) { 

        if (mGoogleApiClient == null) { 
         buildGoogleApiClient(); 
        } 
        mMap.setMyLocationEnabled(true); 
       } 

      } else { 

       // Permission denied, Disable the functionality that depends on this permission. 
       Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show(); 
      } 
      return; 
     } 

     // other 'case' lines to check for other permissions this app might request. 
     //You can add here other case statements according to your requirement. 
    } 
} 

Ваша помощь будет оценена. Спасибо.

+0

Просто поместите 'RelativeLayout' над MapFragment с \t android: layout_width = "match_parent" \t android: layout_height = "wrap_content" «ImageView» с изображением маркера (он должен быть как png с прозрачным слоем, а сам маркер должен быть в верхней половине изображения) centerInPare nt = "true" для этого. –

+0

Я сделал это в своем XML-файле, добавил изображение маркера (gps.png) и line centerInParent = "true". Как я могу назвать это в MapActivity? – AIS

+0

В вашем коде нет контейнера для 'android: name =" com.google.android.gms.maps.SupportMapFragment "и нет' RelativeLayout' над ним, а параметр 'centerInParent =" true "' для 'android: id = "@ + id/imageView1" ' –

ответ

10

Наличие карты под ImageView с вашим значком маркера было бы лучшим способом перейти сюда (просто фреймэлей с фрагментом вашей карты и вашим изображением маркера, расположенным сверху, должно работать). Затем вы можете использовать OnCameraIdleListener, который получит обратный вызов, когда движение карты закончится. Так просто установить экземпляр OnCameraIdleListener на карту, чтобы слушать обратные вызовы движения так:

map.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() { 
     @Override 
     public void onCameraIdle() { 
      //get latlng at the center by calling 
      LatLng midLatLng = map.getCameraPosition().target; 
     } 
    }); 
+0

Итак, мой ImageView будет поверх фрагмента карты? – AIS

+0

Да, это должно быть на вершине фрагмента карты. –

+0

и не забудьте его центрировать '(android: layout_gravity =" center ")', если вы используете макет фрейма, иначе он появится в левом верхнем углу. –

4

Try сначала этот макет для вашего Activity_map.xml:

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <fragment 
     android:id="@+id/map" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     class="com.google.android.gms.maps.MapFragment" 
    /> 

    <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:src="@drawable/gps" 
    /> 

</RelativeLayout> 
+0

Отредактировано ... см. Оригинальное сообщение – AIS

+0

1) удалить 'android: orientation =" vertical "' для вашего root 'RelativeLayout' 2) удалить' xmlns: android = "http://schemas.android.com/apk/res/ android "и" xmlns: tools = "http://schemas.android.com/tools" из вашего фрагмента карты; 3) измените 'android: name =" com.google.android.gms.maps.SupportMapFragment "на' class = "com.google.android.gms.maps.SupportMapFragment" 'как указано [здесь] (https: // developers.google.com/android/reference/com/google/android/gms/maps/SupportMapFragment). Это должно помочь. –

+0

Не использовать xmlns: android = "http://schemas.android.com/apk/res/android"> дал ошибку ..hence there there – AIS

Смежные вопросы