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 cars is an object because there is only one item inside it whereas in cars_array_json.json cars 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.

Android image slideshow/image carousel using viewpager



In this tutorial, we will discuss how to implement a slideshow of images which rotates its slides on its own. These image carousels/slideshows find their use when we want to showcase our products, suppose we are running an e-commerce app. It can also be used to update recent events, live updates etc. Providing a slide show of selected items within your app can allow easy and fast access to them.

Now let us look into some coding part :

We will be doing a slide show of cars in this tutorial. So we will have to define some attributes for our car objects. So create a model for the car object as shown below:
Now we will need to pre-populate an arraylist of the above model so that we could easily pass it into the slideshow. In order to create a slide show, we will be using a viewpager. We then use a handler to slide the items in viewpager automatically. Now open up your MainActivity.java file and make the following changes.
As shown above you will need to create a viewpager and obviously, an adapter for this viewpager. We then pass the arraylist with the car objects to the adapter like shown in populateSlides() method and finally set the adapter to the viepager like this viewPager.setAdapter(pagerAdapter); .
Now you can create like shown below
You have successfully created an image carousel of cars, try running the project now!
You can download the complete source code here 

Paypal Integration in android using Braintree SDK

performing paypal payments using braintree android sdk
Braintree is a division of PayPal and is a company based in Chicago that specializes in mobile and web payment systems. Braintree provides client libraries and integration examples in Ruby, Python, PHP, Java, .NET, and Node JS. It also provides mobile libraries for iOS and Android, and Braintree.js for in-browser card encryption.
Braintree payment gateway is basically a paypal service, so we would require braintree sdks to be integrated in our android code. We can then link our paypal credentials with braintree dashboard.


We will see how to integrate braintree  sdk in android and perform paypal transactions
  1. First of all go here https://www.paypal.com/in/webapps/mpp/merchant and create a paypal merchant account. You may choose to create shoppers account or business account or freelancers account based on your needs.
  2. As soon as the above step is complete, head over to the paypal developer website here https://developer.paypal.com/ and login with the above generated credentials. Once you are logged in click on your username at the top right corner and then click on dashboard. Now click on "create app" option in your dashboard. Now fill in the app name for your sandbox environment and complete the app creation. As soon as the app is created, you can see that the client id, client secret has beem generated has been generated.
  3. Now go here and create braintree sandbox account >> https://sandbox.braintreegateway.com/ . Once the account is created, goto Settings >> processing >> paypal. Now toggle paypal to turn it on. Now click on "options" next to the paypal field. Now enter the paypal email, client id, secret id generated in step 2 and click update to save. Now we have successfully linked paypal with braintree.
  4. Once you are logged in with the braintree sandbox account, you can goto Account >> Merchant Account Info and then click "new sandbox merchant account" to create a braintree merchant account for testing purposes. The braintree merchant account is not like a bank account, basically this account directs funds from your customers to your business bank account.
  5. You may create any number of  braintree merchant account like shown above. While creating the braintree merchant account, it can be set as the default merchant account so that the transactions will be using it as the default one.
As of now the initial dashboard setup is now complete.

Follow the below steps for integration :

  1.  The first step is the generation of client token at the server side using your server side braintree library. We will be following .NET library for server side integrations. Check here for other formats available
Following library supports both .NET Framework 4.5.2+, .NET Core 1.0+ and higher.

  • Version: 4.8.0
  • SHA256: a700b98818c1f4266701160a1059d75f1cb17aa8d8ae12696c6812264781d932
        2.  Once the braintree library is setup login to your braintree sandbox account here >>                       https://sandbox.braintreegateway.com/ and goto settings >> API Keys. Now click on 
"Generate new API key". Now you will get a public key, private key and merchant id if you click the "view" option in the generated API Key. Now add the above generated values as shown below

        3. Now that you have setup the braintree sandbox, the next step is the generation of client token, which will be required at the client side to initialise the client side braintree sdk(in our case >> android braintree sdk). Inorder to allow return customers to choose previously chosen payment method options, you can make use of a customerid like shown below

Now generate the client token and expose it to the clients like shown below

         4. Now, the client(android app) requests the client token and intialieses the client side sdk using this client token. Once the sdk is initialised, the client generates a payment_method_nonce value and sends it to the server, the server should accept the payment_method_nonce value like shown below

         5. You have now successfully accepted the payment_method_nonce value from the client which depicts client side authorisation to create transaction. So create a transaction  like shown below, using an amount and the payment_method_nonce you received from client

