How can i get use location in monotouch?
i'm trying with following code but any events does not fire(AuthorizationChanged & LocationsUpdated)
How should i do?please advise
public Task<CLLocation> test()
{
TaskCompletionSource<CLLocation> objTaskCompletionSource1 = new TaskCompletionSource<CLLocation> ();
CLLocation currentLocation = null;
CLLocationManager LocMgr = new CLLocationManager ();
if (CLLocationManager.LocationServicesEnabled)
{
LocMgr.LocationsUpdated += (object sender, CLLocationsUpdatedEventArgs e) =>
{
currentLocation = e.Locations [e.Locations.Length - 1];
locationUpdated = false;
if (currentLocation != null && AllAreas != null)
{
LocationDetector.Instance.UpdateCurrentArea (new RLatLng (currentLocation.Coordinate.Latitude, currentLocation.Coordinate.Longitude));
objTaskCompletionSource1.SetResult(currentLocation);
}
else
{
currentLocation = null;
objTaskCompletionSource1.SetResult(currentLocation);
}
};
LocMgr.AuthorizationChanged+= (object sender, CLAuthorizationChangedEventArgs e) => {
Console.WriteLine("AuthorizationChanged Fired");
};
LocMgr.Failed += (object sender, NSErrorEventArgs e) =>
{
};
LocMgr.StartUpdatingLocation ();
}
else
{
currentLocation = null;
objTaskCompletionSource1.SetResult (currentLocation);
Console.WriteLine ("Location services not enabled, please enable this in your Settings");
}
return objTaskCompletionSource1.Task;
}
Chances are you are testing this on iOS 8.
For iOS 8 you now need to request authorization.
So use something like the following in your ViewDidLoad (make LocMgr class scope level - so remove the local instance in your version):-
LocMgr = new CLLocationManager();
if (UIDevice.CurrentDevice.CheckSystemVersion(8,0))
{
LocMgr.RequestWhenInUseAuthorization();
}
Also, in order for the above to work, and for the dialog box to show you also need to add the following entry into your info.plist:-
<key>NSLocationWhenInUseUsageDescription</key>
<value>{some message that will be shown to the end-user}</value>
Update 1:-
Code that I am using:-
In ViewDidLoad:-
LocMgr = new CLLocationManager ();
if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) {
LocMgr.RequestWhenInUseAuthorization ();
}
UIButton objButton1 = new UIButton (UIButtonType.RoundedRect);
objButton1.SetTitle ("Click Me", UIControlState.Normal);
objButton1.TouchUpInside += (async (o2, e2) => {
CLLocation objLocationInfo = await Test1();
Console.WriteLine("Completed");
});
this.View = objButton1;
And the Test1 function:-
public Task<CLLocation> Test1()
{
TaskCompletionSource<CLLocation> objTaskCompletionSource1 = new TaskCompletionSource<CLLocation> ();
CLLocation currentLocation = null;
if (CLLocationManager.LocationServicesEnabled) {
LocMgr.LocationsUpdated += (object sender, CLLocationsUpdatedEventArgs e) => {
currentLocation = e.Locations [e.Locations.Length - 1];
locationUpdated = false;
//if (currentLocation != null && AllAreas != null) {
if (currentLocation != null) {
//LocationDetector.Instance.UpdateCurrentArea (new RLatLng (currentLocation.Coordinate.Latitude, currentLocation.Coordinate.Longitude));
objTaskCompletionSource1.SetResult (currentLocation);
} else {
currentLocation = null;
objTaskCompletionSource1.SetResult (currentLocation);
}
};
LocMgr.AuthorizationChanged += (object sender, CLAuthorizationChangedEventArgs e) => {
Console.WriteLine ("AuthorizationChanged Fired");
};
LocMgr.Failed += (object sender, NSErrorEventArgs e) => {
Console.WriteLine("AHH Failed");
};
LocMgr.StartUpdatingLocation ();
} else {
currentLocation = null;
objTaskCompletionSource1.SetResult (currentLocation);
Console.WriteLine ("Location services not enabled, please enable this in your Settings");
}
return objTaskCompletionSource1.Task;
}
Your need these also at class level:-
private bool locationUpdated = false;
private CLLocation currentLocation = null;
private CLLocationManager LocMgr;
Remember you need to edit your info.plist as well.
If you then run the example putting a breakpoint at the Console.WriteLine("Completed"); you should then be able to inspect objLocationInfo and see that it has a location.
Related
I implemented the CLLocationManager.StartMonitoring() method. The CLLocationManager.EnterRegion is fired when the beacon comes into the range of the phone, however the RegionLeft does not get called when the Beacon is outside of the range of the phone again. I use the following code:
public void StartWakeupForBeacon()
{
//NSOperationQueue.MainQueue.AddOperation(() =>
//{
string message = "";
CLProximity previousProximity = CLProximity.Far;
var userId = ServiceLocator.Instance.Get<IAccountStoreService>().GetAccountUserId();
var tupple = UtilHelper.GetMajorMinorFromUserId(userId);
var major = tupple.Item1;
var minor = tupple.Item2;
var beaconUuid = UuidHelper.BeaconUuidString;
BeaconRegion = new CLBeaconRegion(new NSUuid(beaconUuid), (ushort)major, (ushort)minor, "com.example.company");
BeaconRegion.NotifyEntryStateOnDisplay = true;
BeaconRegion.NotifyOnExit = true;
BeaconRegion.NotifyOnEntry = true;
LocationManager = new CLLocationManager();
LocationManager.RequestAlwaysAuthorization();
LocationManager.RegionEntered += (object sender, CLRegionEventArgs e) =>
{
Console.WriteLine("region entered");
var btService = ServiceLocator.Instance.Get<IBluetoothService>();
ServiceLocator.Instance.Get<ILoggingService>().LogEvent(LoggingService.BeaconRegionEnteredEvent);
btService.ExchangeData();
};
LocationManager.RegionLeft += (object sender, CLRegionEventArgs e) =>
{
Console.WriteLine("region left");
ServiceLocator.Instance.Get<ILoggingService>().LogEvent(LoggingService.BeaconRegionLeftEvent);
};
LocationManager.DidDetermineState += (object sender, CLRegionStateDeterminedEventArgs e) =>
{
switch (e.State)
{
case CLRegionState.Inside:
Console.WriteLine("region state inside");
break;
case CLRegionState.Outside:
Console.WriteLine("region state outside");
break;
case CLRegionState.Unknown:
Console.WriteLine("region unknown");
break;
default:
Console.WriteLine("region state unknown");
break;
}
};
LocationManager.DidStartMonitoringForRegion += (object sender, CLRegionEventArgs e) =>
{
LocationManager.RequestState(e.Region);
string t_region = e.Region.Identifier.ToString();
Console.WriteLine(t_region);
};
LocationManager.DidRangeBeacons += (object sender, CLRegionBeaconsRangedEventArgs e) =>
{
if (e.Beacons.Length > 0)
{
CLBeacon beacon = e.Beacons[0];
switch (beacon.Proximity)
{
case CLProximity.Immediate:
message = "Immediate";
break;
case CLProximity.Near:
message = "Near";
break;
case CLProximity.Far:
message = "Far";
break;
case CLProximity.Unknown:
message = "Unknown";
//SendNotication();
break;
}
if (previousProximity != beacon.Proximity)
{
Console.WriteLine(message);
}
previousProximity = beacon.Proximity;
}
else
{
Console.WriteLine("nothing");
}
};
LocationManager.StartMonitoring(BeaconRegion);
LocationManager.MonitoringFailed += (sender, e) =>
{
System.Diagnostics.Debug.WriteLine("Failed monitoring");
};
LocationManager.StartRangingBeacons(BeaconRegion);
//});
}
When the Beacon is out of range of the phone, I can see that this is recognized by the app, since DidRangeBeacon does not recognize any beacon anymore and prints "nothing" to the console.
Additionally I get weird device logs regarding the location manager, it basically spams the following warning:
#Warning Tried injecting when not running
I am trying to get CCTextFieldTTF to work in cocos sharp with Xamarin for an android application. But can't get hold of this for the life of me. Could not find any documentation on cocos sharp API either. Does anyone know how to use this class to render a text area in an android application? The reason I am asking is in a xamarin forum I saw someone saying that this does not work in the API yet. Any help would be highly appreciated. Thanks in advance.
I have this working in android
Here is the sample code:
Create a node to track the textfield
CCTextField trackNode;
protected CCTextField TrackNode
{
get { return trackNode; }
set
{
if (value == null)
{
if (trackNode != null)
{
DetachListeners();
trackNode = value;
return;
}
}
if (trackNode != value)
{
DetachListeners();
}
trackNode = value;
AttachListeners();
}
}
//create the actual input textfield
var textField = new CCTextField(string.Empty, "Somefont", 25, CCLabelFormat.SystemFont);
textField.IsColorModifiedByOpacity = false;
textField.Color = new CCColor3B(Theme.TextWhite);
textField.BeginEditing += OnBeginEditing;
textField.EndEditing += OnEndEditing;
textField.Position = new CCPoint (0, 0);
textField.Dimensions = new CCSize(VisibleBoundsWorldspace.Size.Width - (160 * sx), vPadding);
textField.PlaceHolderTextColor = Theme.TextYellow;
textField.PlaceHolderText = Constants.TextHighScoreEnterNamePlaceholder;
textField.AutoEdit = true;
textField.HorizontalAlignment = CCTextAlignment.Center;
textField.VerticalAlignment = CCVerticalTextAlignment.Center;
TrackNode = textField;
TrackNode.Position = pos;
AddChild(textField);
// Register Touch Event
var touchListener = new CCEventListenerTouchOneByOne();
touchListener.OnTouchBegan = OnTouchBegan;
touchListener.OnTouchEnded = OnTouchEnded;
AddEventListener(touchListener);
// The events
bool OnTouchBegan(CCTouch pTouch, CCEvent touchEvent)
{
beginPosition = pTouch.Location;
return true;
}
void OnTouchEnded(CCTouch pTouch, CCEvent touchEvent)
{
if (trackNode == null)
{
return;
}
var endPos = pTouch.Location;
if (trackNode.BoundingBox.ContainsPoint(beginPosition) && trackNode.BoundingBox.ContainsPoint(endPos))
{
OnClickTrackNode(true);
}
else
{
OnClickTrackNode(false);
}
}
public void OnClickTrackNode(bool bClicked)
{
if (bClicked && TrackNode != null)
{
if (!isKeyboardShown)
{
isKeyboardShown = true;
TrackNode.Edit();
}
}
else
{
if (TrackNode != null)
{
TrackNode.EndEdit();
}
}
}
private void OnEndEditing(object sender, ref string text, ref bool canceled)
{
//((CCNode)sender).RunAction(scrollDown);
Console.WriteLine("OnEndEditing text {0}", text);
}
private void OnBeginEditing(object sender, ref string text, ref bool canceled)
{
//((CCNode)sender).RunAction(scrollUp);
Console.WriteLine("OnBeginEditing text {0}", text);
}
void AttachListeners()
{
// Attach our listeners.
var imeImplementation = trackNode.TextFieldIMEImplementation;
imeImplementation.KeyboardDidHide += OnKeyboardDidHide;
imeImplementation.KeyboardDidShow += OnKeyboardDidShow;
imeImplementation.KeyboardWillHide += OnKeyboardWillHide;
imeImplementation.KeyboardWillShow += OnKeyboardWillShow;
imeImplementation.InsertText += InsertText;
}
void DetachListeners()
{
if (TrackNode != null)
{
// Remember to remove our event listeners.
var imeImplementation = TrackNode.TextFieldIMEImplementation;
imeImplementation.KeyboardDidHide -= OnKeyboardDidHide;
imeImplementation.KeyboardDidShow -= OnKeyboardDidShow;
imeImplementation.KeyboardWillHide -= OnKeyboardWillHide;
imeImplementation.KeyboardWillShow -= OnKeyboardWillShow;
imeImplementation.InsertText -= InsertText;
}
}
This is all taken from the link below but needed a bit of additional work to get it working on each platform.
https://github.com/mono/cocos-sharp-samples/tree/master/TextField
How can i pause application for prevention from running next method unit client does not selected dialog buttons?
For example i am showing location update dialog for accessing location service and i want to pause my application for dialog response
public CLLocation UpdateUserLocation()
{
CLLocation currentLocation = null;
CLLocationManager LocMgr = new CLLocationManager();
if (CLLocationManager.LocationServicesEnabled)
{
if (UIDevice.CurrentDevice.CheckSystemVersion (6, 0))
{
LocMgr.LocationsUpdated += (object sender, CLLocationsUpdatedEventArgs e) =>
{
currentLocation = e.Locations [e.Locations.Length - 1];
};
}
else
{
LocMgr.UpdatedLocation += (object sender, CLLocationUpdatedEventArgs e) =>
{
currentLocation = e.NewLocation;
};
}
LocMgr.StartUpdatingLocation ();
LocMgr.Failed += (object sender, NSErrorEventArgs e) =>
{
Console.WriteLine (e.Error);
};
}
else
{
currentLocation = null;
Console.WriteLine ("Location services not enabled, please enable this in your Settings");
}
if (currentLocation != null)
{
LocationDetector.Instance.UpdateCurrentArea (new MyLatLng (currentLocation.Coordinate.Latitude, currentLocation.Coordinate.Longitude));
}
return currentLocation;
}
If I am understanding your question correctly.
When you display a dialog box, you are wanting to stop execution of the current method from further executing until the user selects a dialog box response.
Once they have selected a response, you would then like to continue execution of the code in the same function, effectively achieving your 'pause' that you are after.
To achieve this in iOS you can use a TaskCompletionSource.
In the example below it shows a dialog box first, asking the user if they want some coffee and then waits for the user to respond.
Once the user responds, it then continues execution, within the same function, and displays a further message box that is dependent on the selection that the user made.
UIButton objButton1 = new UIButton (UIButtonType.RoundedRect);
objButton1.SetTitle ("Click Me", UIControlState.Normal);
objButton1.TouchUpInside += (async (o2, e2) => {
int intCoffeeDispenserResponse = await ShowCoffeeDispenserDialogBox();
//
switch (intCoffeeDispenserResponse)
{
case 0:
UIAlertView objUIAlertView1 = new UIAlertView();
objUIAlertView1.Title = "Coffee Dispenser";
objUIAlertView1.Message = "I hope you enjoy the coffee.";
objUIAlertView1.AddButton("OK");
objUIAlertView1.Show();
break;
case 1:
UIAlertView objUIAlertView2 = new UIAlertView();
objUIAlertView2.Title = "Coffee Dispenser";
objUIAlertView2.Message = "OK - Please come back later when you do.";
objUIAlertView2.AddButton("OK");
objUIAlertView2.Show();
break;
}
});
//
View = objButton1;
private Task<int> ShowCoffeeDispenserDialogBox()
{
TaskCompletionSource<int> objTaskCompletionSource1 = new TaskCompletionSource<int> ();
//
UIAlertView objUIAlertView1 = new UIAlertView();
objUIAlertView1.Title = "Coffee Dispenser";
objUIAlertView1.Message = "Do you want some coffee?";
objUIAlertView1.AddButton("Yes");
objUIAlertView1.AddButton("No");
//
objUIAlertView1.Clicked += ((o2, e2) => {
objTaskCompletionSource1.SetResult(e2.ButtonIndex);
});
//
objUIAlertView1.Show();
//
return objTaskCompletionSource1.Task;
}
I have a 3 GSM phones and a 3 verizon (CDMA) phones. I have a BB application in which the location listener is set to a 5 minute interval.
For 2 of the verizon phones the application's location update method gets called frequently. For the rest, the location listener gets called at a regular 5 minute interval.
What could be causing this difference in behavior?
public synchronized void locationUpdated(LocationProvider locationProvider, Location location) {
if (enabled) {
if (blackberryProvider != null) {
try {
constructCriteria(GPSInfo.GPS_MODE_CELLSITE);
gpsUpdate();
} catch (LocationException e) {
log stuff//
}
}
}
}
private void gpsUpdate() throws LocationException, InterruptedException {
try {
String gpsMode = null;
if (bbCriteria.getMode() == GPSInfo.GPS_MODE_CELLSITE) {
gpsMode = "cellsiteMode";
}
if (gpsMode == "cellsiteMode" && gpsMode.length() > 0 && bbProvider != null) {
// variable declaration
try {
bbLocation = (BlackBerryLocation) bbProvider.getLocation(10);
} catch (LocationException e) {
bbLocation = null;
}
if (bbLocation != null) {
// do stuff
// store location in the database
}
}
}
}
}
}
private void constructCriteria(final int mode) {
blackberryCriteria = null;
blackberryProvider = null;
blackberryCriteria = new BlackBerryCriteria();
blackberryCriteria.setSatelliteInfoRequired(true, false);
if (mode == GPSInfo.GPS_MODE_CELLSITE) {
setCriteraForCellSite();
}
try {
blackberryProvider = (BlackBerryLocationProvider) LocationProvider.getInstance(blackberryCriteria);
if (iLocationListner == null) {
iLocationListner = new ILocationListner();
blackberryProvider.setLocationListener(iLocationListner, locationInterval == 0 ? 300 : locationInterval, -1, -1);
} else {
blackberryProvider.setLocationListener(iLocationListner, locationInterval == 0 ? 300 : locationInterval, -1, -1);
}
} catch (LocationException lex) {
Logger.log("LocationEventSource constructor", lex);
return;
}
}
You are setting your criteria to update every 300 seconds if locationInterval == 0 or at the default rate (once per second) otherwise. Is this really what you want? Where is locationInterval initialized? How does its value change as the program runs?
I can't read location with this function. When I try to get location information, it always returns altitude 0, longitude 0.
void getirGps(){
Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);
try
{
LocationProvider myLocationProvider =
LocationProvider.getInstance(myCriteria);
try
{
Location myLocation = myLocationProvider.getLocation(300);
seTLatitude(myLocation.getQualifiedCoordinates().getLatitude());// sunlarıda bir public statıc dene..
seTLongitude(myLocation.getQualifiedCoordinates().getLongitude());
Dialog.alert("latitude = "+GPSThread.latitude +" longi"+GPSThread.longitude);
velocity = myLocation.getSpeed();
heading = myLocation.getCourse();
timeStamp = myLocation.getTimestamp();
nmeaString = myLocation.getExtraInfo
("application/X-jsr179-location-nmea");
}
catch ( InterruptedException iex )
{
Dialog.alert("InterruptedException");
return;
}
catch ( LocationException lex )
{
Dialog.alert("LocationException lex");
return;
}
}
catch ( LocationException lex )
{
Dialog.alert("LocationException lex2");
return;
}
}
public void doThis(){
MapView mapView = new MapView();
mapView.setLatitude( (int) Threads.latitude);//39.9208, Longitude = 32.8541
mapView.setLongitude((int) Threads.longitude);
mapView.setZoom(10);
MapsArguments mapsArgs = new MapsArguments(mapView);
Invoke.invokeApplication(Invoke.APP_TYPE_MAPS, mapsArgs);
Dialog.alert("latitude = "+Threads.latitude +" longi"+Threads.longitude);
Make sure the GPS functionality is enabled on the device.