Tuesday, 12 July 2016

Opening Android App When Particular link/Host with Scheme is opened in Browser.

Opening Android Application when particular "Host" is opened in Android mobile browser or particular Link is opened Also named as Mobile DeepLinking.

We need to define host & scheme in the intent filters of the activity, which we need to open when link or host is opened.


Below is the code for opening app when particular Host is opened.

 <activity


            android:name=".ActivityName">
<intent-filter>

                <action android:name="android.intent.action.GALLERY" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
<data
                    android:host="http"
                    android:scheme="abc.com" /> 
</intent-filter>

</activity>

Below is the code for opening app when we are trying particular Link  in browser.


 <activity

        android:name=".ActivityName">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="http"
                  android:host="abc.com"
                  android:pathPrefix="/images/" />
            <data android:scheme="https"
                  android:host="abc.com"
                  android:pathPrefix="/images/" />
        </intent-filter>
   </activity>
 
   
Cheers!!   

Thursday, 7 July 2016

Firebase (via Assistant) Crash Reporting In Android Studio 2.2 Preview

Hi Guys, Today i'll be discussing how to use Firebase which is present as a Assistant in Android Studio 2.2.1 Preview.

As we know Firebase is a Cloud Services Provider which was acquired by Google back in 2014 in order to help developer build better real-time apps.

Now Firebase will be available as Assistant in Android Studio upcoming version which will help us easliy integrate following :

1. Analytics
2. Cloud Messaging
3. Authenication
4. Real time Database
5. Storage
6. Crash Reporting etc..

Now using Assistant present in Android Studio to use/integrate one the above services is quite easy and fast.

Here i'll be going through the steps to integrate Crash Reporting via Firebase in one of my demo app.

By Crash Reporting you can track all the crashes that occurs in your app and rectify once to get the report via Firebase.

So here are the steps :

1. Go to Tools and select Firebase.





2. You will see the Assistant opened in the right side in a tab named Assistant.

3. Now Scroll down and click on Crash Reporting






4. Click on Setup Firebase Crash reporting







5. Now  This will ask to to connect to Firebase.

6. Once you click on Connect it will take you to Browser and ask you to login via Google Account and will ask for permission.





7. After that Successful login you will be re-directed to Firebase Console and you can come back to Android Studio where it shows connected.





Note : This will automatically create your project inside google web console. Where make sure your Firebase Api is Enable for the project in case if you face
crash reporting problems.

8. Now you need to create a new Firebase project or select the existing Firebase Google project in which we wish to integrate Firebase.






Here you can create a new Firebase project.

After you select/create Firebase project and connect then it shows progress in Assistant like this :





Now once you are connected Assistance show you as connected as well.




After this we are all done setting up Firebase project and connection. Now Lets come to Coding part which is also a small part to do.

9. Now you need to add following Classpath into your buildscript dependencies

buildscript {
    // ...
    dependencies {
        // ...
        classpath 'com.google.gms:google-services:3.0.0'
    }
}

10. After that you need to add following dependencies in your app level build.gradle

android {

    // ...

}

dependencies {

    // ..

    compile 'com.google.firebase:firebase-ads:9.2.0'

}

// ADD THIS AT THE BOTTOM

apply plugin: 'com.google.gms.google-services'

Note : Make sure you are using the latest version of Firebase and Google play services here 11. Add following dependencies to app level build.gradle as well
    compile 'com.google.android.gms:play-services:9.2.0'
12. Now all is done. You can following code lines to track crashes
FirebaseCrash.logcat(Log.ERROR, TAG, "NPE caught");
FirebaseCrash.report(ex);
This Lines will send crash reports to cloud. And you can login to console and check the crash reports easliy there.

Note : Every crash is visible on console only after 20-25 minutes after it is reported.


In one of my demos i've created arithmetic exception to check the Firebase something like this :


try { int i = 10 / 0; }catch (Exception e){ FirebaseCrash.logcat(Log.ERROR, "Crash", "NPE caught"); FirebaseCrash.report(e); }


Which reported the Crash to console which was available to check after 20-25 minutes.
Once Crash occurs Firebase service starts and sends the crash details up to cloud.

You can find the below log in you logcat when Firebase service runs successfully.


Logcat Details which ensures Firebase Sent the Report successfully :

