Smart home (IoT) – the beginnings

Intro

Since I am a fan of DYI and love gadgets(and IoT), I started to play with a Raspberry Pi and ESP8266 for a while. I had some failing ideas like automating my curtains, after long plans and setup, I abandoned the idea because I couldn’t see a way to make it look nice with the Raspberry Pi board. But now I finally managed to wrap up something that I use and would like to share with others.

It is about automating my kitchen led band by adding the ability to switch it off/on using and Android phone and a physical button(because you don’t have the phone on you in the house always ūüėõ ).

The first IoT “Thing”

I would like to call this setup a “thing” from the IoT (Internet of Things) because I would like to work more on it and finally make it behave just like a real IoT thing.

At this moment we can name it “Smart switch” because it can connect to a Wifi router and switch a relay ON and OFF, and it also has the fancy button. I hope in the near future to smarten it more and more. Currently as I said, with the relay, I am switching my kitchen’s led band ON and OFF but one can use it to switch any outlet ON/OFF or other equipment that makes sense.

Please note that I don’t take any responsibility for any damages that you might encounter while doing this, I am still at the early beginning of my IoT journey.

Ok, so here is what you can see in this article:

  • Code for the Android application
  • Arduino code for the NodeMCU ESP8266 board
  • How to wire the hardware components on the NodeMCU ESP8266 board
What can the NodeMCU ESP8266(custom built) do:
  • connect to a WPS enabled router
  • be discoverable on the network using the mDNS protocol
  • get input from a button
  • create a web server that manages the relay
  • controls a relay
What can the Android app do:
  • search for the NodeMCU ESP8266 module on the network and get the IP address
  • check the relay’s current “status” (ON/OFF)
  • switch the relay ON/OFF
Hardware components that I am using:
  • android phone ūüôā
  • NodeMCU v2 – Lua ESP8266¬†board
  • Solid state relay that can operate up to 340VAC and can be switched with a low of 3VDC (this one)

The high level schema of the system can be checked below (Schema 1).

NodeMCU smart relay schema
Schema 1 – NodeMCU ESP8266 smart relay schema

 

The wiring of the hardware components(button and the relay) on the NodeMCU ESP8266 board can be found in Schema 2 below.

Schema 2 – ESP8266 and relay wiring

 

Note that the wiring diagram does not position the¬†lines to the real GPIO pins, instead I noted the exact GPIO pins so the position will be different than in the diagram. D1 corresponds to GPIO5, D2 to GPIO4 so in the Arduino code you will find them referenced as 5 and 4. Also, the relay I am using emits a charge of a few volts back to the board. That makes the button press detection to trigger false positives. There is a way to outcome that hardware wise but I don’t know exactly the component that I should use in order to avoid the charge and so I made some hacks in the Arduino code. I will get back with updates when I will find out how to fix it properly. If you know how, please let me know.

Below you can find the NodeMCU ESP8266 pins layout. You can find out more about that here.

ESP8266 NodeMCU pins
ESP8266 NodeMCU pins

 

Below you can also see a small sample of how my setup looks like (I know, it doesn’t look nice, I bought some stuff to box it ūüôā ).

IoT with ESP8266 with relay and a power source for a led band
ESP8266 with relay and a power source for a led band

 

A few details…

The led band is powered by a transformer that outputs 24V from 220VAC. What I’ve done was to put the relay in front of the 220VAC of the source and switch it off and on whenever I need it to. The ESP8266 sends a 3VDC power to the relay and in that moment the relay turns ON and the led band lights up.

I bought a solid state relay because those are responding faster and have longer life than the other one. Please share your thoughts if this doesn’t make sense for you. The whole project(hardware) cost me about 40 dollars (max) and it is not built with cheap components so one could get it below that(depending on the region and trading skills :)) ).

The code for both the Arduino and Android projects can be found on my Github account HERE. Please let me know if you have issues or you have better ideas and feel free to contribute.

At last

I would like to end with a list of items that I want to address in the future and also some util links.

Future improvements:
  • fix the relay leak hardware wise and not in code
  • implement a well known and widely used IoT things protocol so that other smart home servers could talk with my “smart relay”
  • implement a better wifi connection and discovery mechanism (remember the connection after a restart…)
  • refactor the android app to abstract the “Thing” and add support for future things
  • integrate with IFTTT
  • integrate with Google Assistant
