Android MapView: Event for animateTo is finished? - android

Are there some kind events for animateTo() is finished in android's MapView?
I don't mean manual scrolls, I mean animateTo()-calls from my code or animateTo()-calls causing by changing myLocation if myLocation is enabled?
Thank you

Yes, there is an animateTo that takes a Runnable parameter. You can use this in this manner:
mapController.animateTo(geoPoint,
new Runnable() {
#Override
public void run() {
// your code
}
});

Related

Android GoogleMaps slow onMapClick response

I set a click listener (GoogleMap.OnMapClickListener) for GoogleMap object in the onMapReady() method like this.
#Override
public void onMapReady(GoogleMap map) {
addClickListener(map);
}
Here is the addClickListener():
private void addClickListener(GoogleMap map) {
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
Log.d("ON_MAP_CLICK", "1. OnMapClick called");
handleOnMapClick(point);
}
});
}
Since I set the map ready in the onMapReady method it is logical that I also add the click listener there.
The problem is that the delay for clicking on the map and the code to register that click is around 1 second while is should be instant.
Problem: The problem is not the time it takes to call addClickListener(GoogleMap) but the time that onMapClick() registers a click on the map (around 1 second).
Why is it so slow?
I am using GoogleMap V2
Thanks!
It is obvious that addClickListener method is called after 1 second because onMapReady call back will called only after intializing the map. So it take some delay initially for calling your addClickListener method.
So you will observe this delay only for the first time not all the time and it is working as like it is expected, No changes required in your code
onMapReady will call after the map is initialized, i had a project that took a while to load the map making all the functions "slow".
You can try to load the map earlier to prevent that by adding this to the Splashscreen or Activity.
new Thread(new Runnable() {
#Override
public void run() {
try {
MapView mv = new MapView(getApplicationContext());
mv.onCreate(null);
mv.onPause();
mv.onDestroy();
}catch (Exception ignored){
}
}
}).start();

How to detect moveCamera is finished on the Google map service?

I want to take a snapshot when moveCamera is finished.
I used both onCamerachange() and onMapLoaded() functions to Googlemap object,
But this callback handler's timing is not fit on my intention.
I want to move camera to what I want, and when loading map is finished, want to take a screnshot.
Who do you guys know about how can I do?
Thank you.
====================================================
+MYSOLUTION
Actually, I want to implement tilesloaded() call back function that is supported on the google map API of the javascript.
But, as a result, there is no function which is completely accomplished that function.
OnMapLoaded() callback function is just invoked once when the map is loaded first.
OnCameraChanged() or OnCancallableCallback is invoked before all the tiles are loaded.
So I implemented like below source code
...
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10), this);
...
#Override
public void onFinish() {
mapFragment.getMapAsync(this);
}
..
#Override
public void onMapReady(GoogleMap googleMap) {
// TODO Auto-generated method stub
mMap = googleMap;// Add a marker in Sydney and move the camera
mMap.setOnMapLoadedCallback(this);
}
Now, when the camera is moved, onMapLoaded() is always invoked.
Thank you everybody.
You can implement this:
mMap.animateCamera(CameraUpdateFactory.zoomTo(16), 3000, new GoogleMap.CancelableCallback() {
#Override
public void onFinish() {
//Here you can take the snapshot or whatever you want
}
#Override
public void onCancel() {
}
});
The most detailed form of this method, GoogleMap.animateCamera(cameraUpdate, duration, callback), offers three arguments:
cameraUpdate
The CameraUpdate describing where to move the camera.
callback
An object that implements GoogleMap.CancellableCallback. This generalized interface for handling tasks defines two methods onCancel() and onFinished(). For animation, the methods are called in the following circumstances:
onFinish()
Invoked if the animation goes to completion without interruption.
onCancel()
Invoked if the animation is interrupted by calling stopAnimation() or starting a new camera movement.
Alternatively, this can also occur if you call GoogleMap.stopAnimation().
Source: Google Maps Android API Guides
So you are definitely in the right area by using the onCameraChange() and onMapLoaded() callback. The best way to handle this would be to handle your screenshot in the onMapLoaded() function.
Also, remember to use the newest libraries, and the support libraries when instantiating your map fragment. This is very important.
So:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...All of the other important things you have here
//Instantiate the map object using the support library
map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
map.getMapAsync(this);
//Add the callback to your map object
map.setOnMapLoadedCallback(this);
}
#Override
public void onMapLoaded(){
//Perform screenshot here
}
EDIT
Here is code for a handler, complete with comments.
#Override
public void onCameraChange(){
//Constant for our time. I would put this below your class declaration
private static final int DELAY_TIME_IN_MILLI = 3000;
//Here is the handler for waiting
mMap.postDelayed(new Runnable() {
//This function runs after the time allotted below
#Override
public void run() {
//Call your screenshot function here
takeScreenShot();
}
},DELAY_TIME_IN_MILLI); //Our delay
}

Android maps v2 becomes low quality when map area is automatically moved

