Add a macOS project to your existing solution

With the new version of Xamarin, we can create apps for macOS. But how can I add a macOS project to my solution? I explain step by step what we have to do.

Add new project

The first step is to add a new project for macOS in your solution. Right-click on your solution and select Add New project... Step 1 - Add new project

Now select from the list App under Mac and then Cocoa App.Step 2 - Select project type

Then name your project, usually, we call this project with yourprojectname.macOS. Step 3 - Name your project

How you see in the preview, the name in the dock it is not very nice. Then we can change it: check Use a Different App Name in Dock and then type the app name.Step 4 - Change name for dock

At the end select the folder where you want to save your project, usually, in the root of your folder in the filesystem.Step 5 - Select project folder

Add packages

In your new project add under Packages Xamarin.Forms and all your other packages you are using in the other project.

Now we have to add the main project. Under References, select the main project and the other dependencies. Edit references

Update the code

Now the complicated part is starting. In your Info.plist file, we have to remove NSMainStoryboardFile.Edit Info.plist

Now in your macOS project, we have to delete Main.storyboard because we don't need it anymore. Right-click on Main.storyboard and then select Remove.

Main.storyboard in your projectMain.storyboard delete

Open your Main.cs and change the Main function with the following code:

static class MainClass
{
    static void Main(string[] args)
    {
        NSApplication.Init();
        NSApplication.SharedApplication.Delegate = new AppDelegate();
        NSApplication.Main(args);
    }
}

Open AppDelegate.cs and add at the top the following packages:

using Xamarin.Forms;
using Xamarin.Forms.Platform.MacOS;

You see now AppDelegate derives from NSApplicationDelegate. Change NSApplicationDelegate with FormsApplicationDelegate. Now you see that AppDelegate is underlined with a red line. We take care of that shortly.

Now add in the AppDelegate body 

NSWindow window;

We override MainWindow function (Visual Studio helps to create this function with the correct signature). As return, we use window.

public override NSWindow MainWindow
{
    get
    {
        return window;
    }
}

Now we have to display a window. For that we have to change AppDelegate(). For creating a window, we have to define its style and dimension.

public AppDelegate()
{
    var style = NSWindowStyle.Closable | NSWindowStyle.Resizable | 
                NSWindowStyle.Titled;
    var rect = new CoreGraphics.CGRect(100, 100, 1024, 768);

    window = new NSWindow(rect, style, NSBackingStore.Buffered, false);
    window.Title = "WordBank Easy";
    window.TitleVisibility = NSWindowTitleVisibility.Hidden;
}

The last thing to do, it is the inizialization of Xamarin.Forms and your app. We change now DidFinishLaunching

public override void DidFinishLaunching(NSNotification notification)
{
    Forms.Init();
    LoadApplication(new App());

    base.DidFinishLaunching(notification);
}

Pretty easy, isn't it? Here my complete code of AppDelegate.cs

using AppKit;
using Foundation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.MacOS;

namespace WordBankEasy.macOS
{
    [Register("AppDelegate")]
    public class AppDelegate : FormsApplicationDelegate
    {
        NSWindow window;

        public override NSWindow MainWindow
        {
            get
            {
                return window;
            }
        }

        public AppDelegate()
        {
            var style = NSWindowStyle.Closable | 
                        NSWindowStyle.Resizable | 
                        NSWindowStyle.Titled;
            var rect = new CoreGraphics.CGRect(100, 100, 1024, 768);

            window = new NSWindow(rect, style, NSBackingStore.Buffered, 
                                  false);
            window.Title = "WordBank Easy";
            window.TitleVisibility = NSWindowTitleVisibility.Hidden;
        }

        public override void DidFinishLaunching(
                                NSNotification notification)
        {
            Forms.Init();
            LoadApplication(new App());

            base.DidFinishLaunching(notification);
        }

        public override void WillTerminate(NSNotification notification)
        {
            // Insert code here to tear down your application
        }
    }
}

Happy coding!

