问题
I'm trying to update my map so that the map automatically moves to centre the marker. I want it such that if I move around, after 5 seconds, the map will animate itself to move such that the marker is central again.
Here is the code:
public class TrackDifferentLocation extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
LatLng mLatlng;
String json_string;
public static TextView data;
LatLng latLng = null;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Toast.makeText(this, "Tracking location...", Toast.LENGTH_LONG).show();
setContentView(R.layout.activity_track_different_location);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map_fragment);
mapFragment.getMapAsync(this);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//new FetchJSON.execute(); //Not valid syntax
new FetchJSON().execute();
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
Log.i("", "onMapReady()");
displayMarkers();
}
private void displayMarkers(){
if (mMap == null)return;
//If mLatlng is null (as the Async task has not finished, then nothing will happen.
if(mLatlng == null) return;
//The camera and map will then update to the new location with zoom.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLatlng, 17));
mMap.addMarker(new MarkerOptions().position(mLatlng).title(String.valueOf(mLatlng)));
}
//Part of menu see following
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home){
//ends the activity
this.finish();
}
switch (item.getItemId()) {
case R.id.mapTypeNone:
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
break;
case R.id.mapTypeNormal:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.mapTypeTerrain:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case R.id.mapTypeSatellite:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case R.id.mapTypeHybrid:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
class FetchJSON extends AsyncTask<String, Integer, LatLng> {
String JSONStr = "";
String name, address, type = "";
String lat = "";
String lng = "";
String id = "";
//double lat, lng;
int idInt;
double latDouble = -1;
double lngDouble = -1;
protected LatLng doInBackground(String... args) {
//LatLng latLng = null;
try {
//URL url = new URL("https://api.myjson.com/bins/ehzqu");
URL url = new URL("https://api.myjson.com/bins/sv5vm");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
Log.d("BufferedReader: ", String.valueOf(bufferedReader));
String line = "lind";
while (line != null) {
line = bufferedReader.readLine();
JSONStr = JSONStr + line;
}
Log.d("", JSONStr);
JSONObject obj = new JSONObject(JSONStr);
JSONArray array = obj.getJSONArray("server response");
for (int i = 0; i < array.length(); i++) {
JSONObject o = array.getJSONObject(i);
id = o.optString("id");
name = o.optString("name");
address = o.optString("address");
lat = o.optString("lat");
lng = o.optString("lng");
Log.d("lat: ",lat);
latDouble = Double.parseDouble(lat);
lngDouble = Double.parseDouble(lng);
latLng = new LatLng(latDouble, lngDouble);
Log.i("JSON Values", lat + " " + lng);
type = o.optString("type");
}
} catch (Exception ex) {
Log.e(TAG, "FetchJSON --- " + ex.getMessage());
}
return latLng;
}
protected void onPostExecute(LatLng latLng) {
if (latLng != null) {
mLatlng = latLng;
displayMarkers();
}
}
}
}
Please note, for the question I have removed all imports and package.
回答1:
To demonstrate how this can work I have changed the code which is more applicable to your code:
int index = 0;
private void loadLocation() {
new FetchJSON().execute();
startAutoHandler();
}
class FetchJSON extends AsyncTask<String, Integer, LatLng> {
@Override
protected LatLng doInBackground(String... params) {
LatLng latLng = null;
try {
URL url = new URL("https://api.myjson.com/bins/sv5vm");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
String json = stringBuilder.toString();
Log.e(TAG, "Return = " + json);
String lat= "";
String lng= "";
JSONObject obj = new JSONObject(json);
JSONArray array = obj.getJSONArray("server response");
for(int i = 0; i < array.length(); i++){
JSONObject o = array.getJSONObject(i);
lat = o.optString("lat");
lng = o.optString("lng");
}
Log.e(TAG, "Lat = " + lat);
Log.e(TAG, "lng = " + lng);
index++;
double adjustLat = 0.1 * index;
double adjustLng = 0.01 * index;
double latDouble = Double.parseDouble(lat) + adjustLat;
double lngDouble = Double.parseDouble(lng) + adjustLng;
latLng = new LatLng(latDouble, lngDouble);
}
catch (Exception ex) {
Log.e(TAG, "doInBackground --- " + ex.getMessage());
}
return latLng;
}
@Override
protected void onPostExecute(LatLng latLng) {
try{
if(latLng != null){
mLatLng = latLng;
displayMarker();
}
}
catch(Exception ex){
Log.e(TAG, "onPostExecute" + ex.getMessage());
}
}
}
private void displayMarker(){
if(mMap == null) return;
if(mLatLng == null) return;
mMap.clear();
MarkerOptions markerOption = new MarkerOptions();
markerOption.position(mLatLng);
CameraUpdate loc = CameraUpdateFactory.newLatLngZoom(mLatLng, 10.3f);
mMap.animateCamera(loc);
mMap.addMarker(markerOption);
}
Handler mAutoHandler = new Handler();
long delay = 2000l; //this delay is in ms change as needed
private void startAutoHandler(){
try{
Log.e(TAG, "startAutoHandler");
mAutoHandler.postDelayed(mAutoRunnable, delay);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mAutoRunnable = new Runnable() {
@Override
public void run() {
new FetchJSON().execute();
mAutoHandler.postDelayed(mAutoRunnable, delay);
}
};
private void stopAutoHandler(){
mAutoHandler.removeCallbacks(mAutoRunnable);
}
You will need to call stopAutoHandler();
in your onPause()
method. Otherwise it will carry on and can cause some real issues!
来源:https://stackoverflow.com/questions/50438095/how-to-correctly-animate-a-map-created-in-android-studio-to-follow-the-marker