Blog Stats

Category: Windows Phone 8.1 For Newbies

Geofencing was one of the newest features Windows Phone 8.1 provided and for the developers it indeed was cool. Previously people did it their way but it’s always better to have an api in our hand. So, before digging into that i strongly suggest you guys to read my previous 2 articles if you haven’t done it already.

These two would get you started pretty fast and you’d probably want that. If you already read my aforementioned 2 articles, I expect you know how to use a map control in Windows Phone 8.1. We’re going to need that later.

Geofencing:

Geofencing is a mechanism where you put a virtual boundary around a specific point of interest and you want to interact with the user when you arrive or leave that specific boundary. You seriously can do pretty amazing stuff with it actually.

Initial Work:

Now, let’s take a more practical approach to this, every time I go into my room, Im supposed to check my mails. But I usually forget that. How cool it would be if my phone reminds me every time I get into my room and tells me to check my mail? 😉

So, let’s go ahead and create a new Windows Phone app and name it GeoFencingTest. Now, lets see how to do that actually.

So, first of all go over your Package.appxmanifest file and go to the Capabilities Tab and select the Location capability.

Now, when you are done with that, let’s move on and start cracking. Before going deep lets get a basic UI running. And it looks like following:

Before going in deep on what is for what let’s get some basic stuff done. Let’s get our current location first.

Since you guys have seen in the last articles, it’s fairly easy to do so. All I’m doing here is get the current location using Geolocator and put the Latitude, Longitude and Altitude into the textblocks defined in the MainPage.xaml.

The only thing that is interesting here is having a CancellationToken generated from a CancellationTokenSource. Usually these are used if you really want control over your task after it’s being fired, the rest of the procedure should look familiar as it’s a basic Geolocator usage to find current geolocation.

Setting up a GeoFence:

Now comes the setting up the actual GeoFence part and even this is fairly simple. The method looks like the following:

The first one is definitely the GeofenceKey. Put a GeofenceKey in position just to identify a specific Geofence. I put s generic string to identify my home geofence.

Then I called up GetMyHomeLocation() method to set the geofence center to the location of my room. This will identify the center of our desired Geofence.

And the next thing to define is a radius that will define the radius of our circular geofence. We are using Geocircle object to define our geofence here, thus we are using a center and a radius in meters to defined our geofence. You can definitely see the next thing we did is define our geocircle. Actually the Geofence takes a Geoshape object to define it’s radius and currently only Geocircle is supported.

Now, we have put a checkbox in our XAML named SingleUse. This is supposed to define whether our geofence would be used for only one time or not. You can set up temporary one time used geofence using this.

bool singleUse = (bool)SingleUse.IsChecked;

Now, the next thing we did is we defined how our desired geofence would be treated. Which events are we considering with this geofence? Should this be fired only when we get into that geofence or should this will only be considered when we exit the geofence, or even we remove the geofence? We can actually select all or a subset of that group. So we used Logical OR operator to add up all the cases we want our geofence to react upon.

Let’s move on into the time domain now. Now we need to figure how long we need to stay in our favourite geofence to trigger up it’s desired events. I put a textbox in front to define that in seconds, if that is defined, we fire out events from our geofence in that number of seconds and if not we fire out events in our default dwell time defined by 0 seconds.

// setting up how long you need to be in geofence for enter event to fire
TimeSpan dwellTime;
dwellTime = DwellTime.Text!=&quot;&quot;? ParseTimeSpan(DwellTime.Text) : TimeSpan.FromSeconds(DefaultDwellTimeInSeconds);

You can even define how long a geofence should be up and running. Like I want my rooms geofence to be running for next 10 days.

// setting up how long the geofence should be active
TimeSpan GeoFenceDuration;
GeoFenceDuration = TimeSpan.FromDays(10);

Even with that thing defined, one question remains, even though it will run for 10 days, when does the geofence gets activated so it can start counting to that defined 10 days. Answer is right below:

// setting up the start time of the geofence
DateTimeOffset GeoFenceStartTime = DateTimeOffset.Now;

Well, the only thing left to do is create our desired geofence and add it to GeofenceMonitor.

Now, that’s how you create your own geofence and add it to the GeofenceMonitor. Now you might wonder that whether you’d really have to define all that parameters to create a geofence. Not actually, the littlest you can do is define an Id and a Geocircle to start your geofence. 😉 The rest of the values would take the default assumption.

Handling GeoFence Notifications on Foreground:

We have all our background work to create a geofence but we wont be able to do a single thing unless we test our geofence. Now, we have already defined that our geofence would trigger events after the aforementioned dwellTime and will trigger events if I enter or leave it. So, I definitely have to attach a event handler at a certain place. Don’t I?

Before that, let’s create the method stub for the click event handler for CreateGeoFencingButton and start SetupGeofence() method inside it. If you don’t know how to do that, select the CreateGeoFencingButton in XAML, go to properties, select events tab and double click on the click textbox.

There you go! That’s how you set up your geofence in an app running in the foreground.

Setting up GeoFence on the background:

Now, this is where things get a little bit tricky. There’s a number of steps involved in this.

Create a Windows Runtime Component Project and add it to your solution.

Change Package.appxmanifest to declare the BackgroundTask that has been created.

Register the BackgroundTask

Handle Geofence Notifications from Background Task

Create a Windows Runtime Component Project:

Usually, background tasks are windows runtime component so you have to add one to your solution. Please go over to your solution and add a Windows Runtime Project.

After the new project is created go over class1.cs and rename it to your liking . I renamed it to BackgroundTask and added IBackgroundTask interface to the class and implemented it. I didn’t write anything afterwards. Let’s just keep it like that for a while and move to our GeofenceTest Project. Go over references and add the newly created GeofenceTask.BackgroundGeofenceTask project to it. So our Wp8.1 project now has reference to the GeofenceTask.BackgroundGeofenceTask project.

Change Package.appxmanifest to declare the BackgroundTask:

Now let’s scoot over to our Package.appxmanifest file and go over Declarations tab. From Available Declarations combobox select BackgroundTask and select loction under the Properties list.

Now on the Entry point field please put the full qualified assembly name of your newly created background task. Don’t get confused. It’s fairly easy. Let’s have a look at BackgroundGeofenceTask class first.

Let’s see what we have in here now. The very first one is get the BackgroundAccessStatus. That helps us to know whether our application is capable of accessing BackgroundTasks. Now, let’s move up and use BackgroundTaskBuilder to create the background task we intend to create. Now, if you look at the TaskEntryPoint we provided there, you’d now realize why we created our Background Task project before and added it to the manifest. Because we are using the same entry point name here. I put a name to identify the background task. This is needed as if there is another background task with the same name you would be thrown an exception. If you want to know whether there is another BackgroundTask with the same name you can iterate through BackgroundTaskRegistration.AllTasks and then make sure whether there is one with the same name or not. You can use a method like the following to do so:

The next thing that comes off is defining the LocationTrigger for the BackgroundTaskBuilder object. So, we defined a new LocationTrigger of type LocationTriggerType.Geofence and used SetTrigger method to set it up. Then we used BackgroundTaskBuilder object to register the task and we instantiated a GeofenceTask_Completed event handler for that too.

At the bottom you’d see a switch with backgroundAccessStatus and putting a MessageDialog when it’s denied or unspecified.

Handle Geofence Notifications from Background Task:

So, lets move to our Windows Runtime Component which actually is the Background Task project and implement the IBackgroundTask interface. A method named

public void Run(IBackgroundTaskInstance taskInstance)

would pop up, we’d put our regular geofence event handling in there like there in the Foreground example. Now it looks like following when we are handling it from background

Now, this looks a wee bit different from the first example. The first change that is noticable is that we are now selecting the reports based on our geofence id and the report’s new state. As we are in background now, we are using our geofence id to get the proper geofence from the whole list. And as now we are in background we are using a Toast Notification instead of a MessageDialog to show our notification.

Handling it from the App Side:

Now you guys might get confused what to do with the foreground code we made earlier. Do we need Current_GeofenceStateChanged event handler anymore. Now here we might have to be a bit careful. Now if we want our app to react different when it is on foreground and make some UI changes it needed then we have to use GeofenceTask_Completed event rather than Current_GeofenceStateChanged. And there’s another thing to be added. We get our GeofenceMonitor Reports using GeofenceMonitor.Current.ReadReports() and this step can only be done once for every change. So if your background reads it first then, your foreground app would not be able to read it. So, we have to save it somewhere when the background reads it so our foreground app can read it from there.

So we are using ApplicationData.Current.LocalSettings to save our state in the Background Task. If you look closely you’d find the following snippet:

You can definitely test the app on the emulator. Like always click the debug button with a emulator selected as the device and when it opens go to additional tools button and open up the location tab. Select a close location to your geofence, I did select a close one to my room and the status changed itself to “Entered”. It was that easy! You can even try the foreground example in the same way!