Get the Most Out of iOS 11 with Visual Studio Tools for Xamarin

Join Craig Dunn explains what’s new in iOS 11 and how to take advantage of the latest updates – from drag-and-drop for iPad to machine learning and more – 100% in .NET and Visual Studio. Whether you’re building new or updating existing Xamarin.iOS apps, you’ll see how to implement new frameworks, APIs, and UI features, walk-through code samples, get expert tips and tricks, so you can start shipping iOS 11-ready apps to your users. In this webinar, you’ll:

  • Explore iOS 11 UI changes, including adapting to the iPhone X form factor
  • Dive into what .NET developers need to know about iOS 11
  • Add iOS 11 features to new and existing Xamarin apps with step-by-step examples
  • Ensure backwards compatibility with prior OS versions
  • Learn how to incorporate Azure Machine Learning tools into CoreML
  • Ask questions and receive guidance from our team of app experts

To develop for iOS 11, you'll need to have a machine that supports macOS Sierra and Xcode 9.

Download the source code of this video from GitHub.

Xamarin Forms: TranslateY (or other properties) for platform

Sometimes you need to change a value for a specific platform and this value is a Double, for example. I spent a couple of minutes to find a working code.

<Label>
    <Label.TranslationY>
        <OnPlatform x:TypeArguments="x:Double" Android="-10" />
    </Label.TranslationY>
</Label>

Happy coding!

Enable and control iOS 11 Large Titles in Xamarin.Forms

Apple introduced with iOS 11 a new UI in particular for larger titles: if you open your email, you see at the top a large title. That sit in the Navigation Bar and can be scrolled away when more space is needed. We can enable large titles with a renderer.

For this example, I only created a new project and added the following renderer in the iOS project under Renderers folder. You can easily add to all your solution the following renderer in your iOS project:

using System;
using YourProject.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(NavigationPage), 
                          typeof(CustomNavigationRenderer))]
namespace YourProject.iOS.Renderers
{
    public class CustomNavigationRenderer : NavigationRenderer
    {
        protected override void OnElementChanged(
                                VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            // Enables iOS 11 new Large Titles system-wide
            if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
            {
                // Enable Large Titles
                NavigationBar.PrefersLargeTitles = true;

                // Adopt same TextAttributes as for normal titles
                // beacuse Xamarin.Forms NavigationPage
                // does not have a dedicated property for this yet
                UINavigationBar.Appearance.LargeTitleTextAttributes =
                    new UIStringAttributes { 
                            ForegroundColor = 
                               (Element as NavigationPage)?.
                               BarTextColor.ToUIColor() };
            }
        }
    }
}

iOS 8 Screenshot - Large title

Happy coding!

UriBuilder in Xamarin Forms

In Xamarin Forms there is a native function called UriBuilder: it allow you to create a well-formed url. In my implementation, all parameters are in a Dictionary called parameters. Using Linq, I put in builder.Query only the parameters with a value.

UriBuilder builder = new UriBuilder(yourUrl);

Dictionary<string, string> parameters = 
                              new Dictionary<string, string>();
parameters.Add("reference", Reference);
parameters.Add("param1", Param1);

builder.Query = 
    string.Join("&", 
        parameters.Where(p => !string.IsNullOrWhiteSpace(p.Value))
                  .Select(p => string.Format("{0}={1}", 
                                      Uri.EscapeDataString(p.Key), 
                                      Uri.EscapeDataString(p.Value))));
return builder.ToString();

Happy coding!

Binding FormattedString for Xamarin Forms

Xamarin Forms doesn't have a Label with a Bindable FormattedString. For example, if you want a bindable bold word in the middle of a sentence in a Label, it's very hard to design it with common control. For that, I create my own component for that.

LabelRenderer.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

namespace PSC.Controls
{
    public class Label : Xamarin.Forms.Label
    {
        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
            UpdateFormattedTextBindingContext();
        }

        protected override void OnPropertyChanged(
           [CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);

            if (propertyName == FormattedTextProperty.PropertyName)
                UpdateFormattedTextBindingContext();
        }

        private void UpdateFormattedTextBindingContext()
        {
            var formattedText = this.FormattedText as FormattedString;

            if (formattedText == null)
                return;

            foreach (var span in formattedText.BindableSpans)
                span.BindingContext = this.BindingContext;
        }
    }

    [ContentProperty("BindableSpans")]
    public class FormattedString : Xamarin.Forms.FormattedString
    {
        private ObservableCollection<Span> _bindableSpans = 
            new ObservableCollection<Span>();

        public IList<Span> BindableSpans { 
            get { return this._bindableSpans; } 
        }

        public FormattedString()
        {
            this._bindableSpans.CollectionChanged += OnCollectionChanged;
        }

        private void OnCollectionChanged(object sender, 
            NotifyCollectionChangedEventArgs e)
        {
            if (e.OldItems != null)
            {
                foreach (var bindableSpan in e.OldItems.Cast<Span>())
                    base.Spans.Remove(bindableSpan);
            }
            if (e.NewItems != null)
            {
                foreach (var bindableSpan in e.NewItems.Cast<Span>())
                    base.Spans.Add(bindableSpan);
            }
        }

        /// <param name="text">To be added.</param>
        /// <summary>
        /// Cast a string to a FromattedString that contains 
        /// a single span with no attribute set.
        /// </summary>
        /// <returns>To be added.</returns>
        public static implicit operator FormattedString(string text)
        {
            return new FormattedString
            {
                BindableSpans = { 
                    new Span { Text = text ?? "" } 
                }
            };
        }
        /// <param name="formatted">To be added.</param>
        /// <summary>
        /// Cast the FormattedString to a string, 
        /// stripping all the attributes.
        /// </summary>
        /// <returns>To be added.</returns>
        public static explicit operator string(FormattedString formatted)
        {
            return formatted.ToString();
        }
    }

    [ContentProperty("Text")]
    public sealed class Span : BindableObject
    {
        Xamarin.Forms.Span _innerSpan;

        public Span() : this(new Xamarin.Forms.Span()) { }

        public Span(Xamarin.Forms.Span span)
        {
            _innerSpan = span;
            // important for triggering property inheritance from parent Label
            this.BackgroundColor = this._innerSpan.BackgroundColor;
            this.FontSize = this._innerSpan.FontSize;
            this.FontAttributes = this._innerSpan.FontAttributes;
            this.FontFamily = this._innerSpan.FontFamily;
            this.ForegroundColor = this._innerSpan.ForegroundColor;
            this.Text = this._innerSpan.Text ?? "";
        }
        public static readonly BindableProperty BackgroundColorProperty =
            BindableProperty.Create(nameof(BackgroundColor), 
                typeof(Color), typeof(Span), Color.Default);

        public Color BackgroundColor
        {
            get { return (Color)GetValue(BackgroundColorProperty); }
            set { SetValue(BackgroundColorProperty, value); }
        }

        public static readonly BindableProperty FontAttributesProperty =
            BindableProperty.Create(nameof(FontAttributes), 
                typeof(FontAttributes), 
                typeof(Span), 
                FontAttributes.None);

        public FontAttributes FontAttributes
        {
            get { return (FontAttributes)GetValue(FontAttributesProperty); }
            set { SetValue(FontAttributesProperty, value); }
        }

        public static readonly BindableProperty FontFamilyProperty =
            BindableProperty.Create(nameof(FontFamily), 
                typeof(string), 
                typeof(Span), 
                string.Empty);

        public string FontFamily
        {
            get { return (string)GetValue(FontFamilyProperty); }
            set { SetValue(FontFamilyProperty, value); }
        }

        public static readonly BindableProperty FontSizeProperty =
            BindableProperty.Create(nameof(FontSize), 
                typeof(double), 
                typeof(Span), -1.0, BindingMode.OneWay, 
                null, null, null, null, 
                bindable => Device.GetNamedSize(
                    NamedSize.Default, typeof(Label)));

        [TypeConverter(typeof(FontSizeConverter))]
        public double FontSize
        {
            get { return (double)GetValue(FontSizeProperty); }
            set { SetValue(FontSizeProperty, value); }
        }

        public static readonly BindableProperty 
            ForegroundColorProperty =
                BindableProperty.Create(nameof(ForegroundColor), 
                   typeof(Color), 
                   typeof(Span), 
                   Color.Default);

        public Color ForegroundColor
        {
            get { return (Color)GetValue(ForegroundColorProperty); }
            set { SetValue(ForegroundColorProperty, value); }
        }

        public static readonly BindableProperty TextProperty =
            BindableProperty.Create(nameof(Text), 
                                    typeof(string), 
                                    typeof(Span), 
                                    string.Empty);

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public Xamarin.Forms.Span InnerSpan { 
            get { return _innerSpan; } 
        }

        protected override void OnPropertyChanged(
            [CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);
            _innerSpan.BackgroundColor = this.BackgroundColor;
            _innerSpan.FontSize = this.FontSize;
            _innerSpan.FontAttributes = this.FontAttributes;
            _innerSpan.FontFamily = this.FontFamily;
            _innerSpan.ForegroundColor = this.ForegroundColor;
            _innerSpan.Text = this.Text ?? "";
        }

        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
        }

        public static implicit operator Xamarin.Forms.Span(Span bindableSpan)
        {
            return bindableSpan.InnerSpan;
        }

        public static implicit operator Span(
            Xamarin.Forms.Span span)
        {
            return new Span(span);
        }
    }
}

In your XAML you use this control like that:

<ctl:Label
    FontSize="Small"
    TextColor="#333"
    HorizontalOptions="FillAndExpand">
    <Label.FormattedText>
        <ctl:FormattedString>
            <ctl:Span Text="{Binding YourVar1}" FontAttributes="Bold"/>
            <ctl:Span Text="{Binding YourVar2, StringFormat=' {0}'}"/>
        </ctl:FormattedString>
    </Label.FormattedText>
</ctl:Label>

Download the code from GitHub.

Happy coding!

Xamarin Forms Repeater View

A ListView is a kind of repeater but isn’t always what I want. It’s surprising something like this isn’t included in the framework but making your own is fairly simple.

namespace PSC.Controls
{
    /// <summary>
    /// Repeater view.
    /// </summary>
    public class RepeaterView : StackLayout
    {
        /// <summary>
        /// The item template property.
        /// </summary>
        public static readonly BindableProperty ItemTemplateProperty = 
                BindableProperty.Create(
                    "ItemTemplate",
                    typeof(DataTemplate),
                    typeof(RepeaterView),
                    null,
                    propertyChanged: (bindable, value, newValue) => 
                        Populate(bindable));

        /// <summary>
        /// The items source property.
        /// </summary>
        public static readonly BindableProperty ItemsSourceProperty = 
            BindableProperty.Create(
                "ItemsSource",
                typeof(IEnumerable),
                typeof(RepeaterView),
                null,
                BindingMode.OneWay,
                propertyChanged: (bindable, value, newValue) => 
                  Populate(bindable));

        /// <summary>
        /// Gets or sets the items source.
        /// </summary>
        /// <value>The items source.</value>
        public IEnumerable ItemsSource
        {
            get => (IEnumerable)this.GetValue(ItemsSourceProperty);
            set => this.SetValue(ItemsSourceProperty, value);
        }

        /// <summary>
        /// Gets or sets the item template.
        /// </summary>
        /// <value>The item template.</value>
        public DataTemplate ItemTemplate
        {
            get => (DataTemplate)this.GetValue(ItemTemplateProperty);
            set => this.SetValue(ItemTemplateProperty, value);
        }