Now let us see some client side code using android

Add the following dependency in your app level build.gradle

implementation 'com.braintreepayments.api:drop-in:3.7.0' 
implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta4' 
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

In our server side implementation, we have already created an api to expose client token(check step 3 in server side integration). We will need to get this client token to initialise our braintree payment gateway sdk in our app side. So write a network call to fetch client token like shown below(here we are using retrofit library for network calls)
and create RequestInterface.java like this Please note that you have to set the base url and endpoint according to the one that you have created in step 3 in server side integration
As you can see above we need to pass the client token like this onBraintreeSubmit(response.body().toString()); to the braintree sdk from the onResponse method of our retrofit instance. So we need to write the code for this method like shown below
Now we will need to override onActivityResult as shown below, so that we can get the results from the braintree sdk
As shown above, we have successfully obtained the nonce value from the braintree sdk like this String payment_method_nonce=result.getPaymentMethodNonce().getNonce(); . Now we will need to send this nonce value along with an amount to our server side implementation to perform the transaction at the server side. So create submitNonce() method like shown below :
now update your RequestInterface.java like shown below

startactivityforresult example in android



startActivityForResult method helps to send data to another activity, get data from another activity or even wait for the result from another activity to perform certain action/ process the result data.

The process involved are,

  • Consider there are two activities - MainActivity.java and SecondActivity.java, the main activity calls the second activity and waits for the result like shown below, 
Intent intent=new Intent(MainActivity.this,SecondActivity.class);       
startActivityForResult(intent, 2);

  •  Now the SecondActivity performs the required operations(if any) and returns the result like shown below
Intent intent=new Intent();      
intent.putExtra("MESSAGE","your message to FirstActivity ");                   
setResult(2,intent);

  • Now we should override the onActivityResult method inside MainActivity which gets automatically invoked once the results from the SecondActivity are returned. It is overidden like shown below
          @Override  
          protected void onActivityResult(int requestCode, int resultCode, Intent data)  
          {
                 super.onActivityResult(requestCode, resultCode, data);  
                   if(requestCode==2)  
                         {
                            String message=data.getStringExtra("MESSAGE");   
                         }
          }  

  • Finally you can now access the message send from the SecondActivity using the  String "message" 
Now let us look into a working example. In this example, we will be passing a message from an editext field inside the SecondActivity.java to a texview field in MainActivity.java . So first of all create a new android studio project and make the following changes to your activity_main.xml file
As shown above we have created a button to call the second activity and also added a textview to display the result from second activity. Now we need to call the second activity and wait for result as shown below :
As shown above we have used startActivityForResult to start the second activity so that we we will get the result from the second activity in the callback method - onActivityResult
Now create new activity and name it as SecondActivity.java . Create an edittext field to type the message and also add a button to send the message
Now you may update the SecondActivity.java like this

Blockchain explained with javascript, node.js

We all have been aware of the terms blockchain and bitcoin recently. People usually confuse between the two terms and don't really realise that both are not "equal". Let us now figure out what these actually mean and how do they function.

A blockchain, is simply a list of blocks/nodes that are linked using cryptography. The blocks in this chain are interconnected with each other using a cryptographic hash. Hence each block contains a cryptographic hash of the previous block, a timestamp and the transaction data. The blockchain basically acts as a public ledger which records the transactions.

Bitcoin is a cryptocurrency. It is a decentralised digital currency which does not offer/require a central point of administration. Here the transactions can be carried out without the help of an intermediate authority like a bank. The bitcoin is one of many cryptocurrencies which uses the blockchain ledger.


Typical Usage Scenario

Now let us dig deeper into blockchain. First of all consider a normal scenario where you are transferring some amount of money from your bank in UK to one in the US. First, we request a 3rd trusted party(a bank) to transfer some amount to certain bank account in US. The trusted 3rd party then identifies the bank account in US and transfers the requested amount to the particular account. For doing this, the trusted third party(your bank) charges a certain amount of money as a transaction fee. Also, the entire operation may consume a lot of time(may be even days). Here is where the blockchain comes in, where we completely get rid of the third party. The transaction will take place directly between the sender and receiver. The transaction fee now becomes almost negligible and the time gets reduced from days to seconds! yes just seconds!

Time and transaction fees are definitely the two most advantages of a blockchain powered cryptographic system.

Open Ledger

Consider a blockchain which consists of some nodes A,B,C,D. Now let us assume that A wish to perform a transaction with B , B would like to perform a transaction with C and so on. All this transaction appears on a ledger which is public. The importance of an open/public ledger is that everyone on the network can easily know how much money each node in the network has, also each node in the network can decide whether a transaction is valid or not.

Suppose that A had 10$ during the initial condition and it has already transferred a sum of 5$ with B. Once the transaction is complete and the entry has been successfully created in the public ledger, the data is now public and everyone in the network now knows that A only has a remaining balance of  5$. Now if A again initiates a transaction of 10$ to D, all the nodes in the network easily invalidates the transaction as A only has a balance of 5$ and it is practically impossible to transfer an amount of 10$.

As a result every new transaction in a blockchain needs to be validated by all the participating nodes

Distributed Ledger(decentralised)

In the concept of open ledger we have seen that it is centralised, but we need to get rid of its centralised architecture to match the blockchain principles. So we would be having a copy of the ledger on each node. Here the goal is to keep all the ledgers synchronised. So each of the node will be updating the ledger whenever a transaction takes place in the network. 

Miners

Suppose a scenario where a node A wants to perform a transaction with node B. So what basically A does is that it publishes/broadcasts an intended transaction message on the network. As of now this transaction is an invalidated one. So here is where the miners comes in. Miners are special nodes in the network who has access to the ledger. As soon as an intended transaction is created in the network, the miners will compete among themselves to validate the transaction and add it to the ledger. The first miner to do so will get a financial reward, in the case of a bitcoin network they will be awarded a certain amount of bitcoin.

In order to successfully add a transaction to the ledger, the miners will have to two things :
  • Check if the transaction is valid. This step is easy, since the ledger is open and the miners could easily analyse if the node has enough funds to perform the transaction.
  • Find the unique key which can be used to lock the current transaction with the previous transaction. In order to find the key the miner needs to invest huge computational power and time since the key is completely random. This process of investing huge computational power and time to find the unique key which links a new transaction to the chain successfully is called as mining.
As soon as key for the current transaction is mined by a miner, all the other miners now will have to stop mining the key for that transaction since it is already mined and added to the blockchain. Now what all the miners will do is that, all of them will update their ledger with the new transaction so that they could start mining the key for next transaction. There is no point in searching the key for a transaction which is already validated since the financial reward is already claimed by someone(of course another miner!) . All the nodes will have to update their copy of ledger to mine for further transactions.

Now let us see how can we give a programatic explanation to the bitcoin architecture :

First of all create a new javascript file and name it blockchain.js. Now create a class named Block that takes in index, timestamp, data and previousHash through its constructor as shown below


Now we will need to create the calculateHash() shown above. For that we will need SHA256  as a hash function. In order to import this library, first navigate to the blockchain.js file using terminal and type in the following command :

npm install --save crypto-js
Now update the blockchain.js file with the following code

In the above code you can see that calculateHash() is used to create a SHA256 hash using the index, timestamp, data, previousHash of the current block. This creates the key hash for the current block

If you check the addBlock(newBlock) method in Blockchain class, you can see that we have set the previousHash value of new block to hash value of the latest block, which means that each node in the blockchain points to the next node using a unique key hash.

Also inorder to make the blockchain hack proof, we have written a check isChainValid(). This function basically returns that the block chain is not valid when the chain is tampered with. For example, if we update a block with a new amount value and recalculate the hash, the isChainValid() function would return as false.

Now open your terminal and try running

node blockchain.js

You will be able to see your blockchain like shown below

blockchain that we created

Now, let us check if our blockchain is valid by adding the following console.log statement at the bottom of blockchain.js

console.log('Is chain valid? ' + navneetCoin.isChainValid()); 

If we run the code and check the output you can see that it gives the output as true, which means that our blockchain is valid and hence no tampering has been done.

Now let us try tampering with the blockchain by adding the following at the bottom of blockchain.js file

navneetCoin.chain[1].data  = { amount: 100 };
console.log('Is chain valid? ' + navneetCoin.isChainValid()); 
Now if we run the code we can see that it gives the output as false. Now if we try being clever and recalculate the hash, still the output will be false since the node has lost its relationship with the adjacent nodes when we tampered the hash value

How to create different shape textviews in android using xml drawable ?

1) Rectangle textview

textview with rectangle shape


First go to your res>drawable folder. Create a new drawable file rectangle_drawable.xml and add the following code inside it

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/transparent"/>
    <stroke
        android:width="3dp"
        android:color="#0FECFF"/>
    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp"/>
    <corners
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp"/>
</shape>


Now, inside your layout file create a textview and set the background property to above drawable file as shown below

<TextView
        android:background="@drawable/rectangle_drawable"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

2)  Circular Textview

textview with round shape

First go to your res>drawable folder. Create a new drawable file circle.xml and add the following code inside it

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">

<solid android:color="#9FE554" />

<size
    android:height="60dp"
    android:width="60dp" />

</shape>


Similarly create another drawable file round_textview.xml and add the following code inside it


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/circle" />
</selector>


Now, inside your layout file create a textview and set the drawable as shown below

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="N"
    android:textSize="30sp"
    android:background="@drawable/round_textview"
    android:textColor="@android:color/white"
    android:gravity="center"
     />

3) Custom Shape Textview

textview with a custom shape

First go to your res>drawable folder. Create a new drawable file custom_shape.xml and add the following code inside it

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#00ff00" />

    <corners
        android:bottomRightRadius="50dp"
        android:topLeftRadius="50dp" />

</shape>


Now, inside your layout file create a textview and set the drawable as shown below

<TextView
        android:textStyle="bold"
        android:padding="10dp"
        android:gravity="center"
        android:background="@drawable/custom_shape"
        android:layout_width="100dp"
        android:layout_height="150dp"
        android:text="Sample TextView"
        android:layout_centerInParent="true"/>

finished with non-zero exit value 2 : How to handle duplicate dependencies error in android ?

Here is the detailed view of the gradle sync error :

FAILURE: Build failed with an exception.  * What went wrong: 
Execution failed for task ':app:dexDebug'. > com.android.ide.common.process.ProcessException:org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2

This error occurs because  of many factors.

Case 1 :  When your app and the libraries it references exceeds 64K limit

There is a 64K limit for adding dependencies, beyond which you will need to add multidex support as enabled to properly compile dependencies.

In order to fix the issue go to your app level build.gradle and make the following change

defaultConfig {
   ...
   ...
   multiDexEnabled true
}

Making this change will help you solve the issue in above lollipop devices(greater than 5.0). But for devices < 5.0, this may produce unexpected results or NoClassDefFoundError


So for devices < 5.0 , do the following
  1. Add this dependency in app level build.gradle >   compile 'com.android.support:multidex:1.0.0'
  2. You need to change the application in the manifest to the multidex application, or override attachBaseContext() in your custom application class to call MutiDex.install(this) after the super.attachBaseContext(base);  see more info here

Case 2 : Duplicate entries of same dependencies

Also, suppose you are adding a lot of dependencies to your project. Now each of these dependencies may internally use other dependencies as well. In this way, there is a possibility of same dependencies to get added up more than once.

In order to check which dependencies are being internally used by other dependencies you could print the gradle dependencies tree like shown below.



  • Select View > Tool Windows > Gradle (or click Gradle icon in the tool windows bar).


  • Expand AppName > Tasks > android and double-click androidDependencies. After Gradle executes the task, the Run window should open to display the output.

  • The output tree structure will be something like this

    +--- MyApp:mylibrary:unspecified
    |    \--- com.android.support:appcompat-v7:25.3.1
    |         +--- com.android.support:animated-vector-drawable:25.3.1
    |         |    \--- com.android.support:support-vector-drawable:25.3.1
    |         |         \--- com.android.support:support-v4:25.3.1
    |         |              \--- LOCAL: internal_impl-25.3.1.jar
    |         +--- com.android.support:support-v4:25.3.1
    |         |    \--- LOCAL: internal_impl-25.3.1.jar
    |         \--- com.android.support:support-vector-drawable:25.3.1
    |              \--- com.android.support:support-v4:25.3.1
    |                   \--- LOCAL: internal_impl-25.3.1.jar
    

    From this structure we can easily identify which all dependencies are being internally used by other dependencies

    Suppose you have a facebook sdk dependency which use support-v4 internally. But we already have a different version of support-v4 already added in dependencies list. When we try to compile the project, we may see that gradle sync has failed due to finished with non-zero exit value 2. The fix for this issue will be to exclude the internally used dependency from facebook sdk like shown below

    compile ('com.facebook.android:facebook-android-sdk:4.0.1'){
        exclude module: 'support-v4'
    }
    

    By specifying like this, it will no longer compile the internal dependency, but will only compile the dependency which we have already defined in the dependencies list