I am simulating a car moving on a pre-recorded path on Android maps v2. When I zoom on the path by hand, it works great, but when I move the camera over the path with mMap.animateCamera(), it doesn't load the visible map area, I only get a very pixelated, low quality map. If I touch the screen and move the map or zoom a little, then it loads again this part.
How can I achieve, that it always loads clearly the visible part?
EDIT:
I added an example image: this is what I see when I don't touch the map. After I touch it, it becomes clear (similar to the bottom left part).
EDIT2:
I have an idea, that this is because Google want's to prevent the map to be cached by quickly moving the camera over an area. Is it possible, that this is the cause of this issue? (The map is showing Budapest, Hungary, which part of the map you can not download for offline use...) But here I only want to show the animation and place markers, I only need the visible area to be cached - are there any way to workaround this behaviour?
EDIT3:
The animation code:
new Thread(new Runnable() {
#Override
public void run() {
// ... Calculating and sending new location, in an infinite loop with sleeps for timing
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
}
});
}
}).start();
Finally found a solution. I was able to recreate your problem using the code you provided. I replaced your code with the following and it worked for me.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// ... Calculating and sending new location, in an infinite loop with sleeps for timing
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
}
});
}
}, 0, 2000);
Just remove your code for sleeping and replace the last argument in scheduleAtFixedRate (the 2000) with whatever value you were using for sleeping.
I had the same issue. Since it did not happen when not animating the camera, it had to be something related to that.
Apperently the camera has to be able to finish its operation, before it will update the background/roads etc.
Since my app updates the position every second and the map needs about 2 seconds to complete I end up with pixelated roads and no surroundings at all.
The solution is to use one of overloads of animateCamera:
public final void animateCamera (CameraUpdate update, int durationMs,
GoogleMap.CancelableCallback callback)
Moves the map according to the update with an animation over a
specified duration, and calls an optional callback on completion. See
CameraUpdateFactory for a set of updates.
I used for my case a duration of 900msec, so the animation is done before it receives a new location.
To get the callback to work you need to implement GoogleMap.CancelableCallback to your class. This requires you to add two overrides:
#Override
public void onFinish() {
}
#Override
public void onCancel() {
}
They are not required to get the problem solved, altough you are free to add extra logic there.
The call to update the camera can look like this:
cameraPosition = new CameraPosition.Builder()
.target(current)
.zoom(zoomLevel)
.bearing(bearing)
.tilt(tilt)
.build();
CameraUpdate update = CameraUpdateFactory.newCameraPosition(cameraPosition);
map.animateCamera(update, 900, this);

Blinking marker in android Google maps v2

After long search on how to blink a marker i came up with this code in my project using google maps v2. Here is the code..
MyMarker = map.addMarker(new MarkerOptions().position(current_loc).title(address).snippet(city).
icon(BitmapDescriptorFactory.fromResource(R.drawable.bus4)));
markertimer = new Timer();
markertimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
blinkMarker();
}
});
}
}, 0, 500);
here the blinkMarker method..
private boolean blinkMarker(){
if(marker == true){
current.setVisible(true);
marker = false;
}
else if(marker == false){
current.setVisible(false);
marker = true;
}
return marker;
}
So the above is working fine and the marker is blinking , but my doubt is
will the above code use more memory for blinking?
and i'm using reverse geocoding for getting address, so not able to click the marker when blinking. Please suggest any other way to blink the marker?
Try replacing setVisible with setIcon. When doing that you need to prepare another drawable for icon with the same size as bus4.png, but with all pixels transparent.
Note there is a bug related to setIcon that causes info window to disappear.
As a side note a couple of problems in your code:
Using Timer is wasteful. It uses Thread, which you don't need. Consider using Handler instead.
You (probably) have a memory leak. Timer will not stop working when the Activity is destroyed. You need to cancel it if you don't do that already. If switching to Handler, rember to remove any Runnables or Messages you send.
Usually a Google map is more busy: with many markers. So, you can use Scheduledthreadpoolexecutor with runnable.
Your blinkMarket method could be shorter, like this:
'current.setVisible(!marker)'. I'm affraid that using Timer is not right approach. You can do the same using Handler with postDelayed. If the flashing of marker depends on some condition, that should be repeately checked, than flashing task should not be generated twice.

Android : Make application wait till the current location is found

I'm trying to make my app wait till the current location is found. I've tried few different ways using Threads and all have failed really. I was using wait() and notify() but application just hung and never found the current location.
I amen't using google map api as it is not part of the application. Does anyone have any ideas how to do this or examples.
EDIT : The Thread I was using did not start till the user pressed a button then within onLocationChanged other data is processed e.g. adding the new location to ArrayList, Calculate the distance between the current and last Location as well as the Time taken to get to the new location
You could try starting an AsyncTask in onCreateto get the location. Your default onCreate layout could be a "loading" page, then when your AsyncTask completes successfully with the location it draws your "real" UI.
So if I understand what you want to do correctly, then I would avoid making another thread in onClick(). Instead, onClick() should just request a location, display a progress dialog, and return. Since the work you want to do happens after you receive the new location, I would start an AsyncTask there. Then you finally remove the dialog box (removing it returns control to the user) when the AsyncTask finishes.
Code usually helps, so, I would put this in onCreate() or wherever:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.refresh();
}
});
And put this in your LocationListener:
public void refresh() {
myLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
myDialog = new ProgressDialog(myContext);
myDialog.setIndeterminate(true);
myDialog.show();
}
#Override
public void onLocationChanged(Location location) {
// now do work with your location,
// which your probably want to do in a different thread
new MyAsyncTask().execute(new Location[] { location });
}
And then you need an AsyncTask, which may look like this:
class MyAsyncTask extends AsyncTask<Location, Void, Void> {
#Override
protected Void doInBackground(Location... location) {
// start doing your distance/directions/etc work here
return null;
}
#Override
protected void onPostExecute(Void v) {
// this gets called automatically when you're done,
// so release the dialog box
myDialog.dismiss();
myDialog = null;
}
}

Categories

Resources