Tuesday, December 30, 2014

Launching Third party Maps from your App


There could be Scenarios where you don’t really want the full control over how maps behave and want the experts (Bing maps, Nokia Maps and many more) to handle it for your , in that case all you have to do is use is

Windows.System.Launcher.LaunchUriAsync(uri) .
Now lets get into details on how to work with each of the major Map apps.

Working with Bing Maps

The Uri Schema to launch the Bing maps is "bingmaps:" and below is the simple code to launch the bing map .

private void LaunchBingMaps()
{

// The URI to launch
string uriToLaunch = @"bingmaps:?cp=140.726966~174.006076";
var uri = new Uri(uriToLaunch);
Windows.System.Launcher.LaunchUriAsync(uri);
}
**other supported parameters are bb(bounding box),lvl(zoom level),where,Q(query term),trfc(traffic),rtp(Route).

Launching Other Map apps

If you want to launch any other map apps other than bing maps then


  •  ms-drive-to :Launches the third party map apps like nokia maps , att maps in the driving Route mode
  • ms-walk-to :Launches the third party in the walking Route mode

The paramters that you pass to the URI schema are destination.latitude , destination.longitude or destination.name .

sample code snippet to launch the third party map application .

public void LaunchDrive()
{
// The URI to launch
string uriToLaunch = @"ms-drive-to:?destination.latitude=12.8399390"
+ "&destination.longitude=77.6770030&destination.name=Electonic city";
var uri = new Uri(uriToLaunch);
Windows.System.Launcher.LaunchUriAsync(uri);
}
**if there is no apps install on your phone to handle this URI schema them the user will be taken to the stores to search for the apps that handles this uri schema **if there are more than one app installed to handle this URI schema then there will be pop up dailog presented to the user to choose the app which needs to handle the schema .

Working with Map control windows phone 8.1


The fist task in hand if you want to use map controls or any other map services(drive service , walk service and more ) in your app is to authenticate your app  to use the map services and this needs to be done in the windows phone developer dashboard .

Here is the Link which will guide you to Authenticate your app to work with maps .

Once done with the above step you will get your  Map service ApplicationID and Map service AuthenticationToken .

The Maps controls for windows phone 8.1 WINRT application resides in the Windows.UI.Xaml.Controls.Maps namespace.

below is the simple code snippet to add map control to the page.

<grid background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<grid margin="12,0,12,0">
<grid .rowdefinitions="">
<rowdefinition height="Auto">
<rowdefinition height="*">
</rowdefinition></rowdefinition></grid>
<textblock fontsize="30" grid.row="0" margin="0,12,0,12" text="My Maps" textwrapping="Wrap">
<maps:mapcontrol grid.row="1" mapservicetoken="Your Map service AuthenticationToken" maptapped="MyMap_MapTapped" x:name="MyMap">
</maps:mapcontrol></textblock></grid>
</grid>
** you need to use the Map service AuthenticationToken for the MapServiceToken property of the maps control .

There are many properties available on the Maps control which allows the developer to customize the behavior and also the look and feel of the maps when it renders ,

we will see how to work with some of the most commonly used properties .

we will see how to work with some of the most commonly used properties .

Set/Get the location in the map 

use the Center property of the maps to Set/Get the location in the map , the Center Property is of the type Geopoint .

MyMap.Center = new Geopoint(new BasicGeoposition() { Latitude = 100.604, Longitude = -12.329 });

** you can also use Databind to directly bind the value to the XAML control

Set/Get the Zoom Level in the map

you can Set/Get the zoom level of your map control with the ZoomLevel Property .

MyMap.ZoomLevel = 12;
** valid values are between 1 to 20.

Set/Get the Directional Heading of the map

You can Set/Get the Directional heading of the map control with the Heading Property .

MyMap.Heading = 360;
** valid values are North =360 or 0,East =90 ,South =180,West =270 .

Set/Get the Tilt of the map

You can use the DesiredPitch Property to check if your map is tilted an angle or you can also tile you map to a desired angle by setting a valid value to this property .

MyMap.DesiredPitch = 360;

** valid values are 0 to 65.

Update a new location in the map control