        /// <summary>
        /// Populate the specified bindable.
        /// </summary>
        /// <returns>The populate.</returns>
        /// <param name="bindable">Bindable.</param>
        private static void Populate(BindableObject bindable)
        {
            var repeater = (RepeaterView)bindable;

            // Clean
            repeater.Children.Clear();

            // Only populate once both properties are received
            if (repeater.ItemsSource == null || 
                repeater.ItemTemplate == null)
                return;

            foreach (var viewModel in repeater.ItemsSource)
            {
                var content = repeater.ItemTemplate.CreateContent();
                if (!(content is View) && !(content is ViewCell))
                {
                    throw new Exception(
                          $"Invalid visual object {nameof(content)}");
                }

                var view = content is View ? content as View : 
                                             ((ViewCell)content).View;
                view.BindingContext = viewModel;

                repeater.Children.Add(view);
            }
        }
    }
}



The view is based on StackLayout which will take care of positioning the items.

There are a couple of bindable properties – ItemTemplate for the item layout and ItemsSource which provides the items. Note that ItemsSource hooks an action to PropertyChanging – I’ll come back to this later on.

Usage in XAML is similar to ListView, with an ItemTemplate, DataTemplate, and ViewCell.

<ui:Repeater x:Name="MainRepeater">
    <ui:Repeater.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal">
                    <Label Text="{Binding Title}" 
                           HorizontalOptions="StartAndExpand" 
                           VerticalTextAlignment="Center"/>
                    <Button Text="Select" />
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ui:Repeater.ItemTemplate>
</ui:Repeater>

Don't forget to define ui

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:ui="clr-namespace:PSC.Controls;assembly=PSC.Controls">

Xamarin, no show images in the device but only in the simulator

In my project I have some images to display. The funny thing is I can see images in the simulator but not in a real device.

Simulator

Simulator-Screen Shot

iPhone (real device)

iPhone-Screenshot

Solution

iPhone is case-sensitive and the name of your images must be specified correctly. iOS Simulator probably is not case-sensitive and then it displays images with every name.

Xamarin Forms and FingerPrint (iOS and Android only)

In this post I explain how to use Finger Print in your app. This app is working only in iOS or Android.

Add NuGet

In your solution, you have to add a package called Plugin.Fingerprint.

XamarinForms Fingerprint Nuget

Only for Android, in your Droid project add another package called Plugin.CurrentActivity. Also, you have to add a permission for fingerprint (and one specific for Samsung).

<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission 
       android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />

Implementation

Now we implement in our PCL project the request for fingerprint. First of all we have to check if a device supports fingerprints. If yes, we show the typical dialog.

XamarinForms Finferprint Dialog

Now I added a button in the XAML and its name is buttonFingerPrint. For it in the code behind, I added a Clicked event. Then In the new function, I'm checking is the device supports fingerprint.

var result = await CrossFingerprint.Current.IsAvailableAsync(true);

The function IsAvailableAsync as true as parameter but it is useful only for iOS to have a code in return. If the device supports fingerprint, I'll show a dialog request with this code:

if (result) {
    var auth = await CrossFingerprint.Current
               .AuthenticateAsync("Authenticate access to fingerprint");
    if (auth.Authenticated) {
        await DisplayAlert("Whoooowhooo!", "Authentication is done!", "Ok");
    }
    else {
        await DisplayAlert("Something wrong", 
                           "There is a problem with your finger", "Ok");
    }
}
else {
    await DisplayAlert("Finger print not available", 
                       "You can't use your finger for using this app", "Ok");
}

Testing on an emulator

iOS

If you test your project in an iOS device, be careful to allow to use Touch ID from Hardware menu with Toggle Enrolled State. When you want to test your virtual finger, select Matching Touch.

XamarinForms Fingerprint iOS Emulator

Android

Let's go to the Android emulator. You need to set up fingerprint under Settings. From your Terminal call (5554 is the default port of an Android emulator but it can be different in your computer)

telnet 127.0.0.1 5554

Then you have to copy an auth token from an hidden file called .emulator_console_auth_token in your profile. In the terminal execute

auth <yourcode>

Now open Settings > Security > Fingerprint and follow the instruction. When you have to recognise your finder, come back to the terminal and type

finger touch 1

Then you can continue with the wizard.

Now you can execute your app. When your app ask your fingerprint, come back to the Terminal and type again

finger touch 1

Android is always easy to use! You find my solution on GitHub.

Happy coding!

Xamarin, Android and starting a service at device boot

In my previous post called Xamarin: how to Start an Application at Device Boot in Android, I explained how you can change your Android Xamarin's project to launch your app at the device boot.

It is a good start but my problem was a bit more complex. I want to create a background service to track the geolocation of a device. I googled a lot to find a solution without a great success. Then I started to implement my code with some tests. Finally, I found a good way and I'm sharing with you it.

Create a Broadcast Receiver

What is a Broadcast Receiver

A broadcast receiver is a component that responds to system-wide broadcast announcements. Many broadcasts originate from the system—for example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More commonly, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work.

How to implement a Broadcast Receiver

I show you now two implementations of it:

  • BootReceiver: this receiver is responsible to do something when a device starts. For that, we have to allow the app to read this event. In your AndroidManifest.xml you must add a permission called RECEIVE_BOOT_COMPLETED.
  • AirplaneModeReceiver: this receiver filters only the broadcast for ActionAirplaneModeChanged.

I start to show you the second one because it is more simple.

	[BroadcastReceiver]
    [IntentFilter(new[] { Android.Content.Intent.ActionAirplaneModeChanged })]
	public class AirplaneModeReceiver : BroadcastReceiver
	{
		private static readonly string TAG = typeof(AirplaneModeReceiver).FullName;

		public override void OnReceive(Context context, Intent intent)
		{
			Log.WriteLine(LogPriority.Debug, TAG, "AirplaneModeReceiver OnReceive Mode " + 
                          isAirplaneModeOn(context));
		}

		private static bool isAirplaneModeOn(Context context)
		{
			var airplane = Android.Provider.Settings.Global.GetInt(context.ContentResolver, 
                           Android.Provider.Settings.Global.AirplaneModeOn);
			return airplane != 0;
		}
	}

Although you can find a lot of posts where people said that you have to declare your broadcast in the AndroidManifest, I discover if I add the broadcast in the AndroidManifest, the broadcast won't work.

This is the first broadcast. Basically when a user taps on AirPlaneMode, this broadcast receives the status with isAirplaneModeOn function and writes this change in the logs.

BootReceiver is more interesting. When a device is booting, this broadcast starts a service to track the position. Also, in my code you find TimeService: I use this service to check if the service is starting properly and the notification is working and updating.

    [BroadcastReceiver]
    [IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
    public class BootReceiver : BroadcastReceiver
    {
        private static readonly string TAG = typeof(BootReceiver).FullName;

        public override void OnReceive(Context context, Intent intent)
        {
            Log.WriteLine(LogPriority.Debug, TAG, "BootReceiver OnReceive");

            Intent i = new Intent(context, typeof(GPSService));
            i.AddFlags(ActivityFlags.NewTask);
            context.StartService(i);
            Log.WriteLine(LogPriority.Debug, TAG, 
                          "BootReceiver OnReceive LocationService started");

			i = new Intent(context, typeof(TimerService));
			i.AddFlags(ActivityFlags.NewTask);
			context.StartService(i);
			Log.WriteLine(LogPriority.Debug, TAG, 
                          "BootReceiver OnReceive TimerService started");
		}
    }

The interesting part of this code is when I start a service. Basically, I define a new Intent with the type of service I want to call, then I start the service with the context.

Although you find a lot of posts on line, the right way to define a service in your AndroidManifest is the following:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="pro.wordbank.app.locationtest">
	<uses-sdk android:minSdkVersion="15" />
	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
	<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
	<uses-permission android:name="android.permission.INTERNET" />
	<application android:label="LocationTest">
		<service android:name=".TimerService" />
        <service android:name=".LocationService" />
	</application>
</manifest>

I have publish a complete solution of that on GitHub. Happy coding!

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin




TagCloud

MonthList