Util links:

Thank you for reading all this long post, please let me know if you managed to setup this and also your opinion/experience with IoT.

Meanwhile I managed to link the ESP8266 to my Google Home assistant speaker using IFTTT using a web hook for now. See the video below.

 

And a short demo with the beast ūüôā

 

Android Show HTML Bulleted List from strings.xml

If you search on the internet about how to show a bulleted list from strings.xml using HTML tags, most of the answers will say that you should use a WebView, or to use the bullet symbol directly, or other alternatives. And on some posts I even read that you can’t use <li> tag from HTML because it is not recognized in Android. This is totally untrue. Here, in this post you can see all the HTML tags which are supported and which are NOT supported. I tried them all ūüôā

Below I will show you how I used <li> tag in order to show a bulleted list from strings.xml.

strings.xml

activity_main.xml

Activity

 

And below is the result ūüôā

As you can see, is pretty easy to show a bulleted list if you need to show it on a TextView. So there’s no need to refactor your code to use WebView or other alternatives. Of course, if you don’t like this approach, you can use the others. I don’t want to imply this the correct and only way to show bullets. But I wanted to write this post, because I didn’t find this approach anywhere else and maybe someone will need it, or like it more than the other ones :P.

Please let me know if you find this post useful by writing a comment or rating it. Also don’t forget to share it if you liked it ūüėČ

Android Activity launchMode

In Android you can specify activity launchMode. You can do this either from AndroidManifest.xml file, either using intents with flags. Some of the flags produce the same effects like those from AndroidManifest.xml, but there are some flags that can be declared only with intents and also there are flags that can be declared only inside AndroidManifest.xml. In this tutorial we will talk only about those from manifest.

launchMode

There are 4 types of launchMode:

standard

Standard is the default launch mode used by the system. If you don’t set any launch mode to your activity, it will use the standard mode by default.

singleTop

We have the following scenarios:

We have 4 activities: A, B, C and D

Scenario 1

  • D¬†activity has launchMode declared in AndroidManifest.xml as singleTop, the other 3 activities have standard

  • the navigation of the activities is: A -> B -> C -> D. From D activity, we start activity D again.

Current Stack:

Question: What happens when we tap the back key?

Answer: The stack remains the same and the navigation is as follows: D -> C -> B -> A

Use case: Search function

Scenario 2

  • B¬†activity has launchMode=”singleTop”, the other 3 activities have standard
  • the navigation of the activities is: A -> B -> C -> D. From D activity, we start activity B.

Current Stack:

Question: What happens when we tap the back key in this scenario?

Answer: A new instance of B activity was added to the stack. The navigation is as follows: B -> D -> C -> B -> A

Conclusion

As you can see, singleTop flag, prevents instantiating a new existing activity only if the activity containing this flag, is the last one (at the top of the stack) like in Scenario 1.

singleTask

What is a task?

  • a task is a collection of activities
  • tasks can be seen in the Recent Apps from your device
  • an app can have multiple tasks
  • an activity declared with launch mode as singleTask can have only one instance in the system (singleton).
  • even though a new task is created, the Back button still returns the user to the previous activity

Use case

An example would be a web browser activity which should always open in its own task. This means that if you open a web browser from your app, it will open in a separate task from your app.

How does it work?

Let’s take an example. We open an app that was not opened recently, so the system creates a new task for this app, let’s say task1. You navigate through the app, and then press the Home button. At this point, the app goes in background, and all the activities are stopped, not destroyed, stopped. This means that the back stack of these activities remains intact. Now, if you open another app, with its own task (task2), and then put this one in the background and resume the first app (task1), you will see that you can pick up where you left off. The activity at the top of the stack will resume, while the other activities from the task remained intact. This means that if you press the Back button you will navigate back through the activities.

Create new task from same app

Scenario 1

We will use the same activities as earlier in this post (A, B, C and D) with the same navigation just that we will open C activity in a new task. The code is this:

Important: Notice that we have to declare taskAffinity in order to open C activity in a new task like the documentation states. Without taskAffinity, it will open in the same task (though the behavior of back stack might be different . See Scenario 4)

