Thursday 17 May 2018

How to check internet connection in device using Dependency Service in Xamarin Forms

Hi Everyone,

In this post I will gonna be explaining about how to check internet connection in device using Dependency service in Xamarin Forms.

Prerequisites:
  • Visual Studio with Xamarin templates installed in either windows machine or Mac machine.

In my case, I am using a windows machine to demonstrate this post.

Step 1: Create a new project using Visual Studio as below shown.

Step 2: If you select “Project” in above context menu, the following window will open.

In above image,
  • Select “Cross-Platform” option from left lane.
  • Choose “Mobile App (Xamarin.Forms)” option for creating Xamarin Forms application.
  • Choose the location on disk where you want store your application on hard disk.
  • Give some name to your project which is relevant to your task. In my case I’m giving it as “CheckInternet
Step 3: After completing the actions given in step2, click “OK” button. Then one more window will open like below.

In above image, 
  • Choose what type of application you are going to develop. In my case, I am choosing “Blank App”.
  • In second step, check the checkboxes before platform names (Android, iOS, Windows(UWP)) for which you gonna be developing an application.
  • In the third step, choose the code sharing method based on your requirements and future scope of an application.
Step 4: Click “OK” after doing the action in step 3, then it will create a project. Following image depicts how the project structure will be.

Step 5: Right click on “CheckInternet” project and select Add=>New Item like below


Step 6: After clicking “New Item” like in above step, the following window will open.

From the above image,
  • Choose “Code” from left lane.
  • Select “Interface” among all the options listed.
  • Enter some name for the interface. In my case I’m giving “IDeviceState”.
Step 7: Click “Add” button from above window, then interface will be added to the “CheckInternet” project. Replace the created interface will following code.
public interface IDeviceState
    {

        bool isNetworkReachable();
    }

Step 8: Since we are using Dependency Service, we have to  Implement the interface in both Android and iOS projects. 
For the first, I am gonna be implementing interface in Android project as below.

Before proceeding, in Android project, you should have enable INTERNET permission and ACCESS_NETWORK_STATE permission from Manifest.xml file like below
<?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="com.companyname.CheckInternet" android:installLocation="auto">
       <uses-sdk android:minSdkVersion="19" />
       <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
       <application android:label="CheckInternet.Android"></application>
</manifest>

Now add the following class to your project.

public class DeviceState : IDeviceState
    {
        public bool isNetworkReachable()
        {
            bool isNetworkActive;// = false;
            Context context = Forms.Context; //get the current application context

            ConnectivityManager cm = (ConnectivityManager)context.GetSystemService(Context.ConnectivityService);
            NetworkInfo activeConnection = cm.ActiveNetworkInfo;
            isNetworkActive = (activeConnection != null) && activeConnection.IsConnected;

            return isNetworkActive;
        }
    }
Finally add [assembly: Dependency(typeof(**********************))] on top of namespace statement.

Step 8: Implementation of interface in iOS project is as below.
public class DeviceState : IDeviceState
    {
        public DeviceState()
        {
        }

        public bool isNetworkReachable()
        {
            bool hasInternet = true;
            NetworkStatus internetStatus = Reachability.InternetConnectionStatus();

            if (internetStatus == NetworkStatus.NotReachable)
            {
                hasInternet = false;

            }
            return hasInternet;
        }
    }

We have to add [assembly: Dependency(typeof(**********************))] on top of namespace statement.

Other than this, in iOS we have to ass one more class that is “Reachability”. Actually, that Reachability class has logic to check internet connection.

Here I’m adding reachability class and one enum as below.