D/FirebaseCrashApiImpl: throwable java.lang.ArithmeticException: divide by zero
I/FirebaseCrashReceiverServiceImpl: FirebaseCrashReceiverServiceImpl created by
ClassLoader com.google.android.chimera.container.internal.DelegateLastPathClassLoader
[DexPathList[[zip file "/data/user/0/com.google.android.gms/app_chimera/m/00000005/
DynamiteModulesC_GmsCore_prodmnc_xxhdpi_release.apk"],nativeLibraryDirectories=
[/data/user/0/com.google.android.gms/app_chimera/m/00000005/n/armeabi-v7a,
/data/user/0/com.google.android.gms/app_chimera/m/00000005/n/armeabi,
/vendor/lib, /system/lib]]]  com.youpackage:background_crash D/FirebaseCrashReceiverServiceImpl: onCreate
com.youpackage:background_crash I/DynamiteModule: Considering local module com.google.android.gms.flags:0 and remote module com.google.android.gms.flags:1
com.youpackage:background_crash I/DynamiteModule: Selected remote version of com.google.android.gms.flags, version >= 1
com.youpackage:background_crash D/FirebaseCrashReceiverServiceImpl: Saving crash
com.youpackage:background_crash I/FirebaseCrashSenderServiceImpl: FirebaseCrashSenderServiceImpl created by ClassLoader com.google.android.chimera.container.internal.DelegateLastPathClassLoader[DexPathList[[zip file "/data/user/0/com.google.android.gms/app_chimera/m/00000005/DynamiteModulesC_GmsCore_prodmnc_xxhdpi_release.apk"],nativeLibraryDirectories=[/data/user/0/com.google.android.gms/app_chimera/m/00000005/n/armeabi-v7a, /data/user/0/com.google.android.gms/app_chimera/m/00000005/n/armeabi, /vendor/lib, /system/lib]]]


D/FirebaseCrashSenderServiceImpl: Response code: 200
D/FirebaseCrashSenderServiceImpl: Report sent


You can check the Crash reports on Console by logging into https://console.firebase.google.com in crash reports will look like this








Cheers!!

References :
https://firebase.google.com/docs/android

Monday, 21 March 2016

Method to add events from your Android App to default Calendar application



Please pass required parameters to the below method in order add events to default Calendar in android . 

Add Calendar and Accounts permission to manifest. And Also ask for Calendar Runtime permission for 6.0.

 Accounts permission is normal permission so Runtime implementation for same is not required.

 1. Manifest File

<uses-permission android:name="android.permission.GET_ACCOUNTS"/> <uses-permission android:name="android.permission.READ_CALENDAR"/> <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
2. Methods to add event to Calendar (Modify as per need)

//here you can pass a model class which will contains all your values instead of many parameters

private void addEventToCalendar(Activity activity,String title,String startDateStr,String startTime, String endDateStr,String endTime,String eventDescription) { //Getting google accounts linked here Account[] accounts = AccountManager.get(activity).getAccountsByType( "com.google"); String accountName=""; for (Account acc : accounts) { Log.d(">>>>>>>", "Name: " + acc.name + "-----Type: " + acc.type); accountName = acc.name; } //Getting required calendar ID here long calID = getCalendarId(activity,accountName); long startMillis = 0; long endMillis = 0; Date startDate = null; //Converting date/time as per need try { startDate = new SimpleDateFormat("yyyy-MM-dd hh:mmaa", Locale.ENGLISH).parse(startDateStr+" "+startTime); } catch (ParseException e1) { e1.printStackTrace(); } startMillis = startDate.getTime(); Date endDate = null; try { endDate = new SimpleDateFormat("yyyy-MM-dd hh:mmaa", Locale.ENGLISH).parse(endDateStr+" "+endTime); } catch (ParseException e) { e.printStackTrace(); } endMillis = endDate.getTime(); //Creating content values which will be used to enter data from a query into calendar content resolver ContentResolver cr = activity.getContentResolver(); ContentValues values = new ContentValues(); values.put(CalendarContract.Events.DTSTART, startMillis); values.put(CalendarContract.Events.DTEND, endMillis); values.put(CalendarContract.Events.TITLE, title); values.put(CalendarContract.Events.DESCRIPTION,eventDescription); values.put(CalendarContract.Events.CALENDAR_ID, calID); values.put(CalendarContract.Events.EVENT_TIMEZONE, Calendar.getInstance().getTimeZone().getDisplayName()); try { // Executing query to enter event into the calendar here Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values); } catch(Exception e) { e.printStackTrace(); } } private static long getCalendarId(Activity activity,String MY_ACCOUNT_NAME) { String[] projection = new String[] { BaseColumns._ID }; String selection = CalendarContract.Calendars.ACCOUNT_NAME + " = ?"; String[] selArgs = new String[] { MY_ACCOUNT_NAME }; Cursor cursor = activity.getContentResolver().query( CalendarContract.Calendars.CONTENT_URI, projection, selection, selArgs, null); if (cursor.moveToFirst()) { return cursor.getLong(0); } return -1; }


References : http://developer.android.com/index.html

Thursday, 31 December 2015

What are Normal permissions in Android?

There are two types of permissions:-

1. Normal permissions 
2. Runtime Permissions

We are familiar with Runtime permissions, here we will be discussing about Normal Permissions.
Normal permissions are the permissions which are automatically granted during install time. We need not to check these in our code(i.e runtime).And these are the permissions which user can not revoke from app settings as well.
We simply declare these permissions in the Android Manifest.xml and it will work nomally as did earlier.
.
Below is the list of permissions :-

android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.READ_SYNC_SETTINGS
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER

Sunday, 6 December 2015

Download/Upload files using Dropbox Api Android

This tutorial is about Downloading/Uploading files from/to Dropbox using DropboxApi Android.


Firstly create your App key and App Secret key to use this api from below link.
Dropbox App Console : https://www.dropbox.com/developers-v1/apps

Include the below jars files from the downloaded Dropbox Sdk :
1. dropbox-android-sdk-1.6.3.jar
2. json_simple-1.1.jar

1. MainActivity.java

public class MainActivity extends AppCompatActivity {

        //path of the file to be uploaded here    
String path= Environment.getExternalStorageDirectory()
            .getAbsolutePath() + "/photo.jpg";
    final static private String APP_KEY = "";
    final static private String APP_SECRET = "";
    private DropboxAPI<AndroidAuthSession> mDBApi;
    DropboxAPI.Entry response;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /**
         *   i am using this mode . you can use the Async task to upload and download file
         */
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        setContentView(R.layout.activity_main);
        //Generate dropbox session from the generated keys
        AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
        AndroidAuthSession session = new AndroidAuthSession(appKeys);
        mDBApi = new DropboxAPI<AndroidAuthSession>(session);
        //Check if user has already authorized the dropbox app for you..
        if(!getAccessToken().equalsIgnoreCase("")){
            mDBApi.getSession().setOAuth2AccessToken(getAccessToken());
        }else{
            //if not authorized. i.e for the first time then
            mDBApi = new DropboxAPI<AndroidAuthSession>(session);
            mDBApi.getSession().startOAuth2Authentication(MainActivity.this);
        }

        ((Button) findViewById(R.id.uploaddata)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                uploadFile(path);
            }
        });

        ((Button) findViewById(R.id.downloadfile)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                downloadFile(Environment.getExternalStorageDirectory()
                        .getAbsolutePath());
            }
        });
    }

    protected void onResume() {
        super.onResume();
        //if first time and save the Access Token here
        if(getAccessToken().equalsIgnoreCase("")) {
            if (mDBApi.getSession().authenticationSuccessful()) {
                try {
                    // Required to complete auth, sets the access token on the session
                    mDBApi.getSession().finishAuthentication();
                    String accessToken = mDBApi.getSession().getOAuth2AccessToken();
                    saveAccessToken(accessToken);
                } catch (IllegalStateException e) {
                    Log.i("Error", "Error authenticating", e);
                }
            }
        }
    }

    private void saveAccessToken(String accessToken){
        SharedPreferences sharedPreferences=getSharedPreferences("Prefs", Context.MODE_PRIVATE);
        sharedPreferences.edit().putString("accessToken", accessToken).commit();
    }

    private String getAccessToken(){
        SharedPreferences sharedPreferences=getSharedPreferences("Prefs", Context.MODE_PRIVATE);
        return sharedPreferences.getString("accessToken","");
    }

    public void uploadFile(String file_path) {
        File file = new File(file_path);
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            response = mDBApi.putFile("/photo.jpg", inputStream,
                    file.length(), null, null);
            if(response.rev!=null){
                Toast.makeText(this,"File Uploaded successfully..",Toast.LENGTH_LONG).show();
            }
            Log.i("Success", "The uploaded file's rev is: " + response.rev);
        } catch (DropboxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void downloadFile(String file_path) {
       //Path where you want to stored the downloaded file form dropbox
        File file = new File(file_path+"/testphoto.jpg");
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        DropboxAPI.DropboxFileInfo info = null;
        try {
            info = mDBApi.getFile("/photo.jpg", null, outputStream, null);
            if(info.getMetadata().rev!=null){
                Toast.makeText(this,"File Downloaded successfully..",Toast.LENGTH_LONG).show();
            }
            Log.i("Success", "The file's rev is: "
                    + info.getMetadata().rev);
        } catch (DropboxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

2. Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kamal.dropboxdemoapi" >
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <activity
            android:name="com.dropbox.client2.android.AuthActivity"
            android:launchMode="singleTask"
            android:configChanges="orientation|keyboard">
            <intent-filter>
                <!-- Change this to be db- followed by your app key -->
                <data android:scheme="db-Your App key here" />
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>


Find the source from  Github : https://github.com/CammyKamal/BlogTutorials/tree/master/DropBoxDemoApi

Friday, 4 December 2015

Handling GCM Push Notifications in Android Flavors

In Android Flavors generally we have different package names in our single app for flavours.

When implementing GCM Push Notifications in our android app in case of Flavors there is very little thing that we need to do differently.

Since our Package Name i.e application id is going to be different for different Flavors then push notifications going to be a problem in that case.

Below is the permissions that we generally declare in manifest file when using GCM.
   

 <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

    <!-- Creates a custom permission so only this app can receive its messages. -->
    <permission
        android:name="yourpackagename.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="yourpackagename.permission.C2D_MESSAGE" />

    <!-- This app has permission to register and receive data message. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
   
   
    Now suppose if we are implementing flavours then way of defining these permissions will change.
    Suppose we have below flavours in our build.gradle.
   
    productFlavors {
                        paid
                    {
                        applicationId "com.example.paid"
                        versionCode 1
                        versionName "1.0"
                    }
                        free
                    {
                        applicationId "com.example.free"
                        versionCode 1
                        versionName "1.0"
                    }
                }
               
           
Now when running GCM according to different variants will be a problem. GCM will work accordingly whose permission with package name is defined in manifest.

So add runtime Package Name to the manifest permissions in case of Android Flavors. Below is how can we declare single permissions for multiple Android Flavors in android manifest file.
   
   

    <!-- GCM notifications permissions-->


    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    

    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

    

    <permission android:name="${applicationId}.permission.C2D_MESSAGE"

        android:protectionLevel="signature" />

    

    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />

    
   
Here ${applicationId} will be replaced by the applicationId of the running build variant defined in build.gradle of the app.


Cheers!!

Thursday, 3 December 2015

Snackbar to show Internet Connectivity Changes in App


Here Snackbar will be shown everytime when internet connection is available or connection lost for user via broadcast receiver.

Snackbar works from api 8 and above so its a cool thing to implement for showing such short messages.

 You need to extend your activity with AppCompatActivity for Snackbar.

Add below dependency in your build.gradle compile 'com.android.support:design:22.2.1'

 1. MainActivity.java

public class MainActivity extends AppCompatActivity {
    public static int TYPE_WIFI = 1;
    public static int TYPE_MOBILE = 2;
    public static int TYPE_NOT_CONNECTED = 0;
    private Snackbar snackbar;
    private CoordinatorLayout coordinatorLayout;
    private boolean internetConnected=true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        coordinatorLayout=(CoordinatorLayout)findViewById(R.id.coordinatorlayout);
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerInternetCheckReceiver();
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(broadcastReceiver);
    }
    /**
     *  Method to register runtime broadcast receiver to show snackbar alert for internet connection..
     */
    private void registerInternetCheckReceiver() {
        IntentFilter internetFilter = new IntentFilter();
        internetFilter.addAction("android.net.wifi.STATE_CHANGE");
        internetFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(broadcastReceiver, internetFilter);
    }

    /**
     *  Runtime Broadcast receiver inner class to capture internet connectivity events
     */
    public BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String status = getConnectivityStatusString(context);
            setSnackbarMessage(status,false);
        }
    };

    public static int getConnectivityStatus(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (null != activeNetwork) {
            if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
                return TYPE_WIFI;

            if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
                return TYPE_MOBILE;
        }
        return TYPE_NOT_CONNECTED;
    }

    public static String getConnectivityStatusString(Context context) {
        int conn = getConnectivityStatus(context);
        String status = null;
        if (conn == TYPE_WIFI) {
            status = "Wifi enabled";
        } else if (conn == TYPE_MOBILE) {
            status = "Mobile data enabled";
        } else if (conn == TYPE_NOT_CONNECTED) {
            status = "Not connected to Internet";
        }
        return status;
    }
    private void setSnackbarMessage(String status,boolean showBar) {
        String internetStatus="";
        if(status.equalsIgnoreCase("Wifi enabled")||status.equalsIgnoreCase("Mobile data enabled")){
            internetStatus="Internet Connected";
        }else {
            internetStatus="Lost Internet Connection";
        }
        snackbar = Snackbar
                .make(coordinatorLayout, internetStatus, Snackbar.LENGTH_LONG)
                .setAction("X", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        snackbar.dismiss();
                    }
                });
        // Changing message text color
        snackbar.setActionTextColor(Color.WHITE);
        // Changing action button text color
        View sbView = snackbar.getView();
        TextView textView = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.WHITE);
        if(internetStatus.equalsIgnoreCase("Lost Internet Connection")){
            if(internetConnected){
                snackbar.show();
                internetConnected=false;
            }
        }else{
            if(!internetConnected){
                internetConnected=true;
                snackbar.show();
            }
        }
    }
}


2. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    android:id="@+id/coordinatorlayout"
    android:fitsSystemWindows="true"
    tools:context="com.example.kamalvaid.internetcheckandsnackbar.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>
 
 
3. Add these permissions to manifest file

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />


Github Link : https://github.com/CammyKamal/BlogTutorials/tree/master/InternetCheckAndSnackBar

Output: