Introduction In this article, we will learn how to create Multi-Item Selection Picker Control in Xamarin.Forms. To achieve this, I have cr...

Multiple Item Selection Picker in Xamarin.Forms Multiple Item Selection Picker in Xamarin.Forms

A blog about android developement

Introduction

In this article, we will learn how to create Multi-Item Selection Picker Control in Xamarin.Forms. To achieve this, I have created a common control will open the selection on clicking the control like the picker control. Without making any further delay, we will see the steps one by one to implement the multi-item selection control.

Multi Item Selection Picker

Basically, I am creating a new custom control inherited with Entry control, which will focus the picker when the focused. The Multi-Item Selection Picker listing is nothing but a content page with list view control has the check box template. Also, I have used await able content page which will return the data when the page closes.

Without much introduction, we will skip into the coding part of this article.

Coding Part

Steps

Here, I will explain the steps to create Multi Item Selection Picker in Xamarin.Forms.

Step 1: Creating new Xamarin.Forms Projects.

Step 2: Creating a custom control view in Xamarin.Forms .NetStandard Project

Step 3: Creating the Custom Checkbox listing page.

Step 4: Implementation of Multi Item Selection Picker & It’s Demo.

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New à Project à Select Xamarin Cross Platform App and Click OK.

Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.


Step 2: Creating a custom control view in Xamarin.Forms .NetStandard Project

  1. Create a class named as “MultiSelectionPicker” and inherit with “Entry” to have the basic properties like Placeholder, Focused & Unfocused event.
  2. Then we will create a required bindable properties. First we will see, what are all the properties & events required for dropdown.
    public class  MultiSelectionPicker : Entry
    {
    
          //...
    
    }
    1. ItemsSource – To assign the list of data to be populated in the picker.
    2. SelectedIndices – To identify the index of selected values from the ItemsSource.
    3. Title – To set the title for the control page
  3. Create a bindable property for the ItemsSource as shown in below.
    public static readonly BindableProperty ItemsSourceProperty =           BindableProperty.Create("ItemsSource", typeof(List<string>), typeof(MultiSelectionPicker), null, BindingMode.TwoWay);
    public List<string> ItemsSource
    {
        get { return (List<string>)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }
  4. Create a bindable property for the SelectedIndices as shown in below.
    public static readonly BindableProperty SelectedIndicesProperty = BindableProperty.Create("SelectedItems", typeof(List<int>), typeof(MultiSelectionPicker), null, BindingMode.TwoWay,
        propertyChanged: SelectedIndexChanged);
    
    public List<int> SelectedIndices
    {
        get { return (List<int>)GetValue(SelectedIndicesProperty); }
        set { SetValue(SelectedIndicesProperty, value); }
    }
  5. Create a bindable property for the Title as shown in below.
    public static readonly BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(string), typeof(MultiSelectionPicker), null);
    public string Title
    {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
    } 

Step 3: Creating the Custom Checkbox listing page.

In this step, we will see How to design the picker and awaitable page to return result when the screen closed by the user.

  1. Create await able content page by using the following code block which is base page for the checkbox listing page.
    public class BasePage<T> : ContentPage
    {
        public event Action<T> PageDisappearing;
        protected T _navigationResut;
    
        public BasePage()
        {
    
        }
    
        protected override void OnDisappearing()
        {
            PageDisappearing?.Invoke(_navigationResut);
            if (PageDisappearing != null)
            {
                foreach (var @delegate in PageDisappearing.GetInvocationList())
                {
                    PageDisappearing -= @delegate as Action<T>;
                }
            }
            base.OnDisappearing();
        }
    }
    
    Here, T is nothing but the template which will be any data type like string, bool and so.
  2. Create a xaml file named as CheckboxPage.xaml. Set step 1 created page as a base page.
  3. Then paste the following code xaml and xaml.cs file where the data type is string. Refer the below codes for the screen design and property assignments.
<?xml version="1.0" encoding="utf-8" ?>
<pages:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
                xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                xmlns:pages="clr-namespace:Xamarin.Forms"
                x:Class="Xamarin.Forms.CheckboxPage"
                x:TypeArguments="x:String">
    <ContentPage.Content>
        <StackLayout Padding="5">
            <ListView x:Name="listView"
                      ItemTapped="listView_ItemTapped"
                      SeparatorVisibility="None"
                      VerticalScrollBarVisibility="Never"
                      HorizontalScrollBarVisibility="Never">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
                                <Label Text="{Binding Text}" VerticalOptions="Center" HorizontalOptions="StartAndExpand"/>
                                <CheckBox IsChecked="{Binding IsChecked}" HorizontalOptions="EndAndExpand" Color="Black"/>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <StackLayout HorizontalOptions="End"
                         Orientation="Horizontal">
                <Button Text="Cancel" Clicked="Cancel_Clicked" HorizontalOptions="Center" VerticalOptions="End" BackgroundColor="Transparent"/>
                <Button Text="Done" Clicked="Done_Clicked" HorizontalOptions="Center" VerticalOptions="End" BackgroundColor="Transparent"/>
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
</pages:BasePage>
  1. The above code contains the cancel and done button for cancelling and updating the picker selection.
public partial class CheckboxPage : BasePage<string>
{
    private List<CheckedItem> ItemsSource;
    public CheckboxPage(List<string> itemsSource, List<int> selectedIndices)
    {
        InitializeComponent();
        List<CheckedItem> list = new List<CheckedItem>();
        for (int i = 0; i < itemsSource.Count; i++)
        {
            list.Add(new CheckedItem()
            {
                Text = itemsSource[i],
                IsChecked = false,
                Position = i
            });
        }
        ItemsSource = list;
        foreach (int i in selectedIndices)
        {
            list[i].IsChecked = true;
        }
        listView.ItemsSource = list;
    }

    private void listView_ItemTapped(object sender, ItemTappedEventArgs e)
    {
        ((ListView)sender).SelectedItem = null;
    }

    private void Done_Clicked(object sender, EventArgs e)
    {
        List<CheckedItem> list = (List<CheckedItem>)listView.ItemsSource;
        _navigationResut = string.Join(",", list.Where(x => x.IsChecked).Select(x => x.Position).ToArray());
        Navigation.PopModalAsync();
    }

    private void Cancel_Clicked(object sender, EventArgs e)
    {
        //List<CheckedItem> list = ItemsSource;
        _navigationResut = "";// string.Join(",", list.Where(x => x.IsChecked).Select(x => x.Position).ToArray());
        Navigation.PopModalAsync();
    }
}

public class CheckedItem
{
    public int Position { get; set; }
    public bool IsChecked { get; set; }
    public string Text { get; set; }
}
  1. After that, go to the custom control “Multiselectionpicker.cs” and create the following function which will open the page a modal page with TaskCompletionSource.
public async Task<T> NavigateToModal<T>(BasePage<T> page)
{
    var source = new TaskCompletionSource<T>();
    page.PageDisappearing += (result) =>
    {
        var res = (T)Convert.ChangeType(result, typeof(T));
        source.SetResult(res);
    };
    await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
    return await source.Task;
}
  1. Create focused event in the multiselectpicker and call the above mentioned function
Focused += async (e, s) =>
{
    if (s.IsFocused)
    {
        Unfocus();
        string item = await NavigateToModal<string>(new CheckboxPage(ItemsSource, SelectedIndices));
        if (item == "")
            return;
    }
};
  1. In the focused event, get the selection indexes and assign to the entry with comma separator.
Focused += async (e, s) =>
{
    if (!IsControlLoaded && Device.RuntimePlatform == Device.UWP)
    {
        IsControlLoaded = true;
        Unfocus();
        return;
    }
    if (s.IsFocused)
    {
        Unfocus();
        string item = await NavigateToModal<string>(new CheckboxPage(ItemsSource, SelectedIndices));
        if (item == "")
            return;
        SelectedIndices = item.Split(',').Select(x => Convert.ToInt32(x)).ToList();
        List<string> selectedItems = new List<string>();
        foreach (int i in SelectedIndices)
        {
            selectedItems.Add(ItemsSource[i]);
        }
        Text = string.Join(", ", selectedItems);
    }
};

Full Code of MultiSelectPicker.cs

namespace Xamarin.Forms
{
    public class MultiSelectionPicker : Entry
    {
        public static readonly BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(string), typeof(MultiSelectionPicker), null);
        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }
        public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource", typeof(List<string>), typeof(MultiSelectionPicker), null, BindingMode.TwoWay);
        public List<string> ItemsSource
        {
            get { return (List<string>)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }
        public static readonly BindableProperty SelectedIndicesProperty = BindableProperty.Create("SelectedItems", typeof(List<int>), typeof(MultiSelectionPicker), null, BindingMode.TwoWay,
            propertyChanged: SelectedIndexChanged);

        public List<int> SelectedIndices
        {
            get { return (List<int>)GetValue(SelectedIndicesProperty); }
            set { SetValue(SelectedIndicesProperty, value); }
        }

        private static void SelectedIndexChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var ctrl = (MultiSelectionPicker)bindable;
            if (ctrl == null)
                return;
            List<string> selectedItems = new List<string>();
            foreach (int i in ctrl.SelectedIndices)
            {
                selectedItems.Add(ctrl.ItemsSource[i]);
            }
            ctrl.Text = string.Join(", ", selectedItems);
        }

        bool IsControlLoaded = false;

        public MultiSelectionPicker()
        {
            Focused += async (e, s) =>
            {
                if (!IsControlLoaded && Device.RuntimePlatform == Device.UWP)
                {
                    IsControlLoaded = true;
                    Unfocus();
                    return;
                }
                if (s.IsFocused)
                {
                    Unfocus();
                    string item = await NavigateToModal<string>(new CheckboxPage(ItemsSource, SelectedIndices));
                    if (item == "")
                        return;
                    SelectedIndices = item.Split(',').Select(x => Convert.ToInt32(x)).ToList();
                    List<string> selectedItems = new List<string>();
                    foreach (int i in SelectedIndices)
                    {
                        selectedItems.Add(ItemsSource[i]);
                    }
                    Text = string.Join(", ", selectedItems);
                }
            };
        }

        public async Task<T> NavigateToModal<T>(BasePage<T> page)
        {
            var source = new TaskCompletionSource<T>();
            page.PageDisappearing += (result) =>
            {
                var res = (T)Convert.ChangeType(result, typeof(T));
                source.SetResult(res);
            };
            await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
            return await source.Task;
        }
    }

    public class BasePage<T> : ContentPage
    {
        public event Action<T> PageDisappearing;
        protected T _navigationResut;

        public BasePage()
        {

        }

        protected override void OnDisappearing()
        {
            PageDisappearing?.Invoke(_navigationResut);
            if (PageDisappearing != null)
            {
                foreach (var @delegate in PageDisappearing.GetInvocationList())
                {
                    PageDisappearing -= @delegate as Action<T>;
                }
            }
            base.OnDisappearing();
        }
    }
}

Step 4: Implementation of Multi Item Selection Picker & It’s Demo.

In this step, we will see how to use the view in Xamarin.Forms.

  1. Open your designer file and in my case MainPage.xaml and add the control as shown below.
<control:MultiSelectionPicker x:Name="picker" BackgroundColor="White"/>
  1. Set ItemsSource and SelectedIndices as shown in below.
picker.ItemsSource = new List<string>() { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6" };
picker.SelectedIndices = new List<int>() { 2,4,5 };

Demo



Download Code

You can download the full source code from GitHub. If you like this article, do like, share and star the repo in GitHub.


Introduction: In this tutorial, we will learn how to implement Gradient view in Xamarin.Forms with very simple steps. To achieve the gr...

Gradient View in Xamarin.Forms using Magic Gradients Gradient View in Xamarin.Forms using Magic Gradients

A blog about android developement



Introduction:

In this tutorial, we will learn how to implement Gradient view in Xamarin.Forms with very simple steps. To achieve the gradient view, we are using Magic Gradients plugin for Xamarin Forms. Magic Gradients is a NuGet that provide a possibility to add beautiful and enhanced gradients into Xamarin.Forms applications. It supports all common Xamarin platforms, such as Android, iOS and UWP. It is built upon SkiaSharp to draw a simple multi-color or multi-layer engaged gradients. Without further delay, we will skip into the coding part of the article.

Magic Gradient:

Magic Gradients provides GradientView control which is just a surface for SkiaSharp inside. Inside GradientView you need to set GradientSource which is a default container. Inside it you can place single gradients LinearGradient, RadialGradient or multiple gradients with GradientCollection as a top element.

Coding Part:

Steps:

I have split the coding part into 3 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Setting up the libraries.
  3. Implementation of the Gradient Views

Step 1: Creating new Xamarin.Forms Projects

  • Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
  • Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Setting up the libraries

  • We need to install the NuGet package for Magic Gradients by using any of the below methods.
    1. Search for MagicGradients in NuGet browser.
    2. Using Package Manager CLI: “Install-Package MagicGradients”.
    3. Using the .Net CLI: “dotnet add package MagicGradients”.
    4. Editing your csproj file by adding the following and restoring the project.
    <PackageReference Include="MagiGradients" Version="1.0.0" />
  • We should install it only for our "Core" project.

Step 3: Implementation of the Gradient Views

  • Open your designer file and add the following namespace for magic gradient view.
    xmlns:magic="clr-namespace:MagicGradients;assembly=MagicGradients"
  • After that we can using Magic Gradients as like in the following code snippet. Inside it you can place single gradients LinearGradient, RadialGradient or multiple gradients with GradientCollection as a top element.
  • Here, we have taken LinearGradient as an example.
    <magic:GradientView VerticalOptions="FillAndExpand">
        <magic:GradientView.GradientSource>
            <magic:LinearGradient Angle="90">
                <magic:GradientStop Color="Orange" Offset="0" />
                <magic:GradientStop Color="#ff0000" Offset="0.6" />
            </magic:LinearGradient>
        </magic:GradientView.GradientSource>
    </magic:GradientView>
  • We can use gradient collection for more than one gradient sources like below.
    <magic:GradientView VerticalOptions="FillAndExpand">
        <magic:GradientView.GradientSource>
            <magic:GradientCollection>
                <magic:LinearGradient Angle="45">
                    <magic:GradientStop Color="Orange" Offset="0" />
                    <magic:GradientStop Color="#ff0000" Offset="0.6" />
                </magic:LinearGradient>
                <magic:LinearGradient Angle="90">
                    <magic:GradientStop Color="#33ff0000" Offset="0.4" />
                    <magic:GradientStop Color="#ff00ff00" Offset="1" />
                </magic:LinearGradient>
            </magic:GradientCollection>
        </magic:GradientView.GradientSource>
    </magic:GradientView>

Output

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Introduction: In this tutorial, we will learn how to implement Multi-Lingual in Xamarin.Forms without using external plugins or platfor...

Multilingual Implementation - Xamarin.Forms Multilingual Implementation - Xamarin.Forms

A blog about android developement



Introduction:

In this tutorial, we will learn how to implement Multi-Lingual in Xamarin.Forms without using external plugins or platform wise implementation with dependency service. The latest Xamarin forms offers .net standard to implement the multilingual and without further delay, we will skip into the coding part of the article.

Coding Part:

Steps:

I have split the coding part into 4 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Creating App Resource files for multi-language.
  3. Language Management
  4. Implementation of Multi-Lingual.

Step 1: Creating new Xamarin.Forms Projects

  • Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
  • Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Creating App Resource files for multi-language

  • Add one resource file as base file with the name your preferred name. In my case, I kept the name of the file as “AppResources.resx” and it will be used as default language file.
  • Then add one resource file for each language you want to support. We must follow a specific naming convention for each file as the base resources file followed by a period (.) and then the language code.
  • For Example
    Language Language Code File Name
    Tamil ta AppResources.ta.resx
    French fr AppResources.fr.resx

  • Then add resources with the same name with language specific values in each resource files as like in the below screenshot.

Step 3: Language Management

In this step, we will see how to handle the multilingual for Xamarin.Forms.

  • Get Device Language
    CultureInfo.InstalledUICulture
  • Get or Set the actual language
    CultureInfo language = new CultureInfo("ta");
    Thread.CurrentThread.CurrentUICulture = language;
    AppResources.Culture = language;

Step 4: Implementation of Multi-Lingual

  • Open your designer file and add the resources as shown in below code snippet.
    <?xml version="1.0" encoding="utf-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:resource="clr-namespace:MultilingualXFSample.Resources"
                 x:Class="MultilingualXFSample.MainPage">
            <Label Text="{x:Static resource:AppResources.WelcomeText}"
                   FontSize="Large"/>
    </ContentPage>
  • By default, the app will take the base resource file. By passing the language code will takes the language specific resource file and we can set the language as shown in below code snippet in runtime
    CultureInfo language = new CultureInfo("ta");
    Thread.CurrentThread.CurrentUICulture = language;
    AppResources.Culture = language;
    Application.Current.MainPage = new NavigationPage(new MainPage());

Output

Default - English Tamil French

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Introduction In this tutorial, we will learn how to handle the Placeholder issue in Xamarin.Forms for Picker Control. Xamarin.Forms Picker...

Placeholder for Picker - Xamarin.Forms Placeholder for Picker - Xamarin.Forms

A blog about android developement

Introduction

In this tutorial, we will learn how to handle the Placeholder issue in Xamarin.Forms for Picker Control. Xamarin.Forms Picker Control is a combination of EditText plus AlertDialog for Android and UITextField plus UIPicker for iOS. The Title property of Xamarin.Forms Picker Control is a property to set title for AlertDialog plus Hint for EditText for Android and Placeholder for UITextField.

For Example, we are setting the title property of the picker control is “Title” and it has items source and selected index of the control as “-1” then the control will shows “Title” in Placeholder and title of the alert or popup. Sometimes, it is meaning less to use this control due to this.

To avoid this issue, I have created a customer render for Android and iOS to override this default behavior of picker. Without much delay, we will skip into the coding part of the article.

Coding Part:

Steps:

I have split the coding part into 5 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Creating Custom Picker inherited from picker.
  3. Custom Renderer for Custom Picker in Android.
  4. Custom Renderer for Custom Picker in iOS.
  5. Implementation of the Custom Picker Control.

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Creating Custom Picker inherited from picker

  1. Create a Custom Picker Control class named as “PLPicker” and it is inherited from Xamarin.Forms Picker.
  2. Create a property for Placeholder and is named as Placeholder like below.
    public class PLPicker : Picker
    {
        public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(
            propertyName: nameof(Placeholder),
            returnType: typeof(string),
            declaringType: typeof(string),
            defaultValue: string.Empty);
    
        public string Placeholder
        {
            get { return (string)GetValue(PlaceholderProperty); }
            set { SetValue(PlaceholderProperty, value); }
        }
    
    }

Step 3: Custom Renderer for Custom Picker in Android

In this step, we will create a custom renderer in Android for PLPicker created in “Step 2”.

  1. Create a class named as “PLPickerRenderer.cs” and it is inherited from “Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer”.
  2. Then create a method “UpdatePickerPlaceholder” and copy the below code in the custom renderer class.
    void UpdatePickerPlaceholder()
    {
        if (picker == null)
            picker = Element as PLPicker;
        if (picker.Placeholder != null)
            Control.Hint = picker.Placeholder;
    }
  3. Call this method, in the OnElementChanged method and OnElementPropertyChanged method when the placeholder property changes.
  4. You can find the full coding part for “PLPickerRenderer.cs” below for Android.
    [assembly: ExportRenderer(typeof(PLPicker), typeof(PLPickerRenderer))]
    namespace PickerPlaceholder.Droid
    {
        public class PLPickerRenderer : Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer
        {
            PLPicker picker = null;
            public PLPickerRenderer(Context context) : base(context)
            {
    
            }
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if (e.NewElement != null)
                {
                    picker = Element as PLPicker;
                    UpdatePickerPlaceholder();
                    if (picker.SelectedIndex <= -1)
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
                if (picker != null)
                {
                    if (e.PropertyName.Equals(PLPicker.PlaceholderProperty.PropertyName))
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
    
            protected override void UpdatePlaceHolderText()
            {
                UpdatePickerPlaceholder();
            }
    
            void UpdatePickerPlaceholder()
            {
                if (picker == null)
                    picker = Element as PLPicker;
                if (picker.Placeholder != null)
                    Control.Hint = picker.Placeholder;
            }
        }
    }

Step 4: Custom Renderer for Custom Picker in iOS

In this step, we will create a custom renderer in iOS for PLPicker created in “Step 2”.

  1. Create a class named as “PLPickerRenderer.cs” and it is inherited from “Xamarin.Forms.Platform.iOS.PickerRenderer”.
  2. Then create a method “UpdatePickerPlaceholder” and copy the below code in the custom renderer class.
    void UpdatePickerPlaceholder()
    {
        if (picker == null)
            picker = Element as PLPicker;
        if (picker.Placeholder != null)
            Control.Placeholder = picker.Placeholder;
    }
  3. Call this method, in the OnElementChanged method and OnElementPropertyChanged method when the placeholder property changes.
  4. You can find the full coding part for “PLPickerRenderer.cs” below for Android.
    [assembly: ExportRenderer(typeof(PLPicker), typeof(PLPickerRenderer))]
    namespace PickerPlaceholder.iOS
    {
        public class PLPickerRenderer: PickerRenderer
        {
            PLPicker picker = null;
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if (e.NewElement != null)
                {
                    picker = Element as PLPicker;
                    UpdatePickerPlaceholder();
                    if (picker.SelectedIndex <= -1)
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
                if (picker != null)
                {
                    if (e.PropertyName.Equals(PLPicker.PlaceholderProperty.PropertyName))
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
    
            void UpdatePickerPlaceholder()
            {
                if (picker == null)
                    picker = Element as PLPicker;
                if (picker.Placeholder != null)
                    Control.Placeholder = picker.Placeholder;
            }
        }
    }

Step 5: Implementation of Custom Picker Control

In this step, we will create a custom renderer in iOS for PLPicker created in “Step 2”.

  1. Open created Xamarin.Forms Page, in my case “MainPage” and add the custom control picker with Placeholder property.
  2. Open your MainPage.xaml file and add the custom control as shown in below.
    <local:PLPicker Placeholder="Placeholder"
                    Title="Title"
                    TitleColor="Blue"
                    x:Name="plpicker"
                    Grid.Row="2"
                    Grid.Column="0"
                    Grid.ColumnSpan="2"/>
  3. Then add buttons with clicked events to change selected index as 1 and -1 for the custom picker.
    <Button Text="PLPicker:Set Index 1"
            HorizontalOptions="Center"
            VerticalOptions="Center"
            Clicked="PLPIndex1Clicked"
            Grid.Row="3"
            Grid.Column="0"/>
    
    <Button Text="PLPicker:Set Index -1"
            HorizontalOptions="Center"
            VerticalOptions="Center"
            Clicked="PLPIndex2Clicked"
            Grid.Row="3"
            Grid.Column="1" />
  4. Create an event for setting the selected index for picker as like below.
    private void PLPIndex1Clicked(object sender, EventArgs e)
    {
        plpicker.SelectedIndex = 1;
    }
    
    private void PLPIndex2Clicked(object sender, EventArgs e)
    {
        plpicker.SelectedIndex = -1;
    }

Output:

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Introduction In this tutorial, we will learn how to use Calendarview in Xamarin.Forms. This plugin will helps more when we creating a mob...

Calendarview in Xamarin.Forms Calendarview in Xamarin.Forms

A blog about android developement


Introduction

In this tutorial, we will learn how to use Calendarview in Xamarin.Forms. This plugin will helps more when we creating a mobile app for attendance management system.
This Calendar Control is an awesome plugin created by Rebecca and is open sourced in GitHub.
This control offers

  1. Single date selection,
  2. Multi date selection,
  3. Special date selection and date background selection as image and background pattern.

To know more about we will skip into the coding part without delay.

Coding Part:

Steps:

I have split this part into 3 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Setting up the plugin for Xamarin.Forms
  3. Implementing Calendar View in Xamarin.Forms.

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Setting up the plugin for Xamarin.Forms

  1. Open Nuget Package Manager against the solution and do search for Calendar Control Plugin.
  2. Click Install to install this Plugin against your PCL Project or .NET standard Project.
  3. We need to install this plugin in all client projects.

Step 3: Implementing Calendarview in Xamarin.Forms

  1. After installing the plugin into the project, open your designer page (in my case “MainPage.xaml”) and add the following line for importing the calendar control.
    xmlns:controls="clr-namespace:XamForms.Controls;assembly=XamForms.Controls.Calendar"
  2. Then add the calendar control in your page like below
    <controls:Calendar Padding="10,0,10,0" 
                       SelectedBorderWidth="4" 
                       DisabledBorderColor="Black"
                       ShowNumberOfWeek="false"
                       StartDay="Monday"
                       TitleLabelTextColor="Purple"
                       TitleLeftArrowTextColor="Blue"
                       SelectedDate="{Binding Date}"
                       SpecialDates="{Binding Attendances}"
                       DateCommand="{Binding DateChosen}"/>
  3. Here, SelectedDate is used to select date by default, SpecialDates is used to highlight the sepecial dates like "Holidays", "Festivals", "Appointments" and more.
  4. In this project, we are using MVVM pattern. So, we should create a page model and add this to binding context. After that, add bindable properties for SelectedDate, SpecialDates.
  5. Selection of a particular date can be identified by the "DateCommand". Below you can find the whole code implementations of the PageModel.
    namespace CalendarSample
    {
        public class MainPageModel : BindableObject
        {
            private DateTime? _date;
            public DateTime? Date
            {
                get
                {
                    return _date;
                }
                set
                {
                    _date = value;
                    OnPropertyChanged(nameof(Date));
                }
            }
    
            private ObservableCollection attendances;
            public ObservableCollection Attendances
            {
                get
                {
                    return attendances;
                }
                set
                {
                    attendances = value;
                    OnPropertyChanged(nameof(Attendances));
                }
            }
    
            public Command DateChosen
            {
                get
                {
                    return new Command((obj) =>
                    {
                        System.Diagnostics.Debug.WriteLine(obj as DateTime?);
                    });
                }
            }
        }
    }
  6. You can find the output of this application below

Full Code:

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:controls="clr-namespace:XamForms.Controls;assembly=XamForms.Controls.Calendar"
             xmlns:viewmodels="clr-namespace:CalendarSample"
             mc:Ignorable="d"
             x:DataType="viewmodels:MainPageModel"
             x:Class="CalendarSample.MainPage">

    <StackLayout>
        <controls:Calendar Padding="10,0,10,0" 
                           SelectedBorderWidth="4" 
                           DisabledBorderColor="Black"
                           ShowNumberOfWeek="false"
                           StartDay="Monday"
                           TitleLabelTextColor="Purple"
                           TitleLeftArrowTextColor="Blue"
                           SelectedDate="{Binding Date}"
                           SpecialDates="{Binding Attendances}"
                           DateCommand="{Binding DateChosen}"/>
    </StackLayout>

</ContentPage>

MainPageModel.cs

using System;
using System.Collections.ObjectModel;
using Xamarin.Forms;

namespace CalendarSample
{
    public class MainPageModel : BindableObject
    {
        private DateTime? _date;
        public DateTime? Date
        {
            get
            {
                return _date;
            }
            set
            {
                _date = value;
                OnPropertyChanged(nameof(Date));
            }
        }

        private ObservableCollection attendances;
        public ObservableCollection Attendances
        {
            get
            {
                return attendances;
            }
            set
            {
                attendances = value;
                OnPropertyChanged(nameof(Attendances));
            }
        }

        public Command DateChosen
        {
            get
            {
                return new Command((obj) =>
                {
                    System.Diagnostics.Debug.WriteLine(obj as DateTime?);
                });
            }
        }
    }
}

Reference

Calendar Control in Xamarin.Formshttps://github.com/rebeccaXam/XamForms.Controls.Calendar

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Introduction: In this article, we will learn how to integrate and play a video using YouTube API in Android with Kotlin. YouTube Andro...

YouTube Player API in Android using Kotlin YouTube Player API in Android using Kotlin

A blog about android developement

Introduction:

In this article, we will learn how to integrate and play a video using YouTube API in Android with Kotlin.

YouTube Android Player API enables developers to incorporate or integrate video playback functionality into our own developed Android applications. Using this API, we can load and cue play videos. It has a built in play controls for controlling the video playback actions such as Play, Pause or Seek to a specific time/point in the current video. Our Android Phone must have the YouTube app. Because this API interact with service that is a part of YouTube app.

Before going to coding part, we need to follow below steps for setup the YouTube API in our own developed app

  1. Download YouTube API client library from the following link, basically this library is a jar file. https://developers.google.com/youtube/android/player/downloads/
  2. Register our app in Google API console & Enable YouTube Android Player API in Google API Console. In this way we will obtain an Android API key, which is must for using this API. https://console.developers.google.com/apis/

Register app and get Android API Key:

  1. Open Google API Console.
  2. Create a new project or choose your existing project in API Console.
  3. Open API page and search for YouTube Android Player API.
  4. Then select enable API and go to credentials page.
  5. Then select API Key will creates your API key. We can improve the security of the API key with package name & SHA-1 key of your system.

Step 1 - Creating a new project with Kotlin

  1. Open Android Studio and select "Create new project". 
  2. Name the project as per your wish and tick the "Kotlin checkbox support". 
  3. Then, select your Activity type (For Example - Navigation Drawer Activity, Empty Activity, etc.).
  4. Click the “Finish” button to create a new project in Android Studio.

Step 2: Setting up YouTube Library and Manifest:

In this part, we will see how to setup the YouTube API Client library for the project.

  1. With respect to our previous step, we have already downloaded the API client library for YouTube API as a Zip file.
  2. Then extract the jar files and add them to “libs” folder.
  3. Then open app level build.gradle file and add the following lines in dependencies.
    dependencies { 
       …
       implementation files('libs/YouTubeAndroidPlayerApi.jar')   
        …
    }
  4. Then click “Sync Now” to setup your project.
  5. Now the project is ready and add internet permissions in AndroidManifest.xml.
    <uses-permission android:name="android.permission.INTERNET"/>

Step 3: Integration of YouTube Android Player in Screen using Kotlin:

In this step, we will learn how to embed YouTube Android Player & how to play a particular video (by its id).

  1. Open your layout file and in my case I am using “activity_main.xml” and included the “YouTubePlayerView” as like below.
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.androidmad.ytubeapi.MainActivity">
    
        <com.google.android.youtube.player.YouTubePlayerView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:id="@+id/yt_pv"/>
    
    </android.support.constraint.ConstraintLayout>
  2. We need to initialize & load the video to YouTubePlayerView. So, open or create an activity file. In my case I am using “MainActivity.kt”.
  3. To initialize the YouTube Player add the implementation of “YouTubePlayer.OnInitializedListener” as like below.
  4. YouTubePlayer is initialized by calling Initialize method with Android API key and its initialization listener.
    class MainActivity : YouTubeBaseActivity(), YouTubePlayer.OnInitializedListener {
    
        override fun onInitializationSuccess(provider: YouTubePlayer.Provider?, player: YouTubePlayer?, wasRestored: Boolean) {
        }
    
        override fun onInitializationFailure(p0: YouTubePlayer.Provider?, p1: YouTubeInitializationResult?) {
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            yt_pv.initialize(DeveloperApiKey, this)
        }
    }
    Here, DeveloperApiKey – a variable for Android API Key. In Kotlin, we can directly access the view in design or layout file from code behind using kotlinx for Android
  5. We can load or cue the YouTube video by its id after the YouTube Player initialized successfully like below
    override fun onInitializationSuccess(provider: YouTubePlayer.Provider?, player: YouTubePlayer?, wasRestored: Boolean) {
     showShortToast("Youtube Api Initialization Success")
     if (!wasRestored) {
      player?.cueVideo("wKJ9KzGQq0w");
     }
    }
    Here, showShortToast is an extension method created to Show Toast with short duration. To know about extensions, please read my previous article on Kotlin.

Full Code:

You can find the full code implementation of the Activity here.

class MainActivity : YouTubeBaseActivity(), YouTubePlayer.OnInitializedListener {

    override fun onInitializationSuccess(provider: YouTubePlayer.Provider?, player: YouTubePlayer?, wasRestored: Boolean) {
        showShortToast("Youtube Api Initialization Success")
        if (!wasRestored) {
            player?.cueVideo("wKJ9KzGQq0w");
        }
    }

    override fun onInitializationFailure(p0: YouTubePlayer.Provider?, p1: YouTubeInitializationResult?) {
        showShortToast("Youtube Api Initialization Failure")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        yt_pv.initialize("API KEY", this)
    }
}

Reference:

YouTube Android Player API https://developers.google.com/youtube/android/player/
YouTube API Client Library Downloads https://developers.google.com/youtube/android/player/downloads/
Kotlin Extensions (Previous Article) https://www.androidmads.info/2019/06/how-to-use-extensions-method-in-kotlin.html
Extensions in Kotlin https://kotlinlang.org/docs/reference/extensions.html

If you have any doubt or need any help, contact me.

Download Code:

You can download the full source code of the article in GitHub. If you like this article, do star the repo in GitHub. Hit like the article.


Introduction: Google have updated the policy in Google Developer Blog about user privacy and security. As per the policy, we must remove ...

Verify OTP without SMS permission in Android using Kotlin Verify OTP without SMS permission in Android using Kotlin

A blog about android developement

Introduction:

Google have updated the policy in Google Developer Blog about user privacy and security. As per the policy, we must remove SMS and Call Log permissions from manifest or else our app will be removed from google play store. But our app needs SMS permission for automatically authenticate app users. What is the solution?
Google offers an API named as SMS Retriever API to allow our app to read SMS without SMS permission and we need to follow a set of rules while formatting the verification message. In this article, we will learn how to use SMS Retriever API in Kotlin to read SMS and rules need to be followed. If you are new to Kotlin, read my previous articles to read Kotlin from scratch.

Verification Message Format:

We should follow the below rules while formatting verification message.

  1. Message should have maximum of 140 bytes length.
  2. Should start with “<#>”.
  3. Followed by OTP - One Time Pass (code/word).
  4. 11 character length hash for the app (it is generated by our app).
Example:
<#> Your Example App code is: 123ABC78 
FA+9qCX9VSu

Coding Part:

I have detailed the article as in the following steps.
Step 1: Creating New Project with Empty Activity.
Step 2: Setting up the Google Auth Libraries.
Step 3: Implementation of SMS Retriever API using Kotlin.

Step 1 - Creating a new project with Kotlin

  1. Open Android Studio and select "Create new project". 
  2. Name the project as per your wish and tick the "Kotlin checkbox support". 
  3. Then, select your Activity type (For Example - Navigation Drawer Activity, Empty Activity, etc.).
  4. Click the “Finish” button to create a new project in Android Studio.

Step 2: Setting up the Google Auth Libraries:

In this part, we will see how to setup the library for the project.

  1. Then add the following lines in app level build.gradle file to apply google services to your project.
    dependencies { 
       …
        implementation 'com.google.android.gms:play-services-base:11.6.0'
        implementation 'com.google.android.gms:play-services-auth-api-phone:11.6.0'
        …
    }
    
  2. Then click “Sync Now” to setup your project.
  3. Now the project is ready and no need to add any permissions in Manifest.

Step 3: Implementation of SMS Retriever API using Kotlin:

Create user interface to display your OTP read through the API. Open or create “activity_main.xml” and paste the following code snippet.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.androidmad.smsretrieverapisample.MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:onClick="onBtnResendClick"
        android:id="@+id/btn_restart"
        android:text="Resend"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/editText"
        app:layout_constraintVertical_bias="0.247" />

</android.support.constraint.ConstraintLayout>

We need to create a helper class to provide the hash value for our app to construct the verification message. Create a Kotlin class file named as “AppSignatureHelper.kt” and paste following code snippet which is helpful to create 11 character length hash for our application.

package com.androidmad.smsretrieverapisample

import android.annotation.SuppressLint
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.PackageManager
import android.os.Build
import android.support.annotation.RequiresApi
import android.util.Base64
import android.util.Log
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.*

class AppSignatureHelper(context: Context) : ContextWrapper(context) {

    /**
     * Get all the app signatures for the current package
     *
     * @return
     */
    // Get all package signatures for the current package
    // For each signature create a compatible hash
    val appSignatures: ArrayList
        @SuppressLint("PackageManagerGetSignatures")
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        get() {
            val appCodes = ArrayList()

            try {
                val packageName = packageName
                val packageManager = packageManager
                val signatures = packageManager.getPackageInfo(packageName,
                        PackageManager.GET_SIGNATURES).signatures
                signatures
                        .mapNotNull { hash(packageName, it.toCharsString()) }
                        .mapTo(appCodes) { String.format("%s", it) }
            } catch (e: PackageManager.NameNotFoundException) {
                Log.v(TAG, "Unable to find package to obtain hash.", e)
            }

            return appCodes
        }

    companion object {
        val TAG = AppSignatureHelper::class.java.simpleName!!
        private val HASH_TYPE = "SHA-256"
        private val NUM_HASHED_BYTES = 9
        private val NUM_BASE64_CHAR = 11

        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        private fun hash(packageName: String, signature: String): String? {
            val appInfo = packageName + " " + signature
            try {
                val messageDigest = MessageDigest.getInstance(HASH_TYPE)
                messageDigest.update(appInfo.toByteArray(StandardCharsets.UTF_8))
                var hashSignature = messageDigest.digest()

                // truncated into NUM_HASHED_BYTES
                hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES)
                // encode into Base64
                var base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING or Base64.NO_WRAP)
                base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR)

                Log.v(TAG + "sms_sample_test", String.format("pkg: %s -- hash: %s", packageName, base64Hash))
                return base64Hash
            } catch (e: NoSuchAlgorithmException) {
                Log.v(TAG + "sms_sample_test", "hash:NoSuchAlgorithm", e)
            }

            return null
        }
    }
}

Then we need to get the hash from the class by creating an object for the helper class and call the hash creation method which returns the value.

// This code requires one time to get Hash keys do comment and share key
val appSignature = AppSignatureHelper(this)
Log.v("AppSignature", appSignature.appSignatures.toString())

Then create a Custom BroadCastReceiver class named as “MySMSBroadcastReceiver.kt” and add the following code snippets.

class MySMSBroadcastReceiver : BroadcastReceiver() {

    private var otpReceiver: OTPReceiveListener? = null

    fun initOTPListener(receiver: OTPReceiveListener) {
        this.otpReceiver = receiver
    }

    override fun onReceive(context: Context, intent: Intent) {
        if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
            val extras = intent.extras
            val status = extras!!.get(SmsRetriever.EXTRA_STATUS) as Status

            when (status.statusCode) {
                CommonStatusCodes.SUCCESS -> {
                    // Get SMS message contents
                    var otp: String = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
                    Log.d("OTP_Message", otp)
                    // Extract one-time code from the message and complete verification
                    // by sending the code back to your server for SMS authenticity.
                    // But here we are just passing it to MainActivity
                    if (otpReceiver != null) {
                        otp = otp.replace("<#> ", "").split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0]
                        otpReceiver!!.onOTPReceived(otp)
                    }
                }

                CommonStatusCodes.TIMEOUT ->
                    // Waiting for SMS timed out (5 minutes)
                    // Handle the error ...
                    if (otpReceiver != null)
                        otpReceiver!!.onOTPTimeOut()
            }
        }
    }

    interface OTPReceiveListener {

        fun onOTPReceived(otp: String)

        fun onOTPTimeOut()
    }
}

Here, OTPReceiveListener is an interface used to call back the events from broad cast receiver. Then open your Activity and implement OTPReceiverListener.

Register the receiver in AndroidManifest.xml with SMS_RETRIEVED action.

<receiver android:name=".MySMSBroadcastReceiver" android:exported="true">
 <intent-filter>
  <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
 </intent-filter>
</receiver>

Then start the SmsRetriever API as shown in below. Also, register your broadcast receiver with SmsRetriever.SMS_RETRIEVED_ACTION using intent filter.

private fun startSMSListener() {
 try {
  smsReceiver = MySMSBroadcastReceiver()
  smsReceiver!!.initOTPListener(this)

  val intentFilter = IntentFilter()
  intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION)
  this.registerReceiver(smsReceiver, intentFilter)

  val client = SmsRetriever.getClient(this)

  val task = client.startSmsRetriever()
  task.addOnSuccessListener {
   // API successfully started
  }

  task.addOnFailureListener {
   // Fail to start API
  }
 } catch (e: Exception) {
  e.printStackTrace()
 }

}
You will receive OTP in call back methods implemented in you Activity:
override fun onOTPReceived(otp: String) {
 //showToast("OTP Received: " + otp)
 editText.setText(otp)
 if (smsReceiver != null) {
  LocalBroadcastManager.getInstance(this).unregisterReceiver(smsReceiver)
 }
}