You can also see the task recording of the activities by using dumpsys activity command in the terminal from Android Studio (no logs or anything in the code):

And this what the above command will show us:

As you can see, A and B activities are in task t267 while C and D are in a new separate task t268. C is the root activity for the new task.

Scenario 2

In this scenario, we will let the C activity to be the only one declared with launchMode as singleTask, but we will change the navigation through activities. This is the order:

A -> B -> C -> D -> B -> C

As you can see above, from D activity we will try to open B activity and then C¬†again. Let’s see what happens.

A -> B -> C -> D -> B 

At this point, we have 2 instances of B activity. One in task t305 and a new one in task t306. Let’s see what happens next.

A -> B -> C -> D -> B -> C

“Oh, well, what happened here?”, you might wonder. This happened:

  • C activity is declared as singleTask. This means that only one instance of this activity can exist in the system. So, the system brought the existing C activity in front of B from task t305.
  • in the process of bringing C activity in front of B, the system destroyed¬†the above activities from task t306 (D and B from task t306)

Scenario 3

Let’s suppose that:

  • C and D activities are already in the background
  • D activity is declared with singleTask.
  • A and B activities are in a separate task.

What happens if we open D activity from B activity? See the image below:

As you can see, starting D¬†activity declared as singleTask which already exists in background, from B activity, will move the whole stack of activities from D‘s task in front of B.¬†Thus the back stack of the activities is now A – B- C – D.

Scenario 4

In this scenario, we will test what happens when we declare B activity as singleTask, but without taskAffinity.

The navigation through activities is this:

A -> B -> C -> D

Notice that¬†B¬†activity, even though is declared with launchMode=”singleTask”¬†it seems to be in the same task¬†t340 as the other activities. This means that using singleTask¬†will NOT¬†always put the activity in a new task at the root as the documentation states. BUT¬†declaring singleTask for¬†B¬†is not completely redundant. Look what happens next, when we want to open B again from D¬†activity:

A -> B -> C -> D -> B

C and D activities have been destroyed even if all activities were in the same task. This happens only if we open again an activity declared as singleTask, in our scenario B. If we had opened A activity, it would have been added on top of D.

Scenario 5

Now, let’s see what happens if we declare singleTask for activity D, without taskAffinity:

If we run the app we will notice that D activity is not in the same task as activity C, but it is in the same task as A and B activities.

singleInstance

This launch mode is the same as singleTask, except that an activity declared as singleInstance is always in a separate task and it is the only activity in that task. Any activities opened from this one, open in a separate task.

We will take an example.  The navigation through activities is this:

A -> B -> C -> D

C activity is declared singleInstance. Below is the stack.

As you can see, C activity is alone in a separate task, while A, B, D are in the same task.

taskAffinity

An activity can be set to prefer being in a certain task by using affinity. By default, all activities belong in the same task because they have an affinity for each other.

taskAffinity can be used in 2 cases:

  • when using launchMode singleTask
  • when using¬†allowTaskReparenting

We will discuss only the first case in this tutorial.

taskAffinity with singleTask

In this case, the system looks for launching the activity in a new task. Often, it’a a new one, but it doesn’t always have to be a new one.¬† If there’s already an existing task with the same affinity as the new activity, the activity is launched into that task. Otherwise, it begins a new task.

  • the taskAffinity attribute takes a string as value which has to be declare with “.”, but has to be different from the package name of the app, because that is the default value of the system.
  • If you put an empty string “”¬†as vaslue,¬†will mean that that activity will not have an affinity for any task.
  • if you don’t add taskAffinity to your activity, it will inherit the affinity set for the application

Android ViewPager Tutorial

In Android, if you need to swipe from right to left or vice-versa in order to see different data, you can use a ViewPager. In order to use it, you have to implement a PagerAdapter which will generate the pages that the view shows.

ViewPager’s adapters

We can use one of the 3 adapters provided:

  • PagerAdapter:
    • it is the base class for a ViewPager adapter
    • used when you need to display only views
  • FragmentPagerAdapter:
    • extends PagerAdapter
    • represents each page as a Fragment
    • each page is persistently kept in the fragment manager as long as the user can return to the page, but the view hierarchy can be destroyed when not visible
    • mostly used for static pages like tabs
  • FragmentStatePagerAdapter:
    • extends PagerAdapter
    • represents each page as a Fragment
    • handles saving and restoring of a Fragments’s state
    • mostly used for a large number of pages