Windows Phone 8.1 comes with a lot of prospects in the geo location end and usually the next thing after detecting your very own location, people tends to look for one another thing and that is tracking the location as it should update itself. So, if you’re wondering about how you should instantiate a map and track your location, you really should check out my previous post .

And if you have already done that (I hope you liked it). Then you’d probably know how to do the following:

Please go ahead to your visual studio (Im using a Visual Studio 2013 Community Edition) and open a new project on Blank App on Windows Phone 8.1

Go over your project properties and go over Capabilities. Enable Location for your app (If you are from Windows Phone 8, you’d be pretty amazed that you don’t see ID_CAP_MAP anymore.

A Basic UI:

Let’s set up a basic UI and yes It’s kind of a rip off from MSDN but as long as it helps people, it’s cool. Our little UI has two Buttons and a number of textblocks and it looks like below in XAML (I’m only posting the main grid):

Now, if you dive a little bit into that, you will see that if the locator is instantiated then the first property we do change is the MovementThreshold property. It is the property that defines the movement threshold for the geo tracking to notify you. It’s defined in meters and thus we have defined it to 3 meters. Now next question that comes along is how would I know that I have moved my MovementThreshold amount of distance. The common answer would be actually invoking a PositionChanged event and attach a handler to it. And the handler locator_PositionChanged looks like below:

The reason we are using that would be pretty clear if we look at what are we doing. We are constantly updating our LatitudeText, LongitudeText, AccuracyText and as we are accessing a UI thread frequently from a event handler, we do need to make it sure it doesn’t block the regular UI interactions. Thus we used a CoreDispatcher here, much like it was in Windows Phone 8 as Dispatcher. You’d also be able to notice that the event handler is async and thus dispatcher.RunAsync invocation was awaited. We used CoreDispatcherPriority.Normal and you can even try a higher priority if you like. All this event handler is doing is it is actually updating the UI and the textblocks.

Now all you need is a StoptrackingButton to get things to stop and all you have to do is unhook the locator_PositionChanged event handler.

As this sample has geolocator usage, this is always better to be tested in a device but you can definitely try it on an emulator too. To test it load the app on the emulator first by invoking build.

When the emulator hooks up open up the emulator tools and go to the location tab and click on the map to give you a primary location first. You can have a look at the gif below for an idea

Now after you pointed a primary location in the map. Now you can try clicking the track location button. After you do that Latitude, Longitude and Accuracy would pop up for the place you clicked on the map. Now click some more around it. And you will see the data changes on the textblocks. You can do one thing more too. You can change the interaction mode from Live to Pin and play all the pins. That would even allow to emulate place changes in your emulator. The following gif would definitely help you.

As Windows Phone came up with Windows Phone 8.1 update last year it came up with 2 different platforms to work on , silverlight and WinRT, thus making it a bit tough to keep up with the latest api documentation and maps are not different.

As I have written before how to use Maps following MVVM on Windows Phone 8, I’m going to keep today’s one as a bit of a reference to that and will just post segments that you can use as a code sample.

Instantiating a Map in Windows Phone 8.1:

Quiet frankly this is the easiest job here to do actually. Let’s go ahead and start taking things on screenshot. First we need to open a new project targeting Windows Phone 8.1 and name it MapTest. Then I went to my Toolbox and dragged a MapControl in the middle of the Main Grid. I have already changed my map controls HorizontalAlignment and VerticalAlignment to “stretch’ thus allowing the MapControl to be stretched out to the fullest for the whole app.

Usually a map driven app needs an AuthenticationToken to authenticate the map services but we will focus on it later. Let’s go ahead to solution explorer and open Package.appxmanifest and go to Capabilities tab and make sure Location and Internet both of the checkboxes are checked just to make it sure that your app is map capable.

Now we have a green light to use Maps. If you are a fella from Windows Phone 8 development you’ll see now, you don’t have ID_CAP_MAP here to make an app enable to use maps. You only need it to have location capability.

Getting Your Own Location:

Getting your own location is still as straightforward as it was before in Windows Phone 8 era. All you have to do is use the same Geolocator class and it looks like the following:

Now the question remains now is how would you be able to show it on a Map. Now, Windows Phone 8.1 gives you a lot of options to choose from actually here. You can use three specific things here:

MapIcon

XAML controls

Shapes

Using MapIcon:

The first trial we are going to make is using the MapIcon as it is most straight forward. MapIcon is essentially derived from MapElement class, it can be configured by providing a new image to it or it provides a default one. And the declaration is pretty straight forward too.

Now, if you want to provide a specific Image as your MapIcon, include the image in the Assets folder and let’s assume the image name is MapIcon.png. All you have to do is change the Image property of your MapIcon object.

What people actually misinterpret here is usually they compare PushPin with MapIcon and they do have a valid reason to do so because you can achieve the same result by using both of them but in actuality it doesn’t work like so. MapIcons are actually a set of Icons that define different purposes on the map. These are lightweight, so please chose one if you want to use these to show a specific purpose. Now our purpose was to show our current location.

Now let’s put together a method named GetMyLocation() and put all these together and see what happens.

Now, as this goes, you’ll see Ive done some more works too. I’ve changed the center property of the map control because after adding the MapIcon you need your map to focus on that point and this is how you change the center of your map. And the next thing I did is setting DesiredPitch to 0. We will see more on this property later. You definitely have noticed by now that the method is an asynchronous method because the process of locating your position is asynchronous and we’re using our favourite await keyword to make locator.GetGeopositionAsync() to work synchronously inside the method. The last thing you want is to focus to the selected location (My Location) on the map. So Im setting the map view in an async manner using MyMap.TrySetViewAsync function and it takes two parameters, the first one being the point (the geolocation of you) you want to set your view into and the second is a zoom level of the map. It is actually setting the MyMap.ZoomLevel property that ranges from 1 – 20. Higher number means you’re more zoomed thus more closer to the ground. I’ve also used a custom MapIcon.png with a size of 65×65 pixels. Please be careful on this one as the size you chose is the size you get on the Map. Please choose a size that looks good for your purpose. Now lets put the GetMyLocation() method OnNavigatedTo method and thus you get a smooth zooming animation.

Now, couple of things that are missing here is a progress bar showing that the location is being detected and a try catch that detects any exception detecting the location. Plus we need to put our location detection invocation in a button so we can tap it anytime to load our current location anytime. For that we are going to take help of Application Bar.

Now, let’ wrap up the location detection process under a try-catch just to make sure that if anything goes wrong, you’re covered. And as we’d need to show progress please put the following method in MainPage.xaml too.

Using XAML controls over Map is something I really love because I was pretty fond of the PushPin control provided in Windows Phone Toolkit for Windows Phone 8. Usually this approach is more suitable for MVVM approached apps though. And as per this tutorial goes, we’d not got over MVVM just yet (We will cover that too). So, let’s see how you add XAML controls or shapes in a map from codebehind.

Instead of using MapIcon all you have to do know is generate a XAML control/Shape in background and add it on the children list of the map control rather than the MapElements list.

Now, before moving to the next topic, I’d like to address some points in this approach.

You can create your control in codebehind as you want to build it, you can use possibly any XAML control starting from containers like Grid and StackPanels to Shapes like rectangle and Ellipse.

Select a proper size of the shape if you want to use it and it’s better than MapIcons in one sense is that MapIcons are not guaranteed to be viewed.

MapIcon objects are usually added in the MapElements list but this is added in the Map Children collection.

You can define your datatemplate behind and even hook events (We will see this on MVVM approach

You have to select a proper anchor point for your Xaml/Shape pushpin too. It’s actually nothing but a point object in a 2d space. I want my anchor point to be in the center of the sphere. So if I put my sphere in a 2d space and 1 is the max limit in both X and Y axis, you’d find out that (0.5, 0.5) is the center of the sphere. But this 2d co-ordinate system is actually a tad different. Kindly allow me to demonstrate in the following picture:

So, according to this rule, now you can set your anchor point properly according to your xaml control. Just put it on an imaginary 2d grid and find your desired point. left bottom would be (0,1) and right bottom would be (1,1).

If you look closely you will also see we have changed our TrySetViewAsync invocation with some more parameters. Those are heading, pitch (We kept both of them at 0) and the last one is MapAnimationKind that allows you to define what kind of animation you want when setting the view. I personally love the Bow one thus I used that one and it looks like below:

Changing The Map Properties:

The map control itself comes with a lot of properties equipped, let’s see how we can change these for a chance. The first two things we’d love to change is the pitch/tilt and the rotation/heading. For that we’d need to change our layout a bit. Let’s keep the map in the background and put 2 sliders (one horizontal and one vertical) for changing rotation and pitch of the map.

We have introduced 3 rows and columns in the main grid just to keep the whole map in the background and the sliders floating in the top. The horizontal slider would change the Maps rotation and the Vertical Slider would change the Maps pitch. Now the main grid looks like the following:

Now the first thing you’d notice here is I’ve named the sliders accordingly. The horizontal one is called RotationSlider and the vertical one is called PitchSlider. Now, usually what we do is invoke the ValueChanged event and change the Heading or the DesiredPitch of the map. But there is a smarter way to do that. You can create two element bindings to the MyMap and bind the value of the sliders to the specific properties. If you watch carefully you will see that I have set the RotationSlider maximum value to 360 as that is the maximum rotation value and PitchSlider Maximum to 65 as that is the maximum tilt the MapControl allows. Now replace your sliders with the following binding:

Please make it sure the Binding Mode is set to TwoWay so when the map updates the sliders updates too. And without even writing a single backend code the feature is done!

So, that’s a creative use of element binding. Now you could’ve done it even from code backend. All you had to do is go to properties of PitchSlider and RotationSlider and create the ValueChanged method stub. The methods would’ve looked like the following:

Let’s move on and see some of the other features we’d like to test too. Let’s add two checkboxes in the bottom of the map to enable Traffic Flow and Land Marks. We added a horizontal stackpanel and added two checkboxes along with it.

Now, watch carefully the binding written in TrafficFlowVisible property and LandMarksVisible property. All I did here is binded them with the appropriate checkbox IsChecked property and kept the binding mode two way. So, anytime these properties get changed even from codebehind we’ll see the change on the checkbox and vice versa. Traffic Flow is a cool feature actually. See the next gif to get an idea:

Pretty cool huh!

Now you can even write it on the codebehind. You have to go to the properties of any of the checkbox and create the checked and unchecked property stub so you can toggle the maps TrafficFlowVisible feature. From code behind it will look like this:

I still prefer the Element binding because that is extremely easy. There’s one more property named PedestrianFeaturesVisible property. You can try that following the same way here.

Map Appearance:

Map Control is even cool enough to let you select the Map Appearance too! Let’s modify the bottom stackpanel so it can hold more buttons and added a grid with two columns. We added one combobox in each column so we can change map color scheme and map style.

We have added light and dark as the Map Color Scheme in the MapColorBox combobox and we have added 5 different Map Styles on MapStyleBox combobox. Each of the combobox has SelectionChanged event handler hooked up. Let’s see how MapColorBox_SelectionChanged looks like in MainPage.xaml.cs

This looks like the previous one too. All we did here is based on the MapStyleBox SelectedItem we have assigned MyMap.Style to appropriate MapStyle.

Change Map Tile Source:

Now usually what we see is either bing or here maps on Windows Phone 8.1 Map Control. In some cases people might need to access different tile source like openstreet map. For the ones who doesn’t understand what a tilesource is, every map system is nothing but a series of square shaped images/tiles shown for a range of geo coordinate boundary. It’s a grid of images shown based on the maps zoom level. When you zoom out or zoom in or roam around in the map, based on your X,Y and zoom level the map requests tiles of images to show you.

If you want to add/change a tiles layer, you have to change the TileSources collection of the map control. You can set the Zindex, tile pixel size and visibility. You can even forbid/allow stretching of the tiles while a higher resolution tile is being downloaded. You can define layer type of the tile source like BackgroundReplacement, BackgroundOverlay and RoadOverlay.

And after the app is loaded, your map will look like this. But remember as we set our layer to BackgroundReplacement we will not have any kind of map styles or other features like TrafficFlow anymore.

You will also observe the loading of the map is pretty slow as the tiles are loaded from one source. So, we can balance the load by pointing to three different domains so the maps may load faster. All we have to do is rotate the subdomain of openstreet map in between a,b and c

Here in the GetNextDomain method you will see that all it’s doing is it is actually rotating between the three subdomains of openstreet map.

And it looks like below:

Map Events:

Maps in Windows Phone 8.1 comes with much easier touch events. Touch events now comes along with GeoPoint and local UI coordinates related to the touch point. All these comes along with MapTapped, MapDoubleTapped and MapHolding events. To check if a location is visible on current map window you can use IsLocationInView().

We are going to try the MapTapped event for now. Select the MapControl, go over properties, go to event handlers and double click on the MapTapped event handler to create the method stub for that.

Now here we have a sample reverse geocode query. And you can definitely see this is much easier here. You have to use MapLocationFinder class and it has a FindLocationsAtAsync method to get back with a geocoordinate based on your tap on the map. Actually it usually returns a list and we picked the first on the list and printed out the town, district and country on a messagedialog.

you can definitely check how the thing works on the phone

Authenticating a Maps App:

The last thing that is left to do is authenticating a map app. You will see unless you provide a map control a map service AuthenticationToken it keeps asking it in the bottom of the map.

Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
// MT: Register the Frame with the SuspensionManager.
SuspensionManager.RegisterFrame(rootFrame, "rootFrameKey");