Android Google Maps API v2 onInfoWindowClick triggers on create of activity all listeners - google-maps-markers

Hi i have a map with a lot of markers. When i add the markers to the map i want to add an onInfoWindowClick Listener to each marker with individual data. I want to load an activety with informations of the marker with the onInfoWindowClick Listener.
The code do not work correct. When the activety is created all the listeners are triggered at the same time and when i click on the infoWindow nothing happens.
private void addMarkerToMap(double lat, double lng, String eventTitle,
String eventDiscribtion) {
Marker currentMarker = myMap.addMarker(new MarkerOptions()
.position(new LatLng(lat, lng)).title(eventTitle)
.snippet(eventDiscribtion));
onInfoWindowClick(currentMarker);
}
#Override
public void onInfoWindowClick(Marker marker) {
Intent nextScreen = new Intent(MapsActivity.this,
EventActivity.class);
nextScreen.putExtra("userId", "" + userId);
nextScreen.putExtra("eventId", "" + eventId);
startActivityForResult(nextScreen, 0);
}

You would implement the onclick behavior within your GoogleMap Object (myMap)
myMap.setOnInfoWindowClickListener(
new OnInfoWindowClickListener(){
public void onInfoWindowClick(Marker marker){
Intent nextScreen = new Intent(MapsActivity.this,EventActivity.class);
nextScreen.putExtra("userId", "" + userId);
nextScreen.putExtra("eventId", "" + eventId);
startActivityForResult(nextScreen, 0);
}
}
)

check out this post about how to associate information or objects to markers:
http://bon-app-etit.blogspot.be/2012/12/add-informationobject-to-marker-in.html

Related

Multiple alerts with only one MessagingCenter subscription

I'm developing a sample where Messaging Center send status messeges not coupled from device code to my view models. At this point i used a alert message to notice the event before try in View models.
For it I used a static view instance in my share application constructor (App.xaml) where in view constructor I Subscript the status.
App (shared)
public partial class App : Application
{
#region MasterDetailPage
public static MasterDetailPage MDP;
public static NavigationPage NAV = null;
public static MainView _mainpage;
#endregion
public App ()
{
InitializeComponent();
NAV = new NavigationPage(new StarterView()) { BarBackgroundColor = Color.FromHex("701424"), BarTextColor = Color.White }; ;
MDP = new MasterDetailPage();
MDP.BackgroundColor = Xamarin.Forms.Color.FromHex("701424");
_mainpage = new MainView();
MDP.Master = _mainpage;
MDP.Detail = NAV;
MainPage = MDP;
MainPage.Title = "H2X";
}
(View shared)
public MainView ()
{
InitializeComponent ();
string a="Test";
#region MessegeCenter
MessagingCenter.Subscribe<string,string>("APP", "Message_Received", async (sender,arg) =>
{
string b = a;
a = $"{arg}";
await DisplayAlert("Atenção", a+b, "Ok");
});
#endregion
}
Into the specific platform code (Device - UWP) I create a timer that sends messages after some time instanced in mainpage constructor.
void dispatcherTimer_Tick(object sender, object e)
{
DateTimeOffset time = DateTimeOffset.Now;
TimeSpan span = time - lastTime;
lastTime = time;
//Time since last tick should be very very close to Interval
TimerLog.Text += timesTicked + "\t time since last tick: " + span.ToString() + "\n";
timesTicked++;
if (timesTicked > timesToTick)
{
MessagingCenter.Send<string,string>("APP","Message_Received","MR");
}
}
When I run it, twice alert messages with the same text are opening, but there aren't two subscriptions. The same text give me the information that it was from the same send event.
Where is the problem ? Is there any relationship with my static view ?
Thank you in advance
Guilherme
It is a good practice to always unsubscribe from the MessagingCenter.
MessagingCenter.Unsubscribe<string, string>(this, "Message_Received");
If MessagingCenter is subscribed twice ,then functions will be call twice.

Win10 App - Holding & Releasing the map to manipulate an element on the interface

I working on an UWP (Win10) App with a simple location picker function. The user can drag the map on the wanted location. A basic Pushpin thats always in the center of the Map window acts as the location indicator. It works just like the free location pick in WhatsApp.
To give the user feedback that he is moving the center pin, I want to raise the pin when the user is moving the map and lower it again on release.
Here the simple code to raise the pin (and manipulate the shadow):
private void MyMap_MapHolding(MapControl sender, MapInputEventArgs args)
{
iconSwitch = true;
if(iconSwitch == true) {
centerPin.Margin = new Thickness(0, 0, 0, 60);
centerPinShadow.Opacity = 0.3;
centerPinShadow.Width = 25;
}
But this event doesn't seem to be affected on click & hold or tap & hold. Am I missing something?
FYI: I tried this out with the MyMap_MapTapped(...) method, and it worked just fine, but I need it when the map is dragged not just tapped.
Chees!
I've tested and debugged, MapHolding event can't work by me either. For your purpose, CenterChangedLink event maybe helpful, I've tested it too.
Here is part of my sample code:
RandomAccessStreamReference mapIconStreamReference;
public Maptest()
{
this.InitializeComponent();
myMap.Loaded += MyMap_Loaded;
myMap.MapTapped += MyMap_MapTapped;
myMap.MapHolding += MyMap_MapHolding;
myMap.CenterChanged += MyMap_CenterChanged;
mapIconStreamReference = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/MapPin.png"));
}
private void MyMap_Loaded(object sender, RoutedEventArgs e)
{
myMap.Center =
new Geopoint(new BasicGeoposition()
{
//Geopoint for Seattle
Latitude = 47.604,
Longitude = -122.329
});
myMap.ZoomLevel = 12;
}
private void MyMap_MapTapped(Windows.UI.Xaml.Controls.Maps.MapControl sender, Windows.UI.Xaml.Controls.Maps.MapInputEventArgs args)
{
var tappedGeoPosition = args.Location.Position;
string status = "MapTapped at \nLatitude:" + tappedGeoPosition.Latitude + "\nLongitude: " + tappedGeoPosition.Longitude;
rootPage.NotifyUser( status, NotifyType.StatusMessage);
}
private void MyMap_MapHolding(Windows.UI.Xaml.Controls.Maps.MapControl sender, Windows.UI.Xaml.Controls.Maps.MapInputEventArgs args)
{
var holdingGeoPosition = args.Location.Position;
string status = "MapHolding at \nLatitude:" + holdingGeoPosition.Latitude + "\nLongitude: " + holdingGeoPosition.Longitude;
rootPage.NotifyUser(status, NotifyType.StatusMessage);
}
private void MyMap_CenterChanged(Windows.UI.Xaml.Controls.Maps.MapControl sender, object obj)
{
MapIcon mapIcon = new MapIcon();
mapIcon.Location = myMap.Center;
mapIcon.NormalizedAnchorPoint = new Point(0.5, 1.0);
mapIcon.Title = "Here";
mapIcon.Image = mapIconStreamReference;
mapIcon.ZIndex = 0;
myMap.MapElements.Add(mapIcon);
}
At first I thought, even when the MapHoling event can't work, the Tapped action before holding should handled by MapTapped event, but it is seems this action is ignored. So remember, if a user hold the Map but not move it, nothing will happen.

How to know if Unity UI button is being held down?

I am using Unity 5.2 UI. I am working on a game for iOS. I have a custom keyboard. I want to add the functionality to the del/backspace key so that when i hold the del key for more than 2 secs, it deletes the whole word instead of a single letter, which it deletes on single clicks. How do I achieve that?
Using the UGUI event you'd create a script like the following and attach it to your button:
using UnityEngine;
using UnityEngine.EventSystems;
public class LongPress : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {
private bool isDown;
private float downTime;
public void OnPointerDown(PointerEventData eventData) {
this.isDown = true;
this.downTime = Time.realtimeSinceStartup;
}
public void OnPointerUp(PointerEventData eventData) {
this.isDown = false;
}
void Update() {
if (!this.isDown) return;
if (Time.realtimeSinceStartup - this.downTime > 2f) {
print("Handle Long Tap");
this.isDown = false;
}
}
}

Listview from arrayadapter filled text file always one update behind

I have a listview that I want to update with information from a textfile (rollcall.txt). Each time rollcall.txt is updated I am calling rollcall() (code below). The data is updated correctly in the text file before rollcall() is called, I have checked. The problem I have is that the listview doesnt show the updated entry until the next time I call rollcall() (I.E it always appears to be one update step behind).
Where am I going wrong?
public void rollcall(){
String[] splitdata = null;
try{
File myFile = new File(Environment.getExternalStorageDirectory() + "/rollcall.txt");
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(
new InputStreamReader(fIn));
String aDataRow = "";
String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow + "\n";
}
splitdata = aBuffer.split("`"); //recover the file and split it based on `
myReader.close();
}
catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.logbooklayout, splitdata);
lv1.setAdapter(adapter);
adapter.notifyDataSetChanged(); //called to ensure updated data is refreshed into listview without reload
EDIT: rollcall is called from this method:
public void onClick(View v) {
if (v==badd){
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("ROLLCALL"); //Set Alert dialog title here
alert.setMessage("Enter data: "); //Message here
// Set an EditText view to get user input
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//You will get as string input data in this variable.
// here we convert the input to a string and show in a toast.
add = input.getEditableText().toString();
try {
File myFile = new File(Environment.getExternalStorageDirectory() + "/rollcall.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile, true);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
myOutWriter.append(add);
myOutWriter.append("`"); // ` used to split the file down later in lv section
myOutWriter.close();
fOut.close();
}
catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
} // End of onClick(DialogInterface dialog, int whichButton)
}); //End of alert.setPositiveButton
alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
dialog.cancel();
}
}); //End of alert.setNegativeButton
AlertDialog alertDialog = alert.create();
alertDialog.show();
rollcall();
}//end badd
}
Thanks for the help, I am new to using arrayadapters.
Andy
Short answer to your question is everything in UI thread is asynchronous and unless you somehow manage to freeze/lock the whole application you can't make the rest of your UI wait for your alert to grab the input. So long before you press "OK" button in your alert, your rollcall() method is being called from your onClick() function and whatever is inside your .txt file is being read/displayed on your UI, right behind your alert dialog hanging on for you to press one of the buttons, asynchronously.
Maybe the fastest solution to what you want to achieve is to call your rollcall() function somewhere else, after you confirm that your adapter's feeding data has actually been changed. If you must call it from within onClick() function, without questioning your reasons to do so, you should call it inside the try{} block, right after you close the output stream.
Like this:
try {
File myFile = new File(Environment
.getExternalStorageDirectory() + "/rollcall.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile, true);
OutputStreamWriter myOutWriter = new OutputStreamWriter(
fOut);
myOutWriter.append(add);
myOutWriter.append("`"); // ` used to split the
// file down later
// in lv section
myOutWriter.close();
fOut.close();
rollcall();
}
The reason this "works" is you already declared the listener for your "OK" button and whenever you press it, whatever inside your EditText input will be written on file. In order to make it work as before I think you need superhuman skills to write some text on alert dialog and click on button before rollcall() function is called in the same scope.
Obviously the better way to do update the list view is to be able to use adapter.notifyDataSetChanged() but I believe you should call it somewhere else than where you write on your file and in that case your adapter must be declared outside the scope of rollcall() function.
Anyways in order to show how it all goes on I created a simple(rather ugly) android application and put some logs on where the mysterious stuff is happening:
public class MainActivity extends Activity {
private ListView lv1;
private Button refreshButton;
ArrayAdapter<String> adapter;
String[] splitdata;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
refreshButton = (Button) findViewById(R.id.refreshButton);
lv1 = (ListView) findViewById(R.id.someTextViewId);
refreshButton.setOnClickListener(myButtonhandler);
splitdata = null;
}
View.OnClickListener myButtonhandler = new View.OnClickListener() {
public void onClick(View v) {
Log.d("main", "la noliy");
someFunction();
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void someFunction() {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("ROLLCALL"); // Set Alert dialog title here
alert.setMessage("Enter data: "); // Message here
// Set an EditText view to get user input
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// You will get as string input data in this
// variable.
// here we convert the input to a string and show in
// a toast.
String add = input.getEditableText().toString();
try {
File myFile = new File(Environment
.getExternalStorageDirectory() + "/rollcall.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile, true);
OutputStreamWriter myOutWriter = new OutputStreamWriter(
fOut);
myOutWriter.append(add);
myOutWriter.append("`"); // ` used to split the
// file down later
// in lv section
myOutWriter.close();
fOut.close();
if (splitdata.length > 0) {
rollcall(new String("call from inside"));
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
} // End of onClick(DialogInterface dialog, int
// whichButton)
}); // End of alert.setPositiveButton
alert.setNegativeButton("CANCEL",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
dialog.cancel();
}
}); // End of alert.setNegativeButton
AlertDialog alertDialog = alert.create();
alertDialog.show();
Log.d("someFunction", "before rollcall");
Log.d("someFunction", "location: "
+ Environment.getExternalStorageDirectory().getAbsolutePath());
rollcall(new String("call from outside"));
Log.d("someFunction", "after rollcall");
}// end badd
public void rollcall(String message) {
Log.d("rollcall", message);
try {
File myFile = new File(Environment.getExternalStorageDirectory()
+ "/rollcall.txt");
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(new InputStreamReader(
fIn));
String aDataRow = "";
String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow + "\n";
}
splitdata = aBuffer.split("`"); // recover the file and split it
// based on `
myReader.close();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
int length = splitdata.length;
for (int i = 0; i < length; i++) {
Log.d("rollcall", splitdata[i]);
}
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, splitdata);
lv1.setAdapter(adapter);
}
}
I put a button and an onClickListener to it. The first time you press the button everything is called, listview is updated and your dialog is hanging on your screen for either of the buttons to be pressed:
And you will see a log like this:
07-26 04:09:20.802: D/someFunction(11273): before rollcall
07-26 04:09:20.802: D/someFunction(11273): location: /mnt/sdcard
07-26 04:09:20.802: D/rollcall(11273): call from outside
07-26 04:09:20.802: D/rollcall(11273): some data
07-26 04:09:20.802: D/rollcall(11273): some other data
07-26 04:09:20.812: D/someFunction(11273): after rollcall
You can see that rollcall() has been called from outside and not inside of your try/catch block since there is also another call from there to rollcall(). But when you press the button your try/catch block will do it's job inside your onClick() function and rollcall() will be called afterwards. Hence your listview wil be updated with new data you just entered in the dialog:
Here is the final part of log right after you press "OK" you can see that rollcall() is being called and it can read the new data:
07-26 04:09:46.347: D/rollcall(11273): call from inside
07-26 04:09:46.357: D/rollcall(11273): some data
07-26 04:09:46.357: D/rollcall(11273): some other data
07-26 04:09:46.357: D/rollcall(11273): new data
Finally, I'm sure there are a lot of ugliness in this whole approach to your problem. Bottom line is you need to know that everything happening in the UI thread is asynchronous and no one is waiting for you to enter data inside your dialog in that onClick() function. You should update your listview somewhere else with a more elegant approach in case your application throws an exception for example around that try/catch block. At least maybe you should add a finally{} block at the end of it and update your listview in there even though the try part fails. Hope this answered your question:)
PS. For those who want to try this at home, remember to provide a TextView id from your layout.xml file to the findViewById() function to get the ListView reference in your code, not an actual ListView id. Yeah, I know...
call adapter.notifyDataSetChanged() everytime you update your adapter, then listview will automatically be updated
I suggest you run rollcall as an asychronous task for 2 reasons. First, it will not stop your UI when rollcall() is running.
Second, you will be able to call onPostExecute(Object o) wher you can call `adapter.notifyDataSetChanged(); '

How to use events in GWT Frame

I would like to capture all events within a GWT frame. I've found several ways to do this, but they only return mousemove and mouseout events. I also need keypresses, input, etc. The goal is to capture the events and send them to another client by using websockets, and then replicate them on the other side (co-browsing).
I am using a page on the same domain within the frame.
public class ESinkFrame extends Frame implements EventListener {
public ESinkFrame(String src){
super(src);
DOM.sinkEvents(getElement(), Event.KEYEVENTS);
DOM.sinkEvents(getElement(), Event.MOUSEEVENTS);
}
public void onBrowserEvent(Event event) {
System.out.println( "sunk event: " + DOM.eventGetTypeString(event) );
}
}
And when I use it, I also try to attach a different way of grabbing the events.
ESinkFrame frame = new ESinkFrame("http://127.0.0.1:8888/other.html");
RootPanel.get().add(frame);
FrameElement frameElt = frame.getElement().cast();
Document frameDoc = frameElt.getContentDocument();
BodyElement body = frameDoc.getBody();
Element el = body.cast();
DOM.setEventListener(el, new EventListener()
{
public void onBrowserEvent(Event event)
{
Window.alert("test");
}
});
DOM.sinkEvents(el, Event.KEYEVENTS);
Event.addNativePreviewHandler(new NativePreviewHandler(){
public void onPreviewNativeEvent(NativePreviewEvent event) {
String eventName = event.getNativeEvent().getType();
if (event.isFirstHandler() /* && (event.getTypeInt() & Event.MOUSEEVENTS) == 0*/)
System.out.println("PreviewHandler: " + eventName);
}
});

Resources