When an adapter loads a page, it creates the adjacent pages also. This means that for position 0, it will also load the next page from position 1. And for position 1, it will load the pages from positions 0 and 2, and so on.

Fun fact: even though you can set a click listener or a longClick listener on a viewPager, they won’t work. ViewPager does NOT¬†consume click events. You will have to set the click event on your view in instantiateItem() method.

PagerAdapter

First, we will see an example of a ViewPager that uses a PagerAdapter, this means that we will have to display only some views (in our case, some images :P)

activity_main.xml

view_pager_item.xml

MainActivity.java

As you can see, when using the base adapter, we have to implement the following methods at minimum:

  • instantiateItem(ViewGroup, int): in this method we have to inflate the layout which which will represent a page for the given position.
  • destroyItem(ViewGroup, int, Object): in this method we have to write the code that removes a page from its container for the given position. This method is called while the user navigates through pages. For example if the current position is 0 and the user navigates to the next page, which will be on position 1, at this point, the method is not called. But, when the user goes again to a next page, position 2, at this point, the page from position 0 will be removed. And from now on, whenever the user swipes to a next page the method will be called for the next positions, 1, 2 and so on.
  • getCount(): here we have to provide the number of pages that the viewPager will have to display. In our case, the size of list containing our images which is 3 ūüôā
  • isViewFromObject(View, Object): it is required for a PagerAdapter in order for it to function properly. It checks if Object (the one returned by¬†instantiateItem(ViewGroup, int)) is the same with View.

FragmentPagerAdapter and FragmentStatePagerAdapter

In order to implement any of these 2 adapters you will have to implement just 2 methods to have a working adapter:

  • getCount()
  • getItem(int)

Of course, you can also implement methods from PagerAdapter also if you need to.

In the following example, we will use the same example as above, but using a FragmentStatePager adapter. The example is available for a FragmentPagerAdapter too, as both adapters have to implement same methods.

view_pager_item.xml and activity_main.xml will remain the same. What changes is MainActivity.java class and we have to create a new java class (a fragment), named MyFragment.java.

MyFragment.java

MainActivity.java

FragmentStatePagerAdapter vs FragmentPagerAdapter

What is the difference between these 2 adapters? Well is the way they handle the life of pages. The first will destroy and recreate the pages if we implement getItemPosition() POSITION_NONE. But the latter, will not destroy them, but it will attach and detach them which makes it perfect to use for fragments that are permanent.

Fun fact: notifyDataSetChanged() doesn’t work by itself on a viewPager. It has to be used together with

The above method is triggered by notifyDataSetChanged().

Android ViewPager Cube Animation

After trying some libraries in order to make a cube animation for my viewPager, I realized that is pretty easy to do this. Android provides an interface called ViewPager.PageTransformer and you just have to implement its method transformPage().

Below is the code, step by step.

activity_main.xml

view_pager_item.xml

 

And now, the interesting part of the tutorial:

CubeTransformer.java class

Let’s explain a bit this code. As you can see, we created a new class CubeTransformer¬†that implements the interface I mentioned at the beginning of the post,¬†ViewPager.PageTransformer. The tranformPage() method that has to be overridden, is called for each visible page and for its adjacent pages (left and right) and requires a view and position.

  • view: represents either the current view that starts beeing swiped, either the next one
  • position: represents either the position of the current view, either of the next one
    • 0 – is for the current view/page when it fills the screen
    • 1 – is for next view/page that has just been drawn
    • when the user starts to swipe between pages, page one (current) will have positions with negative values, and the next page that has to come in place, will have positions with positive values.

Before going further, we have to mention that in Android the x,y coordinates start from the top left corner.

The animation is done with just 3 lines of code:

  • view.setPivotX(): This is like a pin on the x axis around which the view will be rotated and scaled.

In our code, when position <= 0 (current image) we will set the pivot on the rightmost point of the X axis (view.getWidth()) , and when position > 0, (next image) the pivot is set on the left (origin of the axis) on X axis. This way, the pages will look like the faces of a cube.

  • view.setPivotY(): This is like a pin on the Y axis, around which the view will be rotated and scaled.

In our code, we set this to be on the halfway on Y axis.

  • view.setRotationY(): The view will be rotated vertically around Y axis with 90 degrees on the left multiplied by position.

So, using these 3 lines of code, we can have a cube animation on our viewPager ūüôā

Now, the final step of the tutorial, is about how to use the above class.

MainActivity.java

The only new thing in the above code, is this line:

The rest of the code is just the usual implementation of a ViewPager.

Android Navigation View With Tabs

In this tutorial we will create a simple app which has a NavigationView, a Toolbar with Tabs and a simple list of items, that are displayed for each selected tab.

Tabs & Navigation lollipop and above

Tools used:

  • Android Studio 2.2 Preview 4
  • Android Emulator 5x API 22

Project

  1. Create a new project by choosing the empty template and then click the Next button until the project is created.
  2. Switch the visibility of project structure by selecting “Project” option like in the image below.
    Android Project Structure

Part 1: NavigationView

First, we will create the NavigationView like explained further in the tutorial.

Summary

  • add¬†compile ‘com.android.support:design:24.0.0’ to dependencies in build.gradle
  • handle theme setup in values – styles.xml
  • handle theme setup in values-v21 – styles.xml
  • set the themes in AndroidManifiest.xml
  • create menu items for NavigationView
  • add strings in strings.xml
  • add dimensions for NavigationView’s header¬†in dimens.xml
  • create the xml file for the NavigationView’s header
  • set TabLayout and NavigationView in the activity_main.xml
  • setup NavigationView in MainActiviy.java

Explanation

  • build.gradle

    In the app module directory, open the build.gradle file and add¬†‘com.android.support:design:24.0.0’¬†to dependencies.

  • Theme setup in values – styles.xml

    Under app Рsrc- main Рres Рvalues Рstyles.xml, set the default AppTheme to support a NoActionBar theme.

    Styles.xml from this directory, will be used for Android versions lower than API Level 21 (Lollipop). Also, keep in mind that for lower versions of Android the status bar won’t be transparent when the NavigationView is opened.

  • Theme setup in values-v21 – styles.xml

    You will have to create this directory because we will use 2 attributes which are available only for Lollipop and above. The directory must be created like this:

  1. Right click on the res directory
  2. Click New – Android resource directory
  3. Select values directory and api level  like in the image below:
    Values v21
  4. Now, inside this directory create a styles.xml file like this:
    1. right click on the values-v21 directory 
    2. click New РValues resource file
    3. write styles.xml
    4. This is the code you should add:

The 2 attributes that are available only from API Level 21 and above are:

  • android:windowDrawsSystemBarBackgrounds:¬†Flag indicating whether this Window is responsible for drawing the background for the system bars. If true and the window is not floating, the system bars are drawn with a transparent background and the corresponding areas in this window are filled with the colors specified in {@link android.R.attr#statusBarColor} and {@link android.R.attr#navigationBarColor}.
  • android:statusBarColor: this will make the status bar transparent when the NavigationView is opened
  • Set themes in AndroidManifest.xml

  • Menu items for NavigationView

    Now, we will have to create a menu directory in which we will have to create a xml file containing the NavigationView items.

    1. Right click on the res directory
    2. Click NewAndroid resource directory
    3. Select menu directory menu
    4. Now right click on the menu directory
    5. Click New РValues resource file
    6. Write navigation_items.xml
    7. Add the following code:
  • strings.xml

    Add the following strings to res – values – strings.xml

     

  • dimens.xml

    Go to res Рvalues Рdimens.xml and add the following code.

  • nav_header.xml

    Under res Рlayout create a new xml file and name it nav_header.xml. This layout will be added as header to the NavigationView. It contains 2 texts and an icon (this file is taken from the NavigationView project from Android Studio Templates).

  • activity_main.xml

    In this xml file we will set the NavigationView, toolbar and tabs, using CoordinatorLayout. In the image below, we have described the hierarchy of the views (which view contains which view).

    CoordinatorLayout Hierarchy

    As you can see,¬†DrawerLayout is the root view of this layout and this is the correct way to do it. If you embed DrawerLayout inside other layout (let’s say a RelativeLayout as root view) and you place other UI components outside the DrawerLayout, those UI components will overlap the NavigationView when opened like below:
    DrawerLayout wrong hierarchy

  • Another wrong example, that I did in a project of mine, was that I used CoordinatorLayout¬†as root view instead of¬†DrawerLayout.¬†And because of that, the navigationView was not being opened over the status bar.Also, you have to keep in mind that FrameLayout¬†(the container) will be replaced in Java code with ContainerFragment.java¬†fragment. This class handles the¬†displaying of the list of items and tabs. You will see later how to use this class. So, by using the correct¬†hierarchy, we can now play with¬†scroll events for the toolbar, due to the use of CoordinatorLayout. But if we don’t follow this hierarchy, the scroll events or UI elements might behave in a strange way.
Explanation of some properties
  • android:fitsSystemWindows="true" Read TYL 15
  • android:theme="@style/AppTheme.AppBarOverlay" Read TYL 16
  • app:layout_scrollFlags="scroll|enterAlways" Read TYL 17
  • app:tabMode="scrollable" Read TYL 11
  • app:layout_behavior="@string/appbar_scrolling_view_behavior" Read TYL 13
  • MainActivity.java (intermediary code)

    At this point, you can run the app to see how the NavigationView looks like and how it behaves on different Android versions (pre-Lollipop and from Lollipop and above).

Next, we will proceed to part 2 of this tutorial: on setting up the tabs.

Part 2: Setup Tabs

Summary

  • setup xml file with ViewPager¬†for the container view
  • setup xml file with RecyclerView¬†for a page from ViewPager
  • setup xml file with a title TextView for RecyclerView¬†rows
  • create a new Java class for RecyclerView’s adapter
  • create a new Fragment¬†for ViewPager’s pages
  • create a new Fragment which represents the container. From here we will create the tabs and handle ViewPager’s adapter.

Project

  • fragment_container.xml

  • fragment_page.xml

  • recycler_item.xml

    Note: android:background="?android:attr/selectableItemBackground" is used in order to have a click effect on the RecyclerView when its rows are clicked.

  • SimpleRecyclerAdapter.java

  • PageFragment.java

  • ContainerFragment.java

  • MainActivity.java (final)

You can also see the project on Github.

Android: CoordinatorLayout RecyclerView First Item not visible

Problem

I had to implement a Toolbar with tabs, together with CoordinatorLayout, and the content of each tab had to be a list of items, for which I used RecyclerView. But when I ran the app, the first item in the list was overlapped by the tabs, so it was not fully visible.

This is how my xml file looked like:

FrameLayout is replaced in the code with a fragment containing the RecyclerView.

Solution

This property MUST be added to your scrolling view in order to make all list’s items¬†visible:

In my case, as I was using a FrameLayout¬†which contained a RecyclerView, I had to add this property to the FrameLayout, and not directly to the RecyclerView as it was in another xml file and wouldn’t work. But if you declare your RecyclerView directly inside CoordinatorLayout, you should add this property to it, and everything should be fine.

Just a final Note

If you are using ListView instead of RecyclerView together with CoordinatorLayout, you will encounter different scrolling and UI issues that will be difficult to handle. At first I had a ListView and tried to make the app work with it, but I ended up in refactoring the code and used RecyclerView instead. This way, all the UI issues were solved much more easily.

So my recommandation is to refactor your code and replace ListViews with RecyclerViews if you intend to benefit from the power of CoordinatorLayout.

Android AdMob With Firebase

About Firebase

First of all, you have to know that using AdMob with Firebase is¬†optional, at least for now, and you can still integrate AdMob by importing¬†compile ‘com.google.android.gms:play-services’¬†(like in this tutorial).¬†But even if it is optional, it is recommended, as it brings all services like AdMob, Analytics, crash reporting and other services together in just one place.

Integration

Versions used:

  • Android Studio¬†2.2 Preview 3
  • classpath google-services¬†3.0.0 dependency
  • firebase-ads 9.0.2¬†dependency

Project setup for supporting ads

  • google-services.json file from Firebase Console
  • In Project-level build.gradle¬†add Google Services¬†to dependencies
  • In App-level build.gradle¬†¬†add Firebase Ads to dependencies¬†and apply Google Services plugin
  • Internet Access

Before we start, create a new project with an Empty Activity template. After the project is created you should have MainActivity.java class and activity_main.xml file in res folder. We will refer to these later in the code.

1. Download google-services.json

This file is mandatory for your project to compile. If google-services.json file is not added to your project, you will get the following error when trying to sync App-level build.gradle.

So, in order to download it, you have to register your project in Firebase Console. Below are the steps:

Register project in Firebase Console
  1. Open Firebase Console and click on the Create New Project button
  2. Type your app name and click on Create Project button
  3. Now the following page should openAdd Firebase
  4. Tap on the button like in the above image
  5. In the new page that will open, type your project’s package name (you can find it in your AndroidManifest.xml file or in activities above imports)Firebase Add Details
  6. Now, after you press Add App button, the google-services.json will be automatically downloaded
  7. Copy the file that has just been downloaded and add it to your project¬†to the application’s root folder, YourAppName/app/Firebase Config File
  8. Click Continue and then Finish
2. Project-level build.gradle

Project Level Build Gradle

In the build.gradle file which is outside app module, you have to add the following dependency:

Now, tap on Sync Now to sync gradle.

3. App-level build.gradle 

Inside the app directory you can see another build.gradle file. In this file you have to add 2 lines:

Below is how the final code should look like:

Tap on Sync Now to sync gradle.

4. Internet access

In order to receive ads you need access to internet. So you have to add the code below in the AndroidManifest.xml, right above <aplication> element:

Add the ads

  1. Go to activity_main.xml file and add the following code

    Note: Notice that in order to use ads: properties we have to add to the root layout

    In order to get YOUR UNIT ID you should do the following:

    • go to AdMob¬†site, click on the Monetize New App button and add your app.
    • If you want to can link the app to Firebase from here. But you can skip an link it later like shown in this tutorial.

    monetize

    • after you add your app, on the Monetize page, you should find your project on the left. Click on it and you will see your Unit ID.¬†Unit IDs have the form ca-app-pub-XXXXXXXXXXXXXXXX/NNNNNNNNNN.

    admob_monetize

    test_unit

    Now, just copy it from here and paste it into your activity_main.xml file.

  2. Go to MainActivity and add this code:

NOTES

NOTE 1:

YOUR APP ID is different from Ad Unit Id. Application IDs have the form ca-app-pub-XXXXXXXXXXXXXXXX~NNNNNNNNNN and can be found on your AdMob account page by clicking the Settings icon РApp Management.

NOTE 2:

It is very important to run the ads in debug mode on your own devices, in order to avoid being disabled for clicking your own ads. So, to get your device ID, you have to run your application on the DEVICE in debug mode and wait for an ad to load. Then go to logcat output and search for the ID. It should be at Log INFO like in the picture below. You can add as many devices as you want.

android_adMob_ID

Link your app from AdMob to Firebase

If you want to see Firebase Analytics information in AdMob you have to link your app from AdMob account with Firebase project we have just configured earlier.

  1. From AdMob account, tap again on the Settings icon – App management
  2. Search your app and tap on the Link to FirebaseLink to Firebase
  3. Add the package name of your app you (in our example we have to use the package name we used when we configured our app directly in Firebase)AdMob Package
  4. Click Continue button and you should see the following screenLink to existing
  5. In our example we let the first option to be enabled (Link to existing…) as we got an error that we cannot create a new Firebase project due to limit exceeded (even though we only have this project). Click the Continue button and done.

Successfully linked

See your linked apps in Firebase Console

View Linked Apps

Android Gradle Dependencies by Flavors

In a previous post about Gradle Flavors and Build Types, we mentioned that we can set different dependencies inside dependencies{} block by flavors, by build type or both combined. Below we will see an example for each situation.

By flavors

  • <flavorName>Compile

By build type

  • <buildTypeName>Compile>

By both flavor and build type

  • <flavorName><BuildTypeName>Compile.
  • In this case you have to define the custom compile in configurations{}¬†block in order to be recognized in dependencies{} block.

    Final result: