Android Recyclerview Tutorial with SQLite ROOM : using MVVM, Dagger 2

What we will be building ?







A simple note taking app, which will have option to add notes and delete it. This will be a minimal design tutorial and hence we won't be spending much time on the app UI. This tutorial will be more focused on the MVVM, dagger2 and building an overall app architecture. This app will be improved in upcoming tutorials with more features, so make sure to stay tuned for that as well.

What are we will be covering ?

We will be using Java 8 to get access to various features like lambda functions, so we will need to enable this in app level build.gradle

We will be making use of data binding, so we will need to enable this also on your app level build.gradle

We will be using Dagger2 for building our dependencies

We will be having a base activity class which will be responsible for performing redundant operations like dependency injection, data binding, setting viewmodels for activities etc. So basically this app structure is developed with more activities to be incorporated in future.

The main reason for choosing MVVM and live data is that, with this pattern database operations like insert, delete gets effortlessly simple. We just need to observe to the database changes and as a result all the UI changes is reflected on the go. There are more advantages to this pattern, we will discuss these while moving forward.

Getting started with project building :

First of all, open your android studio, in file go to new>> new project and then create a project with empty activity

Dependencies Required ?

First of all update project level build.gradle as show below. Here we have set the versions for some dependencies that we will be using in our app :

Now go ahead and update your app level build.gradle with  dependencies for recyclerview,cardview,dagger,room,livedata etc as shown below :


As shown above we have enabled databinding by adding this

dataBinding {
enabled = true}

Also enable java 8 as shown below

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8}


Now let us jump into the coding session right away. Now, since we are making a notes app we will need to make a note model class. So in terms of SQLite ROOM, we will call this an entity. Entities in room are just another java class which is annotated with @Entity annotation. Annotating a class like this will help room in identifying it as an SQLite table. So now our room entity/table will have an notesId field which will be auto incremented on insertion, a notesTitle field and a notesDesc filed. We will be naming our table as notes_model which will be provided in brackets along with the @Entity annotation. So create a class like the following and name it NotesModel.java

Now go ahead and create a DAO class, by annotating it with @Dao. This class will basically act as an interface which will query the sqlite database as per our request. It will contain the various sql queries like insert,delete etc, now name it as NotesDao.java


Now it is time to create our database class, which should be annotated with @Database. Inside the annotation arguments, we can provide an array of entities where we can provide a list of tables/entities that we need inside our database, but for now we will be giving a single entity/table name which is NotesModel and we will keep the database version as 1 . So create the database class as follows :

It is now time to create our NotesRepository which will provide us with the live/updated database changes. It is where we define our live data methods from our db which will be later observed in activity. So create the repository as shown below and name it as NotesRepository.java

You might have noted the @Inject in the constructor which means that we will be getting these dependencies using dagger2, we will see how to create these dependencies using dagger2 later in this tutorial

Now create an abstract class BaseViewModel from which we will be extending all the viewmodel classes

Now we will need tocreate a viewmodel class for our MainActivity, so create MainActivityVM.java  like below

Now we will be creating the BaseActivity.java and make it abstract from which all our activties will be extending from. Also our BaseActivity.java will accept generic params for ViewDataBinding,BaseViewModel etc which means that the respective activities will be supplying our base activity with these params as required so that all databinding, setting viewmodels etc happens in the baseactivity itself.

We will also be using abstract methods for getting binding variable,activity layout, and viewmodel from respective activities. These abstract methods are getBindingVariable(),getLayoutId(),getViewModel() respectively.
now that we have all required attributes for databinding and dependency injection, we can create BaseActivity.java like following :


Now update your layout file which is present in res>> layout>>activity_main.xml , as shown below :

Now add a new layout file for the add new note dialog and name it custom_dialog_with_btns_view.xml


Now goto the project explorer on left hand side of your screen and right click on your package directory and create a new package named "di". This is to organize all your dagger files in this directory, it is optional to create a directory like this but it is highly recommended so that the code becomes more understandable.

Now right click on the di directory, and create a new abstract class and name it ActivityModule.java

In the above class you might have noticed the annotation @Module  which means that this class is a module and in this case this module will be used to provide various activities in our app like MainActivity. All the future generated activities must be defined here.

Now in the same directory - di, we will need the custom annotation ViewModelKey to generate our ViewModelModule.java . So first create interface ViewModelKey.java as follows

Now in the di directory, create another abstract class with @Module annotation and name it as ViewModelModule.java . This module class will provide all the ViewModels in the project. All the ViewModels should be defined here


Create another @Module annotated class AppModule.java which has included module as ViewModelModule.class as follows

Now you will need to design the view for note item, so go to res>>layout, right click on layout directory and click create new layout resource file and name it notes_item_view and add below contents to it

In the above layout for the recyclerview adapter, we have used data binding to set text into the textview. Basically, inorder to perform data binding, we need to make the root layout as "<layout>", also you will need to import the NotesModel and assign it to a variable as shown below.
<data>
<import type="com.example.recyclerviewsqliteroomcrud.persistance.NotesModel"/>
<variable
name="itemModel"
type="NotesModel" />
</data>
Now create a recyclerview adapter like shown below, also you will need to bind the above layout with this adapter in the viewholder

Now update your MainActivity.java  like show below



As shown above we have injected the MainActivityVM. Also we have returned the viewmodel(MainActivityVM) and layout file(activity_main) to the BaseActivity so that we can perform databinding and viewmodel setup inside the BaseActivity itself. This process will apply to all future activities that may be created in the app.
Now we will need to create a component class which will be used along with the earlier created module classes to generate the dependencies using dagger. So create AppComponent.java as shown below :


Now as a final step,we will need to generate the application class which will initialize dagger to build the necessary dependencies. So create BaseApplication.java

As soon as you copy the above file you may notice that DaggerAppComponent is given in red and shows error. This is because dagger has not yet generated the dependencies, inorder to do that click on File>>Sync project with gradle files . If everything goes well, the error will be gone and you may then organize the project structure as shown below(optional)


Finally, go to AndroidManifest.xml and update the application name as .BaseApplication as shown below



How to create github repository from android studio without using a web browser or command line ?


Hi guys in this tutorial we will see how to create a github repository from Android Studio. For this purpose we will not be required to open command line or the web browser. Entire process from repository creation to your first push will be completely carried out on your android studio IDE, provided that you already have git installed on your pc and that you have a valid github account.

It significantly reduces the hassle and also saves a lot of time since we won't be spending much time on writing the commands or be going to the github website to create new repository. All the hassles will be handled by android studio.

So Android Studio will help us in creating the repository, adding all the files for commit, commit the files to be pushed and finally push the project to the github repository created.

Before you begin :

1) Download and install git if you haven't already done.
for mac OS : https://git-scm.com/download/mac
for windows : https://git-scm.com/download/win

2) go here and create a github account >> https://github.com/

Now follow the below steps to create a github repository in the above created account from android studio :

1) First of all open up android studio and create a brand new android studio project. Once the project has finished the building process, goto the VCS option on the top menu as shown below

VCS option appears in the top menu

2) From the above VCS option navigate VCS > Import into version control > Share project on Github like shown in the image below

Share project on Github
3) Now we will be asked to login with your github credentials before sharing the project on github. We will be required to perform this only once since we will be generating an API token during our first login and then will be using this saved token value to login further. So first of all click on "Create API token" to generate one.

Click on "Create API Token"
4) When "Create API Token" is clicked, it will bring up the following screen to login into github. Enter the credentials for github and click login, it will generate the API Token like shown below.

Login here with github credentilas
Generates token on successfully login

5) In the above login screen click the checkbox "Save Credentials" so that we won't have to do this process each time we try create a repository. Now click on login button again. You will be successfully logged in and taken to the following screen
Entering repository details
As shown above you will be prompted to enter a name and description for your repository, keep the remote name as remote. You can also make your repository private, which was earlier a paid feature in github. Now click on share button.

6) As soon as we hit share button, we will be asked what all files are needed to be added to git, since this is our first commit we can select all files like shown below, doing which will make all your files ready for commit

Initial commit to git

As shown above select all files (already selected by default) and enter a commit message. Now click OK button. As soon as we hit OK button we can see that all the files get committed and finally pushed to the remote github repository, you will also be presented with a link to your repository at the bottom of android studio like shown below

Github repository created
Click on the link shown in the image above and you will be taken to your repository in gihub like shown below

Github repository opened in browser


Android Studio git tutorial using github, bitbucket

Hi guys! In this tutorial we will see how to work with git in android studio. We will be showing how to setup git using both github and bitbucket.

Git is basically a distributed version control system for tracking changes in source code during software development. Repository hosting services like github, bitbucket etc are used for version control using git.

We will be breaking down the tutorial into the following steps :

1) Downloading and Installing git
2) Create an account on github/bitbucket and then save the credentials to your git configuration
3) Create a remote git repository using github/bitbucket.
4) Create an android studio project and initialise git within the project.
5) Add the remote repository as the origin of your android studio project.
6) Commit and push your code into remote repository(github/bitbucket)


1) Downloading and Installing git


  • For mac users first of all go to your terminal and check if git is already installed by typing the command git --version , if you get a version value like shown below you already have git installed and you are good to go. If you don't have git installed, you will be getting a message like "command not found", in that case go here >> https://git-scm.com/download/macand install git on your mac
git version check

  • For windows users check if git is already installed by typing git --version in the command prompt, if you are able to get a proper version, then you already have git installed. If you don't have git installed, go here >>  https://git-scm.com/download/win and complete the installation

2) Create an account on github/bitbucket and then save the credentials to your git configuration


  • If you are working with github, go here >> https://github.com/ and create an account(signup)
github signup

  • If you are working with bitbucket, go here >> https://bitbucket.org/account/signup/ and create an account(no need to signup for both github and bitbucket, choose only one which is convenient to you)
bitbucket signup

  • Once you have created the account in one of the repository hosting services, you will now need your local git version control system to be connected with it. For that, go to your terminal and type git --version to ensure that git is properly installed. It should be displaying proper git version number, if not try installing git properly as discussed above. Now, execute the following command in your terminal(mac) or cmd(windows) to connect your remote repo with your local git.
git config --global user.email "your_github_or_bitbucket@email.com" 
git config --global user.name "your_github_or_bitbucket_username"
  • As shown above you will have to specify your registered email and username in above commands. Now when you make commits and other activities to your remote repo(github/bitbucket), your identity will be shown based on these credentials

3) Create a remote git repository using github/bitbucket.


  • Now that you have properly setup your remote repo and then configured it with your git version control system, you will need to go ahead and create a new repository in github/bitbucket.
Now you will need to choose which git repository hosting service you are going to use. You don't need both, choose any one - github or bitbucket ?

          GITHUB REPOSITORY CREATION
  • For github, login with your account and click on the plus button at the top right corner which brings up an option "new repository".
github - create new repository
  • Click on "new repository" and enter the details to complete repository creation. You can either make your repository "public" or "private" as well. When made public, it can be accessed by anyone across the globe whereas private repositories can be accessed only by select individuals whom you choose to share it with. Private repositories were a paid feature in github before, but now it has been made free, thanks to github!
  • Once the repository has been created successfully, it will bring up a screen like shown below
unique link to your github remote repo(highlighted with red marker)
  • Copy the command that starts with "git remote add origin ..", which is the unique link to your remote repo. This command will be used in our android studio terminal to connect your local repo with the remote repo that we just created.

          BITBUCKET REPOSITORY CREATION
  • For Bitbucket, repository creation is similar to github and is straight forward(If you are using github, you are free to skip this step). After logging in to your bitbucket dashboard, you can see a '+' button on the left sidebar, click on it and then select repository from next window to create a new bitbucket repository.
create new bitbucket repository
  • Give a name to your repository and similar to github here also you have option to make it public or private. Choose private if you want it be accessed by people whom you give access only. Now complete repository creation
  • Once the repository has been created you will see the following window from which you will need to copy the remote repo url at the bottom of the screen as shown below
unique link to your bitbucket remote repo(highlighted with red marker)
  • The above copied url will be used in android studio terminal to connect local git repo with the bitbucket repo that we now created

4) Create an android studio project and initialise git within the project.

  • Now start up your android studio. First of all create a new android studio project, finally when your project gets properly build click to open the terminal window at the bottom of the Android Studio IDE.
android studio terminal
  • Now type the following command in your android studio terminal to initialise git within your android studio peoject and hit enter
git init
git init command executed in android studio terminal


5) Add the remote repository as the origin of your android studio project.


  • git is now successfully initialised in your project. Now you will need to get the repository url that we copied earlier while we created our repository. For me it is 
    git remote add origin https://github.com/Navneet7k/SampleGithubTutorial.git
  • This url will be different for your repository, so make sure to copy the right url from your repository. Now paste this inside your android studio terminal and hit enter. If everything is fine, we won't see any error and hence we have successfully linked our local repo with the remote repo.
If you are asked to enter the password, please enter the password for your github/bitbucket account, you wont be shown a password preview, but keep typing and then press enter
  • Now we will see how to move your repository from your local machine to the remote github/bitbucket repository. For that, first of all we will need to add all the files that we need to move to your remote github repository. Since we are starting with a new project let us add entire project( all the files) to github/bitbucket repo. So type in the following command and hit enter
git add .
  • As a result of the above command the entire project gets added(i.e, gets prepared for commit). Here '.' means you are going to add all files to remote repo. Instead if you need to add only a single file, you will need to execute something like this git add your_filename.java . For now we will be doing git add . since we will have to move entire project to our remote repo(github/bitbucket)
  • Before we push our project to github/bitbucket, we will need to commit the changes with a commit message. Since we are making an initial commit for our project we can keep the commit message as "initial commit"(of course, you may set a different message of your choice!). Always make sure to keep a meaningful commit message to all your commits. This helps a lot since it becomes a lot easier to identify changes in each commit at a later point of time. Now execute the following command to commit all the files that have been added.
git commit -m "initial commit"
committing all the added files to git

  • As soon as the commit command is executed, all the files gets saved in your local git. Now we are ready to "push" our changes into our remote github/bitbucket repo. So execute the following push command to push all the committed changes into the remote repository's master branch
git push origin master
pushing committed changes to github/bitbucket remote repo 

  • Now if we go ahead and check our repo in github, we can see that all the files have been successfully pushed like shown below
files pushed successfully

  • Now if we check the "commit" tab you can see your "initial commit" is shown there with the person who did the commit and the date in which the commit has been made. Hence it becomes helpful in identifying a commit very easily.
  • Now go inside one of your files and make a small change for testing purpose (below i'm adding a comment inside MainActivity.java file)
added a test comment to commit
  • Now go ahead and commit this change by running the following command in android studio terminal
git commit -a -m "test commit"
  • As a result of the above command all the changes get added and committed with the commit message "test commit". This command is basically a shortcut to both add and commit the changes in a single command. (You can alternatively type git add . and git commit -m "test commit" separately also)
  • Now again execute the push command like shown below
git push origin master
  • Now if you check your repository in github, you can see that the changes have been reflected there also.
test commit successfully pushed
  • Now if you check the commit tab you can see that our new commit has appeared there as well, see image below

all commit messages
  • Thats all for this tutorial guys, i will try to make more tutorials on git like this later

     


Android Q Bubbles in Action

Android Q bubble

Hi guys, in this tutorial we will be discussing about the new bubbles feature introduced in Android Q. You might have already come across facebook chat heads, well the new bubble feature in android Q is a similar feature. But for android Q Bubbles, it is supported by the android OS itself. From now on, we just have to use the bubbles feature to build such widgets.

You may check here >> https://www.youtube.com/watch?v=td3Kd7fOROw to see an intro about android Q bubbles mentioned in the google i/o 2019

As mentioned in https://developer.android.com/preview/features/bubbles,

Bubbles are built into the Notification system. They float on top of other app content and follow the user wherever they go. Bubbles can be expanded to reveal app functionality and information, and can be collapsed when not being used.
 Features and Characteristics :

  • The bubbles float on top of other apps and hence allows seamless multitasking.
  • Since the bubbles are built into the notification system, it appears as a normal notification in case the device is locked or if the always-on-display is active
  • Bubbles are basically an opt out feature - i.e, the user can choose whether to have the bubbles enabled for an app or not.

Now we will see how to implement this in code :

First of all update your app level build.gradle like shown below

The activity which opens up when a bubble is clicked needs to follow certain guidelines to function properly with bubbles.So inside your AndroidManifest.xml, an activity should be declared as resizeable, embedded, and always launch in document UI mode like shown below



Now in order to create a bubble notification, you will need to :

  • Create a notification like you normally do
  • Create a bubble metadata object by calling Notification.BubbleMetadata.Builder
  • Then by using setBubbleMetadata  add the bubble metadata into the notification

So update your MainActivity.java file like show below :


You may also create a bubble which is expanded automatically by specifying setAutoExpandBubble() and setSuppressInitialNotification() as true. Skip this step if you don't want the bubble to upen automatically
Now your activity_main.xml should be updated like this :

Using custom gson converter to parse dynamic json with free source code

We often come across issue where a json dynamically switches its type based on the response. For example, in normal cases suppose that you have a list of cars returned as an array from your backend, but when the number of cars in the list is one, you are given just an abject instead of array. In such cases, your code should be ready to handle the response no matter whether it is an array or an object.


To handle such cases, Gson provides plenty of customisation options. One such option is registerTypeAdapter. So lets dive deeper to check how its done.

In this tutorial we will be using retrofit to make the network calls and of course gson-converter, so go to your app level build.gradle and add the following as dependencies

implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

please add the latest dependency versions for retrofit, converter-gson


Now check the following json strcutures that we will be parsing

cars_object_json.json
{
"cars" : {
   "car_type" : "Hatchback", 
   "car_models" : {"car_name":"Swift" , "power_window":"yes" }
  }
}

cars_array_json.json
{
"cars" : {
   "car_type" : "Sedan" , 
   "car_models" : [ 
      { 
         "car_name" : "Xcent",
         "power_window" : "no"
      },
      {
         "car_name" : "Ciaz",
         "power_window" : "yes"
      } 
  ]}
}


In cars_object_json.json you can see that car_models is an object because there is only one item inside it whereas in cars_array_json.json  car_models is an array since there are more than one items in it. We have to write a parser which could automatically identify the response format and parse both the cases easily. registerTypeAdapter is exactly what we want here.

Alright, lets see some code now

First of all, there are two type of object models or POJOs that we need to create for the above json >> Cars,CarModels

1) Automatic model class/pojo class generation using http://www.jsonschema2pojo.org/
Specify Target language as Java, Source Type as JSON and annotation style as Gson
  • Now click preview and copy the generated java files
Now copy the contents of the class and add it in android studio project

Now copy the classes Cars,CarModels from http://www.jsonschema2pojo.org/ and add it to your project like this

Cars.java

public class Cars {
    @SerializedName("car_type")
    @Expose
    private String carType;
    @SerializedName("car_models")
    @Expose
    private List<CarModel> cardModels = null;

    public String getCarType() {
        return carType;
    }

    public void setCarType(String carType) {
        this.carType = carType;
    }

    public List<CarModel> getCardModels() {
        return cardModels;
    }

    public void setCardModels(List<CarModel> cardModels) {
        this.cardModels = cardModels;
    }

}


CarModels.java

public class CarModel {
    @SerializedName("car_name")
    @Expose
    private String carName;
    @SerializedName("power_window")
    @Expose
    private String powerWindow;

    public String getCarName() {
        return carName;
    }

    public void setCarName(String carName) {
        this.carName = carName;
    }

    public String getPowerWindow() {
        return powerWindow;
    }

    public void setPowerWindow(String powerWindow) {
        this.powerWindow = powerWindow;
    }
}


Now, create a deserializer like shown below

GsonBuilder b = new GsonBuilder();
        b.registerTypeAdapter(Cars.class, new JsonDeserializer<Cars>() {
            @Override
            public Cars deserialize(JsonElement arg0, Type arg1,
                                     JsonDeserializationContext arg2) throws JsonParseException {
                JsonObject CarsObj = arg0.getAsJsonObject();
                JsonObject innerObj=CarsObj.getAsJsonObject("cars");

                Gson g = new Gson();
                Cars a = g.fromJson(arg0, Cars.class);
                List<CarModel> carModels = null;

                if (innerObj.get("car_models").isJsonArray()) {
                    carModels = g.fromJson(innerObj.get("car_models"),
                            new TypeToken<List<CarModel>>() {
                            }.getType());
                } else {
                    CarModel single = g.fromJson(innerObj.get("car_models"), CarModel.class);
                    carModels = new ArrayList<CarModel>();
                    carModels.add(single);
                }
                a.setCardModels(carModels);
                return a;
            }
        });

In the above deserializer, you can clearly see that we have checked whether car_models is an array or an object and then parsed the response accordingly.

Now go ahead and attach the converter to your retrofit implementation so that the entire code for your MainActivity.java will look like this

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        parseJson();
    }

    private void parseJson() {

        GsonBuilder b = new GsonBuilder();
        b.registerTypeAdapter(Cars.class, new JsonDeserializer<Cars>() {
            @Override
            public Cars deserialize(JsonElement arg0, Type arg1,
                                     JsonDeserializationContext arg2) throws JsonParseException {
                JsonObject CarsObj = arg0.getAsJsonObject();
                JsonObject innerObj=CarsObj.getAsJsonObject("cars");

                Gson g = new Gson();
                Cars a = g.fromJson(arg0, Cars.class);
                List<CarModel> carModels = null;

                if (innerObj.get("car_models").isJsonArray()) {
                    carModels = g.fromJson(innerObj.get("car_models"),
                            new TypeToken<List<CarModel>>() {
                            }.getType());
                } else {
                    CarModel single = g.fromJson(innerObj.get("car_models"), CarModel.class);
                    carModels = new ArrayList<CarModel>();
                    carModels.add(single);
                }
                a.setCardModels(carModels);
                return a;
            }
        });
        
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://navneet7k.github.io/")
                .addConverterFactory(GsonConverterFactory.create(b.create()))
                .build();
        

        RequestInterface request = retrofit.create(RequestInterface.class);
        Call<Cars> call1=request.getJson();
        call1.enqueue(new Callback<Cars>() {
            @Override
            public void onResponse(Call<Cars> call, Response<Cars> response) {
                Toast.makeText(MainActivity.this,"Success!",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call<Cars> call, Throwable t) {
                Toast.makeText(MainActivity.this,"Failure",Toast.LENGTH_SHORT).show();
            }

        });
    }

}

And your RequestInterface.java for cars_object_json.json  will be like this

interface RequestInterface {
    @GET("cars_object_json.json")
    Call<Cars> getJson();
}

RequestInterface.java for cars_array_json.json  will be like this


interface RequestInterface {
    @GET("cars_array_json.json")
    Call<Cars> getJson();
}

By this method you will get the correct response for Response<Cars> response in the retrofit callbacks even if your response changes dynamically.