override fun onOTPTimeOut() {
 showToast("OTP Time out")
}

Full Code:

You can find the full code implementation of the Activity here.

class MainActivity : AppCompatActivity(), OTPReceiveListener {

    private var smsReceiver: MySMSBroadcastReceiver? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        startSMSListener()
    }


    /**
     * Starts SmsRetriever, which waits for ONE matching SMS message until timeout
     * (5 minutes). The matching SMS message will be sent via a Broadcast Intent with
     * action SmsRetriever#SMS_RETRIEVED_ACTION.
     */
    private fun startSMSListener() {
        try {
            smsReceiver = MySMSBroadcastReceiver()
            smsReceiver!!.initOTPListener(this)

            val intentFilter = IntentFilter()
            intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION)
            this.registerReceiver(smsReceiver, intentFilter)

            val client = SmsRetriever.getClient(this)

            val task = client.startSmsRetriever()
            task.addOnSuccessListener {
                // API successfully started
            }

            task.addOnFailureListener {
                // Fail to start API
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    fun onBtnResendClick(view: View){
        startSMSListener()
    }

    override fun onOTPReceived(otp: String) {
        //showToast("OTP Received: " + otp)
        editText.setText(otp)
        if (smsReceiver != null) {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(smsReceiver)
        }
    }

    override fun onOTPTimeOut() {
        showToast("OTP Time out")
    }


    override fun onDestroy() {
        super.onDestroy()
        if (smsReceiver != null) {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(smsReceiver)
        }
    }


    private fun showToast(msg: String) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
    }
}