public enum NetworkStatus
    {
        NotReachable,
        ReachableViaCarrierDataNetwork,
        ReachableViaWiFiNetwork
    }

    public static class Reachability
    {
        public static string HostName = "www.google.com";

        public static bool IsReachableWithoutRequiringConnection(NetworkReachabilityFlags flags)
        {
            // Is it reachable with the current network configuration?
            bool isReachable = (flags & NetworkReachabilityFlags.Reachable) != 0;

            // Do we need a connection to reach it?
            bool noConnectionRequired = (flags & NetworkReachabilityFlags.ConnectionRequired) == 0
                || (flags & NetworkReachabilityFlags.IsWWAN) != 0;

            return isReachable && noConnectionRequired;
        }

        // Is the host reachable with the current network configuration
        public static bool IsHostReachable(string host)
        {
            if (string.IsNullOrEmpty(host))
                return false;

            using (var r = new NetworkReachability(host))
            {
                NetworkReachabilityFlags flags;

                if (r.TryGetFlags(out flags))
                    return IsReachableWithoutRequiringConnection(flags);
            }
            return false;
        }

        //
        // Raised every time there is an interesting reachable event,
        // we do not even pass the info as to what changed, and
        // we lump all three status we probe into one
        //
        public static event EventHandler ReachabilityChanged;

        static void OnChange(NetworkReachabilityFlags flags)
        {
            var h = ReachabilityChanged;
            if (h != null)
                h(null, EventArgs.Empty);
        }

        //
        // Returns true if it is possible to reach the AdHoc WiFi network
        // and optionally provides extra network reachability flags as the
        // out parameter
        //
        static NetworkReachability adHocWiFiNetworkReachability;

        public static bool IsAdHocWiFiNetworkAvailable(out NetworkReachabilityFlags flags)
        {
            if (adHocWiFiNetworkReachability == null)
            {
                adHocWiFiNetworkReachability = new NetworkReachability(new IPAddress(new byte[] { 169, 254, 0, 0 }));
                adHocWiFiNetworkReachability.SetNotification(OnChange);
                adHocWiFiNetworkReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault);
            }

            return adHocWiFiNetworkReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags);
        }

        static NetworkReachability defaultRouteReachability;

        static bool IsNetworkAvailable(out NetworkReachabilityFlags flags)
        {
            if (defaultRouteReachability == null)
            {
                defaultRouteReachability = new NetworkReachability(new IPAddress(0));
                defaultRouteReachability.SetNotification(OnChange);
                defaultRouteReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault);
            }
            return defaultRouteReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags);
        }

        static NetworkReachability remoteHostReachability;

        public static NetworkStatus RemoteHostStatus()
        {
            NetworkReachabilityFlags flags;
            bool reachable;

            if (remoteHostReachability == null)
            {
                remoteHostReachability = new NetworkReachability(HostName);

                // Need to probe before we queue, or we wont get any meaningful values
                // this only happens when you create NetworkReachability from a hostname
                reachable = remoteHostReachability.TryGetFlags(out flags);

                remoteHostReachability.SetNotification(OnChange);
                remoteHostReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault);
            }
            else
            {
                reachable = remoteHostReachability.TryGetFlags(out flags);
            }

            if (!reachable)
                return NetworkStatus.NotReachable;

            if (!IsReachableWithoutRequiringConnection(flags))
                return NetworkStatus.NotReachable;

            return (flags & NetworkReachabilityFlags.IsWWAN) != 0 ?
                NetworkStatus.ReachableViaCarrierDataNetwork :    NetworkStatus.ReachableViaWiFiNetwork;
        }

        public static NetworkStatus InternetConnectionStatus()
        {
            NetworkReachabilityFlags flags;
            bool defaultNetworkAvailable = IsNetworkAvailable(out flags);
            if (defaultNetworkAvailable && ((flags & NetworkReachabilityFlags.IsDirect) != 0))
                return NetworkStatus.NotReachable;
            else if ((flags & NetworkReachabilityFlags.IsWWAN) != 0)
                return NetworkStatus.ReachableViaCarrierDataNetwork;
            else if (flags == 0)
                return NetworkStatus.NotReachable;
            return NetworkStatus.ReachableViaWiFiNetwork;
        }

        public static NetworkStatus LocalWifiConnectionStatus()
        {
            NetworkReachabilityFlags flags;
            if (IsAdHocWiFiNetworkAvailable(out flags))
                if ((flags & NetworkReachabilityFlags.IsDirect) != 0)
                    return NetworkStatus.ReachableViaWiFiNetwork;

            return NetworkStatus.NotReachable;
        }
    }
Step 9: Inside of PCL/NET Standard project , in MainPage.xaml add the following code between <ContentPage> </ContentPage> tags.
<Button Text="Check Network Reaachability"
           VerticalOptions="Center"
           HorizontalOptions="Center"
           Clicked="clickedButton"/>

In the code behind of MainPage that is MainPage.xaml.cs, please add the following code.
public partial class MainPage : ContentPage
       {
              public MainPage()
              {
                     InitializeComponent();
              }

        public void clickedButton(Object sender, EventArgs e)
        {
bool internetActive =     DependencyService.Get<IDeviceState>().isNetworkReachable();
              this.DisplayAlert("Device Network", internetActive.ToString(), "OK");
        }

    }
Now run your application, the output will be like as given below.





If you want full source you can find it clicking below.

arin

Thanks for reading the article, please comment me if you have any doubts in it. I will get back to you with an answer(s).

No comments:

Post a Comment

Intoduction to Flutter

Hi All, I hope every one is doing good In this article, we will know about the introduction of Flutter.