if you want to update the map with a new location you should use the MapControl.TrySetViewAsync method as shown below

await MyMap.TrySetViewAsync(new Geopoint(new BasicGeoposition { Latitude = 50, Longitude = -5.399780 }));

**the method has three over loads using which you can set other parameters of the Map control like zoomlevel,heading,pitch and map animation kind when the new location value is set for the map.

Thursday, December 18, 2014

Check your Network Connectivity WindowsPhone 8

In the nutshell you all you have to do is check the NetworkInterface.NetworkInterfaceType property which is a enum with values (none,MobileBroadBandCdma,MobileBroadBandGsm,Ethernet,Wireless80211) .

bool IsConnected = NetworkInterface.NetworkInterfaceType != NetworkInterfaceType.None;

you can subscribe to the NetworkChange.NetworkAddressChanged event to the Monitor the connection changes .

as simple as it looks there are a couple of gotcha's that you might want to take care of

  1. you  will want to  move the code block to monitor the network connection to a background thread a it might block the UI thread when checking  for the connection status .
  2. if the phone switches  the connection several times the NetworkAddressChanged is raised many times and it can again be issue if you are performing some time consuming task ,The Microsoft's Reactive Extension(Rx) comes in handy here , its a great framework with lot of goodies , in this case it lets to control the minimum interval  time before the NetworkAddressChanged, have used the Rx when implementing the search Contract in windows store apps where as a developer you  want to react to input typed into the search box in a timely manner (Link to Rx).
Below is the code Snippet which will check the current connection status and raises events when the connection status .
public class NetworkConnectionMonitor 
 {
  const int sampleRateMs = 1000;
  IDisposable subscription;

  public event EventHandler NetworkConnectionChanged;
  public NetworkConnectionType NetworkConnectionType  { get; private set; }

  public bool Connected
  {
   get
   {
    return NetworkConnectionType != NetworkConnectionType.None;
    //return System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
   }
  }

  public NetworkConnectionMonitor()
  {
   Update();

   var observable 
    = Observable.FromEvent(
     handler => new NetworkAddressChangedEventHandler(handler),
     handler => NetworkChange.NetworkAddressChanged += handler,
     handler => NetworkChange.NetworkAddressChanged -= handler);

   IObservable> sampler 
    = observable.Sample(TimeSpan.FromMilliseconds(sampleRateMs));

   subscription = sampler.ObserveOn(Scheduler.ThreadPool).Subscribe(
                args => Update());
  }
  
  void Update()
  {
   switch (NetworkInterface.NetworkInterfaceType)
   {
    case NetworkInterfaceType.None:
     NetworkConnectionType = NetworkConnectionType.None;
     break;
    case NetworkInterfaceType.MobileBroadbandCdma:
    case NetworkInterfaceType.MobileBroadbandGsm:
     NetworkConnectionType = NetworkConnectionType.MobileBroadband;
     break;
    case NetworkInterfaceType.Ethernet:
    case NetworkInterfaceType.Wireless80211:
    default:
     NetworkConnectionType = NetworkConnectionType.Lan;
     break;
   }

   Deployment.Current.Dispatcher.BeginInvoke(new Action(
    () => NetworkConnectionChanged.Raise(this, EventArgs.Empty)));
  }
 }
** Along with the above you might want to consdier one more important paramter when downloading/uploading content  from you app, that is the datacost when the user is connected to the mobile network , The DataSense API  allows you to query if the data connection in roaming ,is the user reaching the data plan limit / exceeded the limit, based on the result the app can decided if it can download the data or not .

ConnectionProfile connectionProfile = NetworkInformation.GetInternetConnectionProfile(); \
ConnectionCost = connectionProfile.GetConnectionCost(); 
if (connectionProfile.NetworkAdapter.IanaInterfaceType = = (int) IanaInterfaceTypes.Wifi 
| | connectionCost.NetworkCostType = = NetworkCostType.Unrestricted)
{
// no need to restrict data Transfer
}
if (connectionCost.Roaming | | connectionCost.OverDataLimit)
 { // Dont tranfer any data } 
 
 if (connectionCost.ApproachingDataLimit)
 { // may be you want to warn user }