Reference:

SMS Retriever API for Android https://developers.google.com/identity/sms-retriever/overview
Google Announcement on Security Policy https://android-developers.googleblog.com/2019/01/reminder-smscall-log-policy-changes.html

If you have any doubt or need any help, contact me.

Download Code:

You can download the full source code of the article in GitHub. If you like this article, do star the repo in GitHub. Hit like the article.

Introduction: In this article, we will learn how to create & use extensions for Android development using Kotlin. We have read abou...

How to use Extensions method in Kotlin How to use Extensions method in Kotlin

A blog about android developement


Introduction:

In this article, we will learn how to create & use extensions for Android development using Kotlin. We have read about Kotlin for Android development. If you are new to Kotlin, read my previous article on Kotlin.

Hello World Android Application Using Kotlin

Extensions:

Kotlin, similar to C# and Gosu, provides the ability to extend a class with new functionality without having to inherit from the class or use any type of design pattern such as Decorator. This is done via special declarations called extensions.

Coding Part:

I have detailed the article as in the following steps.

  1. Creating New Project with Kotlin
  2. Creating Extensions in Kotlin
  3. Implementation of Extension in Kotlin

Step 1 - Creating a new project with Kotlin

  1. Open Android Studio and select "Create new project". 
  2. Name the project as per your wish and tick the "Kotlin checkbox support". 
  3. Then, select your Activity type (For Example - Navigation Drawer Activity, Empty Activity, etc.).
  4. Click the “Finish” button to create a new project in Android Studio.

Step 2: Creating Extensions in Kotlin

In this part, we will see how to create an extensions for Kotlin.

  1. To declare an extensions function, we need to prefix its name with a receiver type, i.e. the type being extended. The following adds a swap function to MutableList
    fun MutableList<Int>.swap(index1: Int, index2: Int) {
        val tmp = this[index1] // 'this' corresponds to the list
        this[index1] = this[index2]
        this[index2] = tmp
    }
  2. We will take an example to show Toast with Short duration. Traditionally, the Toast is shown like below
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
  3. We can simplifies this by the using extensions in Kotlin.
  4. Create a Kotlin file named as “Extensions.kt”. Then add the following code part.
    fun Context.showShortToast(message: CharSequence) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
    Here, the base or receiver type of toast is “Context”. So, we have created a function prefixed with “Context”.
  5. In the same way, I have created an extensions to show “Toast with Long duration” and “Alert Dialog with single option”. You can find the full code below.
    package com.androidmad.ktextensions
    
    import android.content.Context
    import android.support.v7.app.AlertDialog
    import android.support.v7.app.AppCompatActivity
    import android.view.View
    import android.widget.Toast
    
    fun Context.showShortToast(message: CharSequence) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
    
    fun Context.showLongToast(message: CharSequence) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show()
    }
    
    fun AppCompatActivity.showAlert(title: CharSequence, message: CharSequence) {
        val builder = AlertDialog.Builder(this)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("Ok", { dialog, which ->
                })
    
        val dialog: AlertDialog = builder.create()
        dialog.show()
    }

Step 3: Implementation of Extension in Kotlin

In this section, we will see how to call the above created extensions method in android.

  1. Create a layout file named as “activity_main.xml” and add the following code snippets.
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.androidmad.ktextensions.MainActivity"
        tools:layout_editor_absoluteY="81dp">
    
        <Button
            android:id="@+id/btn_short"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="128dp"
            android:text="Show Short Toast"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/btn_long"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="208dp"
            android:text="Show Long Toast"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    
        <Button
            android:id="@+id/btn_alert"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="92dp"
            android:text="Show Alert Dialog"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    
    </android.support.constraint.ConstraintLayout>
  2. The output of the layout file looks like below
  3. We have three buttons in our screen to show Toast with Short duration, Long duration and Alert dialog with single option. Open your MainActivity.kt add click listeners for the buttons.
    // Toast with Short Duration
    showShortToast("Show Short Toast using extensions method")
    // Toast with Long Duration
    showLongToast("Show Long Toast using extensions method")
    // Alert Dialog with Single Option
    showAlert("Android Extensions method", "Show Alert Dialog")
  4. Full code of the MainActivity.kt below.
    package com.androidmad.ktextensions
    
    import android.support.v7.app.AppCompatActivity
    import android.os.Bundle
    import kotlinx.android.synthetic.main.activity_main.*
    
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            btn_short.setOnClickListener({
                showShortToast("Show Short Toast using extensions method")
            })
    
            btn_long.setOnClickListener({
                showLongToast("Show Long Toast using extensions method")
            })
    
            btn_alert.setOnClickListener({
                showAlert("Android Extensions method", "Show Alert Dialog")
            })
    
        }
    
    }

Reference:

Extensions in Kotlin https://kotlinlang.org/docs/reference/extensions.html

Download Code:

You can download the full source code of the article in GitHub. If you like this article, do star the repo in GitHub. Hit like the article.